Category Archives: StructureMap

Lamar v0.9 — Decorators and “MVP”

Lamar, which started life as “BlueMilk,” is the now permanent codename for my next generation IoC tool that is meant to replace StructureMap in new .Net Core projects. I did a little bit of work this morning to add in at least the basic functionality for decorators similar to what StructureMap has supported since 3.0 (but no other kinds of interception for now):

[Fact]
public void decorator_example()
{
    var container = new Container(_ =>
    {
        // This usage adds the WidgetHolder as a decorator
        // on all IWidget registrations
        _.For<IWidget>().DecorateAllWith<WidgetHolder>();
        
        // The AWidget type will be decorated w/ 
        // WidgetHolder when you resolve it from the container
        _.For<IWidget>().Use<AWidget>();
        
        _.For<IThing>().Use<Thing>();
    });

    // Just proving that it actually works;)
    container.GetInstance<IWidget>()
        .ShouldBeOfType<WidgetHolder>()
        .Inner.ShouldBeOfType<AWidget>();
}

This change, and a few other miscellaneous fixes for integration with Jasper, are available on Nuget in Lamar 0.9.0. At this point, I feel like Lamar is already at the feature set I intend to support for a 1.0 release. It’s going to at least go through some load testing at my work over the next month, and still lacks documentation (but most of it behaves identically to StructureMap or the ASP.Net Core DI compliance). All the same,  I’m declaring it ready for real usage if anybody is up for trying it out and hopefully sharing any feedback. It should *mostly* be a drop in replacement for StructureMap if you’re not doing too much weird stuff.

For more information, see some of my previous blog posts about Lamar/BlueMilk:

 

Advertisements

Differences Between BlueMilk and StructureMap

If you’ve been following me lately on Twitter or in this blog, you know I’ve been busy working on a new project called BlueMilk that’s meant to be a much faster replacement for the venerable StructureMap library. There are some advanced StructureMap features that will not be included into BlueMilk. Otherwise though, I’m aiming to make BlueMilk a near drop in replacement for most StructureMap users in terms of behavior and API. That being said, there are some important differences in behavior that you’ll need to be aware of switching from StructureMap to BlueMilk. In all the cases discussed below, the change was to ensure better compatibility with how our ASP.Net Core overlords believe IoC tools work. Bitterness at the ASP.net team aside, some of these design changes led to almost dramatically simpler internals and performance in BlueMilk compared to StructureMap, so it’s still a win overall.

 

Terminology

I dropped some of the old StructureMap verbiage just to be more consistent with ASP.Net Core’s verbiage.

  • “PluginType” becomes “ServiceType”
  • “PluggedType” becomes “ImplementationType”
  • “Instance” is still the name of the BlueMilk unit of registration (it’s basically a superset of ServiceDescriptor in ASP.Net Core), but the API signatures change
  • “Container” is still the same

 

Constructor Selection

While this has been pluggable and configurable forever, by default StructureMap tries to use the “greediest” public constructor it can find on a concrete type. If there are multiple constructors with the same number of arguments, it uses the first one it encounters.

In BlueMilk, we follow the ASP.Net Core prescribed logic of choosing the greediest constructor where BlueMilk has some known registration for each argument. I’ve always hated this idea, purposely kept it out of StructureMap, and I feel like it’s a bad pattern to use with IoC tools because of the extra mental overhead in understanding what’s going on (it’s an addon for ASP.Net Core usage in StructureMap 4.*), but that’s not worth fighting over.

I don’t like this behavior because it can wallpaper over problems with registrations and give you some false positives. My advice when using an IoC container is to build your classes as if they’re always built by the IoC container. In my experience, folks get in trouble when they try to be half in and half out of IoC usage with multiple constructors and optional arguments.

 

Object Lifetime / Lifecycle

This one’s a big difference, so do watch out. BlueMilk changes to using the ASP.Net Core verbiage and logic for service lifecycles. Singleton and Scoped work identically in BlueMilk as they did in StructureMap, except that BlueMilk is a lot better about tracking IDisposable dependencies within singleton or scoped construction.

The new “Transient” really maps to StructureMap’s “UniquePerRequest” lifecycle. If you depended on StructureMap’s default “Transient” behavior from before to have objects scoped per logical request or within a nested container, you’ll probably want to switch to the “Scoped” lifecycle.

 

Use vs. Add No Longer Matters

In the very beginning — and remember that StructureMap is literally the first .Net IoC container so there was no prior art — I had the belief that in the case of multiple registrations for the same service type, the user should explicitly tell StructureMap which one is the default that gets resolved from a call to IContainer.GetInstance(type) and which registrations are just additional services that would be either resolved by name or by an enumerable of all of them.

BlueMilk just uses the ASP.Net Core compliant logic of saying that the very last registration against a service type is the default registration.

In more concrete terms, the old StructureMap Use() and Add() methods now mean the exact same thing, and the last one wins. I might mark one or the other as [Obsolete] just to make the transitions go a little easier. See this code:

var container = new Container(_ =>
{
    // In StructureMap, this would be the default
    _.For<IWidget>().Use<BlueWidget>();

    // In BlueMilk, this would be because it's last
    _.For<IWidget>().Add<GreenWidget>();
});

 

 

Sunsetting StructureMap

I haven’t really been hiding this, but I apparently need to be more clear that I do not intend to do any further development work on StructureMap other than trying to keep up with pull requests and bugs that have no workaround. My focus is on other projects these days and I’m trying to cut down on the time I spend on OSS work as well. If someone wants to take over maintenance, I’d be happy to help someone else take it on. With umpteen dozen .Net IoC containers on GitHub and Nuget and the new built in DI container in ASP.Net Core, I feel like there’s plenty of tools for whatever folks need.

I am working on the BlueMilk project as an intended successor project to StructureMap that should be able to serve as an offramp to many shops developing on StructureMap today. BlueMilk will be a much smaller library that retains what I feel to be the core capabilities of StructureMap, while ditching most of the legacy design decisions that hold StructureMap back and keep my inbox filled with user questions.

For some perspective, I started working on what became StructureMap the summer before my oldest son was born, and he’s starting High School this coming fall. The highlight of my conference speaking history was probably a QCon where I gave a talk about “lessons learned from a long lived codebase” all about working with StructureMap — in 2008!

 

Proposal for StructureMap 5

EDIT 9/12: Meh, I had a couple twitter exchanges and Gitter questions today that reminded me why I’ve been wanting to walk away from StructureMap. Having to support not just SM but really how SM is used internally inside of tools like ASP.Net MVC Core, MediatR, and half a hundred other frameworks is just wearing me down too much. If anyone else is interested in taking on any of this, I’ll happily help out, but otherwise I think I’m just going to leave this alone. Besides, there’s the new built in IoC in ASP.Net and 30 or so other OSS competitors.

 

So I’ve been more or less burned out on StructureMap development and support for quite some time (it’s been better lately though). That being said, there’s a ton of people using it (it averages just shy of a 1,000 downloads a day).  It has also been put through the ringer from a lot of users, which remarkably enough, exposes and leads to fixing a lot of bugs and usability problems — and if you don’t believe me, check out this folder of all the tests for bug regressions and fixes.

StructureMap 4.* has a couple ongoing issues that should get addressed some day if the project is going to keep going on:

  1. StructureMap has fallen behind many or most of the other IoC containers in the public performance benchmarks. I think those benchmarks are mostly over simplified BS, but still, there’s the pride factor
  2. ASP.Net Core DI compliance has been a huge pain in the ass to the point where I’ve openly wondered if the ASP.Net team has purposely tried to sabotage and wipe out all the existing ecosystem of IoC containers in .Net
  3. The child container behavior (which I don’t personally use) has been problematic as StructureMap’s more creative users have found several permutations of this and that where the child container model has broken down a bit

So, here’s my thoughts about a possible direction for a future StructureMap 5.0:

  • Keep API backwards almost completely backward compatible with StructureMap 4.* except for a few places impacted by the next bullet point
  • Completely redesign the internal data structures as a performance optimization. The current structure isn’t terribly different from the very earliest StructureMap versions and there’s absolutely room to cut out some performance fat there
  • Take a dependency on Microsoft.Extensions.DependencyInjection.Abstractions and merge in the functionality that today is in StructureMap.Microsoft.DependencyInjection so that it’s easier to get the compliance against ASP.Net Core right by having everything in one place. My thought here too is that we would somehow use their configuration abstractions, but supplemented with the existing StructureMap configuration options somehow as a kind of buddy class extension. Not sure how that one’s gonna work out yet.
  • Look for opportunities to make the dynamic Expressions that are built up to actually create objects be more efficient by inlining some operations and generally reducing the number of times it bounces through dictionary structures. I know a lot more about building dynamic Expressions that I did several years ago when I moved StructureMap off of IL generation, so surely there’s some opportunity there

Alright, so my personal conundrum is simply wondering do I care enough to do this as an exercise in crafting performant data structures and micro-optimization, or call StructureMap 4.5 the end of the road and just continue to try to address bugs and user questions for the time being.

I’d kind of like to hear from some StructureMap users or contributors to see how much they’d want the performance and ASP.Net Core compatibility, and then see if anyone would want to help out if we go with this.

 

New StructureMap Extensions for Aspect Oriented Programming and AutoFactories

StructureMap gets a couple new, official extension libraries today that have both been baking for quite awhile courtesy of Dmytro Dziuma. Both libraries target both .Net 4.5+ and the CoreCLR (Netstandard 1.3 to be exact).

First off, there’s the StructureMap.DynamicInterception package that makes it easy to apply Aspect Oriented Programming techniques as StructureMap interceptors. Here’s the introduction and documentation page in the StructureMap website for the library.

Secondly, there’s the long awaited StructureMap.AutoFactory library that adds the “auto factory” feature to StructureMap that many folks that came from Windsor had requested over the years. Check out the documentation for the library on the StructureMap website.

A big thanks to Dmytro for all the work he did with these libraries — and an apology from me for having dragged my feet on these things for ages:/

Anybody want a gently used StructureMap?

TL;DR – I’m getting burned out supporting StructureMap, but it’s still very heavily used and I’m really hoping to recruit some new blood to eventually take the project over from me.

I’ve been mulling over whether or not I want to continue development of StructureMap. At this point, I feel like the 3.0 and 4.0 releases dealt with all the major structural and performance problems that I could think of. If you ask me what I’d like to be do to improve one of my other OSS projects I could bend your ear for hours, but with StructureMap I’ve got nothing in mind.

The project is still very widely used (1.5M downloads from Nuget) and I don’t mean to just drop it by any means, but I’m wondering if anybody (hopefully plural) would like to take ownership over StructureMap and actually keep it advancing? I feel like the code is pretty clean, the test coverage is solid, and there’s even close to comprehensive documentation already published online.

Why I’ve lost enthusiasm:

  • I’ve worked on StructureMap since 2003
  • I’m mentally exhausted trying to stay on top of the user questions and problems that come rolling in and I’m starting to resent the obligation to try to help users unwind far out usages of the tool and dozens of disparate application frameworks.
  • There’s a consistent and vocal backlash against IoC containers in my Twitter feeds. To some degree, I think their experiences are just very different than my own and I don’t recognize the problems they describe in my own usage, but it still dampens enthusiasm.
  • I’ve got several other projects going that I’m frankly more passionate about right now (Marten, Storyteller, a couple others)
  • Microsoft has a small, built in IoC container as part of ASP.Net Core that I suspect will eventually wipe out all the myriad OSS IoC containers. I can point to plenty advantages of StructureMap over what’s built in, but most users probably wouldn’t really notice
  • At this point, with every application framework or service bus, folks are putting their IoC container behind an abstraction of some kind that tends to reduce StructureMap and other tools into the least common denominator functionality, so what’s the point of trying to do anything new if it’s gonna be thrown away behind a lame wrapping abstraction?
  • The ASP.Net Core compatibility has been a massive headache for me with StructureMap and I’m dreading the kinds of support questions that I expect to roll in from users developing with ASP.Net Core. More on this one later.

StructureMap 4.3 Fully Embraces CoreCLR

EDIT 8/2: A lot of folks are asking me why SM targets both Netstandard 1.3 and 1.5 and I left that explanation out of the blog post because I was in too much of a hurry yesterday. The only single difference is that with 1.5 StructureMap can try to load an assembly by file path, which only comes into play if you’re using StructureMap to discover assemblies from the file path and an assembly name does not match the file name. I thought it was worthwhile to drop down to 1.3 without that small feature to expand StructureMap’s reach. We’ll see if I’m even remotely right.

I just uploaded StructureMap 4.3 to Nuget today. The big change (95% of my work) was to completely embrace the new world order of CoreCLR, the dotnet cli, and (for now) the project.json system. As such, I consolidated all of the real code back into the root StructureMap.dll project and relied on conditional compilation. This release also adds a great deal of functionality for type scanning and assembly scanning to the CoreCLR targets that were previously only available in the full .Net framework version.

StructureMap >=4.0 supported the CoreCLR through the old “dotnet” target, but we were only compiling to that target. Between users having Nuget issues with the old nomenclature and a CoreCLR specific bug, it was time to convert all the way and make sure that the tests were running against the CoreCLR version of StructureMap on our CI server.

What a StructureMap user needs to know before adopting 4.3…

  • The Nuget now targets .Net 4.5, Netstandard 1.3, and Netstandard 1.5
  • PCL profiles have been dropped for now, but I’m willing to try to put that back in if anyone requests it. That’s definitely a place where I’d love to have some help because I don’t do any mobile development that would test out that build.
  • The old StructureMap.Net4 assembly that used to be in the StructureMap nuget is gone. I’m relying on conditional compilation instead.
  • Any project that uses FubuMVC 3’s service bus should probably update to 4.3 for a big performance optimization that was impacting that functionality.

 

The complete list of changes and bug fixes is here.