Tag Archives: StructureMap

BlueMilk 0.8: It’s fast, runs MVC apps, and probably needs a new name

EDIT 4:30 PM CST on 2/21: Egg on my face. How’s this for the new world order of .Net Core? It works perfectly on OS X, but it blows up on the `RegistryPolicyResolver` class only on Windows. I’ll get a 0.8.1 up soon to fix whatever is different.

I just published the latest BlueMilk v0.8 to Nuget with quite a bit of performance optimization, some additional StructureMap functionality added in, and the ability to handle every kind of service registration that a basic MVC Core application will throw at an IoC container.

BlueMilk is the current codename for a new IoC tool that partially originated in Jasper. You can read about the goals and motivation for the project in Introducing BlueMilk: StructureMap’s Replacement & Jasper’s Special Sauce.

One of my colleagues made the observation yesterday that while being a Star Wars nerd and getting the reference, the name “BlueMilk” is off putting and we probably need to change that (plus it feels awkward to say out loud to me). Other than Marten and BlueMilk, all the projects in the JasperFx organization are named after other little towns or landmarks around my hometown. Once upon a time, I parked some of the code that’s not part of BlueMilk in another repository named “Lamar” that fits that naming scheme, plus my wife is doing a master’s program at Lamar University, I have a former coworker who played baseball there, and it’s also the name of a Texas revolutionary hero. If nobody has a better idea, I’ll probably rename BlueMilk to “Lamar.” My other idea was “Corsair,” but that’s really just too cool a name for yet another IoC tool.

Usage in MVC Core

I blogged last week that BlueMilk is Ready for Early Adopters. I was wrong of course, but thank you to Mark Warpool and others for actually trying to use it and giving me some important feedback. The big problems with 0.7 were that the code generation model that BlueMilk uses internally can’t handle internal types and didn’t allow for using generic types as constructor parameters. Wouldn’t you know it, ASP.Net Core MVC has quite a bit of both of those usages in its service registrations and BlueMilk was falling flat on its face in an MVC Core application (correction, “works on my box,” fails on a couple registrations in AppVeyor even though it’s the same version of the .Net SDK. Still saying it’s good to go at least until someone proves it’s a no go).

After a couple fixes (one big and one small), there’s now a test in BlueMilk that successfully builds every possible service registration from a basic MVC Core application. For those of you following along at home, I had to revert to using the dynamic Expression compiled to a Func<> trick to slide around the nonpublic types just to call non-public constructors.

Performance

A caveat here, it’s just not terribly likely that your IoC tool of choice is the performance bottleneck in your system. 

First off, Maksim Volkau has built some seriously cool stuff, and BlueMilk got quite a bit of the performance boost I’m talking about here from using his ImTools library (both Marten and StructureMap use FastExpressionCompiler as well).

One of my coworkers asked how BlueMilk compared to StructureMap in terms of performance, so I threw together some benchmarks where I was able to show BlueMilk being over 5X faster than StructureMap over a range of potential usages. I made the mistake of tweeting about that yesterday, and Eric Smith asked me how BlueMilk compared to the build in DI container inside of ASP.Net Core. After adding a comparison to the built in container to my BenchmarkDotNet metrics, I could see that BlueMilk lagged a bit (~30% slower over all). Several optimizations later, I can now say that BlueMilk is (barely) faster than the built in DI container and closing in on an order of magnitude faster than the latest StructureMap.

Using a barebones MVC Core application with logging added in as well, I built a series of metrics that just loops through the registered types and builds each possible type. It’s a lazy way of building up metrics, but it gave me a mix of registrations by type, by lambda, pre-built objects, and some deeper object graphs. It’s probably a bit bogus because this isn’t the way that an application is going to use the IoC tool at runtime and may weight more heavily on usages that don’t actually happen.

That being said, here’s the overall metrics on just creating every possible registered type in that minimal MVC Core application:

BenchmarkDotNet=v0.10.12, OS=macOS 10.12.6 (16G1212) [Darwin 16.7.0]
Intel Core i7-6920HQ CPU 2.90GHz (Skylake), 1 CPU, 8 logical cores and 4 physical cores
.NET Core SDK=2.1.4
  [Host]     : .NET Core 2.0.5 (Framework 4.6.0.0), 64bit RyuJIT
  DefaultJob : .NET Core 2.0.5 (Framework 4.6.0.0), 64bit RyuJIT


   Method | ProviderName |      Mean |     Error |    StdDev |
--------- |------------- |----------:|----------:|----------:|
 AllTypes |   AspNetCore |  73.98 us |  1.444 us |  1.976 us |
 AllTypes |     BlueMilk |  70.92 us |  1.408 us |  2.392 us |
 AllTypes | StructureMap | 646.28 us | 12.856 us | 27.398 us |

Getting much more specific, here are some finer grained metrics with an explanation of the different measurements below:

BenchmarkDotNet=v0.10.12, OS=macOS 10.12.6 (16G1212) [Darwin 16.7.0]
Intel Core i7-6920HQ CPU 2.90GHz (Skylake), 1 CPU, 8 logical cores and 4 physical cores
.NET Core SDK=2.1.4
  [Host]     : .NET Core 2.0.5 (Framework 4.6.0.0), 64bit RyuJIT
  DefaultJob : .NET Core 2.0.5 (Framework 4.6.0.0), 64bit RyuJIT


      Method | ProviderName |         Mean |        Error |        StdDev |       Median |
------------ |------------- |-------------:|-------------:|--------------:|-------------:|
 CreateScope |   AspNetCore |     429.0 ns |     8.288 ns |      7.347 ns |     428.2 ns |
     Lambdas |   AspNetCore |   1,784.4 ns |    25.886 ns |     22.948 ns |   1,777.8 ns |
   Internals |   AspNetCore |     914.2 ns |    17.575 ns |     15.580 ns |     912.6 ns |
     Objects |   AspNetCore |     810.2 ns |     7.723 ns |      6.449 ns |     808.7 ns |
  Singletons |   AspNetCore |  18,428.6 ns |   203.784 ns |    159.101 ns |  18,441.3 ns |
       Scope |   AspNetCore |     556.7 ns |     7.823 ns |      7.317 ns |     555.9 ns |
  Transients |   AspNetCore |  41,882.1 ns |   391.872 ns |    327.231 ns |  41,787.8 ns |
 CreateScope |     BlueMilk |     110.8 ns |     2.205 ns |      2.944 ns |     111.4 ns |
     Lambdas |     BlueMilk |   2,138.1 ns |    27.465 ns |     25.691 ns |   2,140.5 ns |
   Internals |     BlueMilk |     332.2 ns |     3.926 ns |      3.278 ns |     331.4 ns |
     Objects |     BlueMilk |     586.9 ns |    17.605 ns |     51.633 ns |     575.4 ns |
  Singletons |     BlueMilk |   9,852.8 ns |   196.721 ns |    548.380 ns |   9,780.1 ns |
       Scope |     BlueMilk |     330.8 ns |     5.781 ns |      4.828 ns |     332.1 ns |
  Transients |     BlueMilk |  54,439.2 ns | 1,083.872 ns |  2,967.082 ns |  53,801.7 ns |
 CreateScope | StructureMap |  16,781.0 ns |   334.284 ns |    948.307 ns |  16,584.2 ns |
     Lambdas | StructureMap |  12,329.5 ns |   244.697 ns |    686.155 ns |  12,121.9 ns |
   Internals | StructureMap |  10,585.0 ns |   209.617 ns |    393.712 ns |  10,519.9 ns |
     Objects | StructureMap |  17,739.9 ns |   430.679 ns |    560.005 ns |  17,606.7 ns |
  Singletons | StructureMap | 162,029.0 ns | 3,191.513 ns |  6,148.961 ns | 161,590.8 ns |
       Scope | StructureMap |   5,830.1 ns |   158.896 ns |    463.507 ns |   5,700.8 ns |
  Transients | StructureMap | 451,798.1 ns | 8,988.047 ns | 21,707.143 ns | 448,860.3 ns |

The metrics named in the first column are:

  1. “CreateScope” — measures how long it takes to create a completely new container scope as MVC Core and other frameworks do on each HTTP request.
  2. “Lambdas” — resolving services that were registered with some kind of Func<IServiceProvider, object> factory
  3. “Internals” — resolving non-public types
  4. “Objects” — resolving services that were registered with a pre-built object
  5. “Singletons” — all singleton registrations of all kinds
  6. “Scope” — bad name, but all registrations with the “Scoped” lifetime
  7. “Transients” — all registrations with the “Transient” lifetime

 

There’s still some performance fat in BlueMilk’s code, but I’m saying that I’ve hit the point of diminishing returns for now and I’m staying put on performance.

New Functionality

BlueMilk v0.8 adds in some old StructureMap behavior for:

Roadmap

I’m probably done working on BlueMilk for now other than the inevitable bug reports. When I do come back to it (or someone else picks it up), the next version (v0.9) will hopefully have support for decorators and interception similar to StructureMap’s existing model. I’d hope to have a 1.0 version out sometime this summer or fall after it’s been in production somewhere for awhile.

Advertisements

Introducing BlueMilk: StructureMap’s Replacement & Jasper’s Special Sauce

BlueMilk is the codename for a new project that’s an outgrowth from our new Jasper framework. Specifically, BlueMilk is extracting the runtime code generation and compilation “Special Sauce” support code that’s in Jasper now into a stand alone library. Building upon the runtime code generation, the logical next step was to make BlueMilk into the intended successor to the venerable StructureMap project as a fast, minimal IoC container on its own, but also supports inlining the service activation code into Jasper’s message and HTTP request handlers.

I think these are the key points for BlueMilk:

  1. Support the essential functionality and configuration API of StructureMap to be an offramp for folks invested in StructureMap that want to move to a faster option in their Netstandard2 applications
  2. Align much closer with the ASP.Net team’s DI compliance behavior. In some cases like object lifecycles, this is a breaking change with StructureMap’s traditional behavior and I don’t entirely agree with their choices, but .Net is their world and all us scrappy community OSS authors are just living in it.
  3. Easy integration into ASP.Net Core applications by directly supporting their abstractions (IServiceCollection, IServiceProvider, ServiceDescriptor, IServiceScope, etc.) out of the box.
  4. Trade in some of the runtime flexibility that StructureMap had in favor of better performance (and fewer ways for users to get themselves in a tangle)
  5. Expose the runtime code generation and compilation model (originally built for Marten, but we took it out later) in a separate library because a few folks have expressed some interest in having just that without using Jasper

There’s a preliminary Nuget up this morning (0.1.0) that supports some of StructureMap’s behavior and all of the ASP.Net Core compliance. You can use a container like this:

// Idiomatic StructureMap
var container = new Container(_ =>
{
    _.For<IWidget>().Use<AWidget>().Named("A");
    
    // StructureMap's old type scanning
    _.Scan(s =>
    {
        s.TheCallingAssembly();
        s.WithDefaultConventions();
    });
});

var widget = container.GetInstance<IWidget>();

// ASP.Net Core DI compatible
IServiceProvider container2 = new Container(_ =>
{
    _.AddTransient<IWidget, AWidget>();
    _.AddSingleton(new MoneyWidget());
});

var widget2 = container.GetService<IWidget>();

 

My Thoughts on Project Scope

I only started working on BlueMilk by itself over the holidays, so it’s not like anything is truly set in concrete, but this list is what I think the scope would be. My philosophy here is to jettison many of the features in StructureMap that cause internal complexity, performance issues, or generate loads of user questions and edge case bugs.

Core Functionality

  1. All ASP.Net Core DI compliance — lifecycle management (note that it’s different than StructureMap’s lifecycle definitions), object disposal, basic service resolution, open generic support, dealing with enumerable types
  2. StructureMap’s basic support for service location
  3. Nested Containers (scoped container)
  4. Type Scanning from StructureMap
  5. Service resolution by name
  6. Lazy & Func<T> resolution
  7. WhatDoIHave() and other diagnostics — no IoC or any other kind of framework author should release a tool without something like this for the sake of their own sanity
  8. Auto-find missing registrations — one of my biggest gripes about the built in container

Later

  1. Inline dependencies
  2. AutoFactory support — I think this could work out very well with the code generation model
  3. Construction Policies
  4. Some of StructureMap’s attribute configuration

Leaving Behind unless someone else really wants to build *and* help support it

  • Interception — Maybe. I’m not super excited about supporting it
  • Child containers and profiles. Utter nightmare to support. Edge case hell. Crazy amount of complexity internally. The only way we use them in work is for per-test isolation, and we can live without them in that case
  • Changing configuration at runtime (Container.Configure()).
  • Passing arguments at runtime. One of the biggest sources of heartburn for me supporting StructureMap. I think the better autofactory support in BlueMilk could be a far better alternative anyway.

Why do this?

One of my fervent goals with Jasper from the very beginning was to maximize performance to the point where its throughput was barely distinguishable from laboriously writing highly optimized bespoke code by hand. I wanted users to have all the productivity benefits of a good framework that takes care of common infrastructure needs without sacrificing performance. I know that some folks will disagree, but I still think there’s ample reasons to use an IoC container to handle quite a bit of the object composition, service activation, object scoping, and service cleanup.

If you allow that assumption of IoC usage, that left me with a couple options and thoughts:

  • I think it’s hugely disadvantageous to .Net frameworks to have to support multiple IoC containers. My experience is that basically every single framework abstraction I have ever seen for an IoC container has been problematic. If you are going to support multiple IoC containers in your application framework, my experience from FubuMVC and from watching the unfolding consternation over ASP.Net Core’s DI compliance is to restrict your framework from making all but a handful of assumptions about IoC container behavior.
  • I could just use my own StructureMap container because I understand it front to back and it fits the way that I personally work and all the .Net developers in my shop know it. The only problem there is that StructureMap has fallen behind in terms of performance. I think I have a decent handle on what it would take to reverse that with a potential 5.0, but I’m just not up for doing the work, I’m exhausted keeping up with user questions, and I really want to get out of supporting StructureMap.
  • I tried a couple times to just use the new built-in ASP.Net Core DI tool, but it’s extremely limited and I was getting frustrated with how many things were missing and how much more hand holding it took to be usable compared to StructureMap.

If you saw my Jasper’s Special Sauce post last week, you know that we are already using the service registration information to opt into inlining all the object construction and disposal directly into the generated message handlers whenever possible. The code that did that was effectively the beginning of a real IoC container, so it wasn’t that big of a jump to pulling all of that code into its own library and building it into the IoC tool that I wanted a theoretical StructureMap 5.0 to be.

 

Exploiting Generic Types with StructureMap

I’ve got a short window at work that I’m using to try to finally fill in the holes in StructureMap documentation. Everything I’m showing here is old, but some of it I’ve never documented or written about before and the usage of generic types has spawned a lot of questions on the StructureMap list over the years. 

The content of this blog post looks a lot better in the actual StructureMap documentation site here.

Example 1: Visualizing an Activity Log

I worked years ago on a system that could be used to record and resolve customer support problems. Since it was very workflow heavy in its logic, we tracked user and system activity as an event stream of small objects that reflected all the different actions or state changes that could happen to an issue. To render and visualize the activity log to HTML, we used many of the open generic type capabilities shown in this topic to find and apply the correct HTML rendering strategy for each type of log object in an activity stream.

Given a log object, we wanted to look up the right visualizer strategy to render that type of log object to html on the server side.

To start, we had an interface like this one that we were going to use to get the HTML for each log object:

    public interface ILogVisualizer
    {
        // If we already know what the type of log we have
        string ToHtml<TLog>(TLog log);

        // If we only know that we have a log object
        string ToHtml(object log);
    }

So for an example, if we already knew that we had an IssueCreated object, we should be able to use StructureMap like this:

            // Just setting up a Container and ILogVisualizer
            var container = Container.For<VisualizationRegistry>();
            var visualizer = container.GetInstance<ILogVisualizer>();

            // If I have an IssueCreated lob object...
            var created = new IssueCreated();

            // I can get the html representation:
            var html = visualizer.ToHtml(created);

If we had an array of log objects, but we do not already know the specific types, we can still use the more generic ToHtml(object) method like this:

            var logs = new object[]
            {
                new IssueCreated(), 
                new TaskAssigned(), 
                new Comment(), 
                new IssueResolved()
            };

            // SAMPLE: using-visualizer-knowning-the-type   
            // Just setting up a Container and ILogVisualizer
            var container = Container.For<VisualizationRegistry>();
            var visualizer = container.GetInstance<ILogVisualizer>();

            var items = logs.Select(visualizer.ToHtml);
            var html = string.Join("<hr />", items);

The next step is to create a way to identify the visualization strategy for a single type of log object. We certainly could have done this with a giant switch statement, but we wanted some extensibility for new types of activity log objects and even customer specific log types that would never, ever be in the main codebase. We settled on an interface like the one shown below that would be responsible for rendering a particular type of log object (“T” in the type):

    public interface IVisualizer<TLog>
    {
        string ToHtml(TLog log);
    }

Inside of the concrete implementation of ILogVisualizer we need to be able to pull out and use the correct IVisualizer<T> strategy for a log type. We of course used a StructureMap Container to do the resolution and lookup, so now we also need to be able to register all the log visualization strategies in some easy way. On top of that, many of the log types were simple and could just as easily be rendered with a simple html strategy like this class:

    public class DefaultVisualizer<TLog> : IVisualizer<TLog>
    {
        public string ToHtml(TLog log)
        {
            return string.Format("
{0}
"
, log); } }

Inside of our StructureMap usage, if we don’t have a specific visualizer for a given log type, we’d just like to fallback to the default visualizer and proceed.

Alright, now that we have a real world problem, let’s proceed to the mechanics of the solution.

Registering Open Generic Types

Let’s say to begin with all we want to do is to always use the DefaultVisualizer for each log type. We can do that with code like this below:

        [Test]
        public void register_open_generic_type()
        {
            var container = new Container(_ =>
            {
                _.For(typeof (IVisualizer<>)).Use(typeof (DefaultVisualizer<>));
            });

            
            Debug.WriteLine(container.WhatDoIHave(@namespace:"StructureMap.Testing.Acceptance.Visualization"));
            

            container.GetInstance<IVisualizer<IssueCreated>>()
                .ShouldBeOfType<DefaultVisualizer<IssueCreated>>();

            Debug.WriteLine(container.WhatDoIHave(@namespace: "StructureMap.Testing.Acceptance.Visualization"));
            


            container.GetInstance<IVisualizer<IssueResolved>>()
                .ShouldBeOfType<DefaultVisualizer<IssueResolved>>();
        }

With the configuration above, there are no specific registrations for IVisualizer<IssueCreated>. At the first request for that interface, StructureMap will run through its “missing family policies“, one of which is to try to find registrations for an open generic type that could be closed to make a valid registration for the requested type. In the case above, StructureMap sees that it has registrations for the open generic type IVisualizer<T> that could be used to create registrations for the closed type IVisualizer<IssueCreated>.

Using the WhatDoIHave() diagnostics, the original state of the container for the visualization namespace is:

===========================================================================================================================
PluginType            Namespace                                         Lifecycle     Description                 Name     
---------------------------------------------------------------------------------------------------------------------------
IVisualizer<TLog>     StructureMap.Testing.Acceptance.Visualization     Transient     DefaultVisualizer<TLog>     (Default)
===========================================================================================================================

After making a request for IVisualizer<IssueCreated>, the new state is:

====================================================================================================================================================================================
PluginType                    Namespace                                         Lifecycle     Description                                                                  Name     
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IVisualizer<IssueCreated>     StructureMap.Testing.Acceptance.Visualization     Transient     DefaultVisualizer<IssueCreated> ('548b4256-a7aa-46a3-8072-bd8ef0c5c430')     (Default)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IVisualizer<TLog>             StructureMap.Testing.Acceptance.Visualization     Transient     DefaultVisualizer<TLog>                                                      (Default)
====================================================================================================================================================================================

Generic Registrations and Default Fallbacks

A powerful feature of generic type support in StructureMap is the ability to register specific handlers for some types, but allow users to register a “fallback” registration otherwise. In the case of the visualization, some types of log objects may justify some special HTML rendering while others can happily be rendered with the default visualization strategy. This behavior is demonstrated by the following code sample:

        [Test]
        public void generic_defaults()
        {
            var container = new Container(_ =>
            {
                // The default visualizer just like we did above
                _.For(typeof(IVisualizer<>)).Use(typeof(DefaultVisualizer<>));

                // Register a specific visualizer for IssueCreated
                _.For<IVisualizer<IssueCreated>>().Use<IssueCreatedVisualizer>();
            });


            // We have a specific visualizer for IssueCreated
            container.GetInstance<IVisualizer<IssueCreated>>()
                .ShouldBeOfType<IssueCreatedVisualizer>();

            // We do not have any special visualizer for TaskAssigned,
            // so fall back to the DefaultVisualizer<T>
            container.GetInstance<IVisualizer<TaskAssigned>>()
                .ShouldBeOfType<DefaultVisualizer<TaskAssigned>>();
        }

Connecting Generic Implementations with Type Scanning

It’s generally harmful in software projects to have a single code file that has to be frequently edited to for unrelated changes, and StructureMap Registry classes that explicitly configure services can easily fall into that category. Using type scanning registration can help teams avoid that problem altogether by eliminating the need to make any explict registrations as new providers are added to the codebase.

For this example, I have two special visualizers for the IssueCreated and IssueResolved log types:

    public class IssueCreatedVisualizer : IVisualizer<IssueCreated>
    {
        public string ToHtml(IssueCreated log)
        {
            return "special html for an issue being created";
        }
    }

    public class IssueResolvedVisualizer : IVisualizer<IssueResolved>
    {
        public string ToHtml(IssueResolved log)
        {
            return "special html for issue resolved";
        }
    }

In the real project that inspired this example, we had many, many more types of log visualizer strategies and it could have easily been very tedious to manually register all the different little IVisualizer<T> strategy types in a Registry class by hand. Fortunately, part of StructureMap’s type scanning support is the ConnectImplementationsToTypesClosing()auto-registration mechanism via generic templates for exactly this kind of scenario.

In the sample below, I’ve set up a type scanning operation that will register any concrete type in the Assembly that contains the VisualizationRegistry that closes IVisualizer<T> against the proper interface:

    public class VisualizationRegistry : Registry
    {
        public VisualizationRegistry()
        {
            // The main ILogVisualizer service
            For<ILogVisualizer>().Use<LogVisualizer>();

            // A default, fallback visualizer
            For(typeof(IVisualizer<>)).Use(typeof(DefaultVisualizer<>));

            // Auto-register all concrete types that "close"
            // IVisualizer<TLog>
            Scan(x =>
            {
                x.TheCallingAssembly();
                x.ConnectImplementationsToTypesClosing(typeof(IVisualizer<>));
            });

        }
    }

If we create a Container based on the configuration above, we can see that the type scanning operation picks up the specific visualizers for IssueCreated and IssueResolved as shown in the diagnostic view below:

==================================================================================================================================================================================
PluginType                     Namespace                                         Lifecycle     Description                                                               Name     
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ILogVisualizer                 StructureMap.Testing.Acceptance.Visualization     Transient     StructureMap.Testing.Acceptance.Visualization.LogVisualizer               (Default)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IVisualizer<IssueResolved>     StructureMap.Testing.Acceptance.Visualization     Transient     StructureMap.Testing.Acceptance.Visualization.IssueResolvedVisualizer     (Default)
                                                                                 Transient     DefaultVisualizer<IssueResolved>                                                   
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IVisualizer<IssueCreated>      StructureMap.Testing.Acceptance.Visualization     Transient     StructureMap.Testing.Acceptance.Visualization.IssueCreatedVisualizer      (Default)
                                                                                 Transient     DefaultVisualizer<IssueCreated>                                                    
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IVisualizer<TLog>              StructureMap.Testing.Acceptance.Visualization     Transient     DefaultVisualizer<TLog>                                                   (Default)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IVisualizer<TLog>              StructureMap.Testing.Acceptance.Visualization     Transient     DefaultVisualizer<TLog>                                                   (Default)
==================================================================================================================================================================================

The following sample shows the VisualizationRegistry in action to combine the type scanning registration plus the default fallback behavior for log types that do not have any special visualization logic:

        [Test]
        public void visualization_registry()
        {
            var container = Container.For<VisualizationRegistry>();

            Debug.WriteLine(container.WhatDoIHave(@namespace: "StructureMap.Testing.Acceptance.Visualization"));

            container.GetInstance<IVisualizer<IssueCreated>>()
                .ShouldBeOfType<IssueCreatedVisualizer>();

            container.GetInstance<IVisualizer<IssueResolved>>()
                .ShouldBeOfType<IssueResolvedVisualizer>();

            // We have no special registration for TaskAssigned,
            // so fallback to the default visualizer
            container.GetInstance<IVisualizer<TaskAssigned>>()
                .ShouldBeOfType<DefaultVisualizer<TaskAssigned>>();
        }

Building Closed Types with ForGenericType() and ForObject()

Working with generic types and the common IHandler<T> pattern can be a little bit tricky if all you have is an object that is declared as an object. Fortunately, StructureMap has a couple helper methods and mechanisms to help you bridge the gap between DoSomething(object something) and DoSomething<T>(T something).

If you remember the full ILogVisualizer interface from above:

    public interface ILogVisualizer
    {
        // If we already know what the type of log we have
        string ToHtml<TLog>(TLog log);

        // If we only know that we have a log object
        string ToHtml(object log);
    }

The method ToHtml(object log) somehow needs to be able to find the right IVisualizer<T> and execute it to get the HTML representation for a log object. The StructureMap IContainer provides two different methods called ForObject() and ForGenericType() for exactly this case, as shown below in a possible implementation of ILogVisualizer:

    public class LogVisualizer : ILogVisualizer
    {
        private readonly IContainer _container;

        // Take in the IContainer directly so that
        // yes, you can use it as a service locator
        public LogVisualizer(IContainer container)
        {
            _container = container;
        }

        // It's easy if you already know what the log
        // type is
        public string ToHtml<TLog>(TLog log)
        {
            return _container.GetInstance<IVisualizer<TLog>>()
                .ToHtml(log);
        }

        public string ToHtml(object log)
        {
            // The ForObject() method uses the 
            // log.GetType() as the parameter to the open
            // type Writer<T>, and then resolves that
            // closed type from the container and
            // casts it to IWriter for you
            return _container.ForObject(log)
                .GetClosedTypeOf(typeof (Writer<>))
                .As<IWriter>()
                .Write(log);
        }

        public string ToHtml2(object log)
        {
            // The ForGenericType() method is again creating
            // a closed type of Writer<T> from the Container
            // and casting it to IWriter
            return _container.ForGenericType(typeof (Writer<>))
                .WithParameters(log.GetType())
                .GetInstanceAs<IWriter>()
                .Write(log);
        }

        // The IWriter and Writer<T> class below are
        // adapters to go from "object" to <T>() signatures
        public interface IWriter
        {
            string Write(object log);
        }

        public class Writer<T> : IWriter
        {
            private readonly IVisualizer<T> _visualizer;

            public Writer(IVisualizer<T> visualizer)
            {
                _visualizer = visualizer;
            }

            public string Write(object log)
            {
                return _visualizer.ToHtml((T) log);
            }
        }
    }

The two methods are almost identical in result with some slight differences:

  1. ForObject(object subject) can only work with open types that have only one generic type parameter, and it will pass the argument subject to the underlying Container as an explicit argument so that you can inject that subject object into the object graph being created.
  2. ForGenericType(Type openType) is a little clumsier to use, but can handle any number of generic type parameters

Example #2: Generic Instance Builder

As I recall, the following example was inspired by a question about how to use StructureMap to build out MongoDB MongoCollection objects from some sort of static builder or factory — but I can’t find the discussion on the mailing list as I write this today. This has come up often enough to justify its inclusion in the documentation.

Say that you have some sort of persistence tooling that you primarily interact with through an interface like this one below, where TDocument and TQuery are classes in your persistent domain:

    public interface IRepository<TDocument, TQuery>
    {

    }

Great, StructureMap handles generic types just fine, so you can just register the various closed types and off you go. Except you can’t because the way that your persistence tooling works requires you to create the IRepository<,>objects with a static builder class like this one below:

    public static class RepositoryBuilder
    {
        public static IRepository<TDocument, TQuery> Build<TDocument, TQuery>()
        {
            return new Repository<TDocument, TQuery>();
        }
    }

StructureMap has an admittedly non-obvious way to handle this situation by creating a new subclass of Instance that will “know” how to create the real Instance for a closed type of IRepository<,>.

First off, let’s create a new Instance type that knows how to build a specific type of IRepository<,> by subclassing the LambdaInstance type and providing a Func to build our repository type with the static RepositoryBuilder class:

    public class RepositoryInstance<TDocument, TQuery> : LambdaInstance<IRepository<TDocument, TQuery>>
    {
        public RepositoryInstance() : base(() => RepositoryBuilder.Build<TDocument, TQuery>())
        {
        }

        // This is purely to make the diagnostic views prettier
        public override string Description
        {
            get
            {
                return "RepositoryBuilder.Build<{0}, {1}>()"
                    .ToFormat(typeof(TDocument).Name, typeof(TQuery).Name);
            }
        }
    }

As you’ve probably surmised, the custom RepositoryInstance above is itself an open generic type and cannot be used directly until it has been closed. You could use this class directly if you have a very few document types like this:

            var container = new Container(_ =>
            {
                _.For<IRepository<string, int>>().UseInstance(new RepositoryInstance<string, int>());

                // or skip the custom Instance with:

                _.For<IRepository<string, int>>().Use(() => RepositoryBuilder.Build<string, int>());
            });

To handle the problem in a more generic way, we can create a second custom subclass of Instance for the open type IRepository<,> that will help StructureMap understand how to build the specific closed types of IRepository<,> at runtime:

    public class RepositoryInstanceFactory : Instance
    {
        // This is the key part here. This method is called by
        // StructureMap to "find" an Instance for a closed
        // type of IRepository<,>
        public override Instance CloseType(Type[] types)
        {
            // StructureMap will cache the object built out of this,
            // so the expensive Reflection hit only happens
            // once
            var instanceType = typeof (RepositoryInstance<,>).MakeGenericType(types);
            return Activator.CreateInstance(instanceType).As<Instance>();
        }

        // Don't worry about this one, never gets called
        public override IDependencySource ToDependencySource(Type pluginType)
        {
            throw new NotSupportedException();
        }

        public override string Description
        {
            get { return "Build Repository<T, T1>() with RepositoryBuilder"; }
        }

        public override Type ReturnedType
        {
            get { return typeof (Repository<,>); }
        }
    }

The key part of the class above is the CloseType(Type[] types) method. At that point, we can determine the right type of RepositoryInstance<,> to build the requested type of IRepository<,>, then use some reflection to create and return that custom Instance.

Here’s a unit test that exercises and demonstrates this functionality from end to end:

        [Test]
        public void show_the_workaround_for_generic_builders()
        {
            var container = new Container(_ =>
            {
                _.For(typeof (IRepository<,>)).Use(new RepositoryInstanceFactory());
            });

            container.GetInstance<IRepository<string, int>>()
                .ShouldBeOfType<Repository<string, int>>();

            Debug.WriteLine(container.WhatDoIHave(assembly:Assembly.GetExecutingAssembly()));
        }

After requesting IRepository<string, int> for the first time, the container configuration from Container.WhatDoIHave() is:

===================================================================================================================================================
PluginType                         Namespace                           Lifecycle     Description                                          Name     
---------------------------------------------------------------------------------------------------------------------------------------------------
IRepository<String, Int32>         StructureMap.Testing.Acceptance     Transient     RepositoryBuilder.Build<String, Int32>()             (Default)
---------------------------------------------------------------------------------------------------------------------------------------------------
IRepository<TDocument, TQuery>     StructureMap.Testing.Acceptance     Transient     Build Repository<T, T1>() with RepositoryBuilder     (Default)
===================================================================================================================================================

New Construction Policies in StructureMap 4.0

This is taken from some brand spanking new StructureMap docs on construction policies. As part of the forthcoming StructureMap 4.0 release this month I’m hoping to flood my blog with little posts on StructureMap. The code samples look a lot better in the actual docs, mea culpa.

StructureMap has long supported conventional policies for registration based on type scanning and 3.0 introduced cleaner mechanisms for interception policies. The 4.0 release extends StructureMap’s support for conventional build policies with a new mechanism for altering how object instances are built based on user created meta-conventions using the IInstancePolicy shown below:

    /// <summary>
    /// Custom policy on Instance construction that is evaluated
    /// as part of creating a "build plan"
    /// </summary>
    public interface IInstancePolicy
    {
        /// <summary>
        /// Apply any conventional changes to the configuration
        /// of a single Instance
        /// </summary>
        /// <param name="pluginType"></param>
        /// <param name="instance"></param>
        void Apply(Type pluginType, Instance instance);
    }

These policies are registered as part of the registry dsl with the Policies.Add() method:

            var container = new Container(_ =>
            {
                _.Policies.Add<MyCustomPolicy>();
                // or
                _.Policies.Add(new MyCustomPolicy());
            });

The IInstancePolicy mechanism probably works differently than other IoC containers in that the policy is applied to the container’s underlying configuration model instead of at runtime. Internally, StructureMap lazily creates a “build plan” for each configured Instance at the first time that that Instance is built or resolved. As part of creating that build plan, StructureMap runs all the registered IInstancePolicy objects against the Instance in question to capture any potential changes before “baking” the build plan into a .Net Expression that is then compiled into a Func for actual construction.

The Instance objects will give you access to the types being created, the configured name of the Instance (if any), the ability to add interceptors and to modify the lifecycle. If you wish to add inline dependencies to Instances that are built by calling constructor function and setter properties, you may find it easier to use the ConfiguredInstancePolicy base class as a convenience:

    public abstract class ConfiguredInstancePolicy : IInstancePolicy
    {
        public void Apply(Type pluginType, Instance instance)
        {
            var configured = instance as IConfiguredInstance;
            if (configured != null)
            {
                apply(pluginType, configured);
            }
        }

        // This method is called against any Instance that implements 
        // the IConfiguredInstance interface
        protected abstract void apply(Type pluginType, IConfiguredInstance instance);
    }

For more information, see:

Example 1: Constructor arguments

So let me say upfront that I don’t like this approach, but other folks have asked for this ability over the years. Say that you have some legacy code where many concrete classes have a constructor argument called “connectionString” that needs to be the connection string to the application database like these classes:

        public class DatabaseUser
        {
            public string ConnectionString { get; set; }

            public DatabaseUser(string connectionString)
            {
                ConnectionString = connectionString;
            }
        }

        public class ConnectedThing
        {
            public string ConnectionString { get; set; }

            public ConnectedThing(string connectionString)
            {
                ConnectionString = connectionString;
            }
        }

Instead of explicitly configuring every single concrete class in StructureMap with that inline constructor argument, we can make a policy to do that in one place:

        public class ConnectionStringPolicy : ConfiguredInstancePolicy
        {
            protected override void apply(Type pluginType, IConfiguredInstance instance)
            {
                var parameter = instance.Constructor.GetParameters().FirstOrDefault(x => x.Name == "connectionString");
                if (parameter != null)
                {
                    var connectionString = findConnectionStringFromConfiguration();
                    instance.Dependencies.AddForConstructorParameter(parameter, connectionString);
                }
            }

            // find the connection string from whatever configuration
            // strategy your application uses
            private string findConnectionStringFromConfiguration()
            {
                return "the connection string";
            }
        }

Now, let’s use that policy against the types that need “connectionString” and see what happens:

        [Test]
        public void use_the_connection_string_policy()
        {
            var container = new Container(_ =>
            {
                _.Policies.Add<ConnectionStringPolicy>();
            });

            container.GetInstance<DatabaseUser>()
                .ConnectionString.ShouldBe("the connection string");

            container.GetInstance<ConnectedThing>()
                .ConnectionString.ShouldBe("the connection string");
        }

Years ago StructureMap was knocked by an “IoC expert” for not having this functionality. I said at the time — and still would — that I would strongly recommend that you simply don’t directly open database connections in more than one or a very few spots in your code anyway. If I did need to configure a database connection string in multiple concrete classes, I prefer strong typed configuration.

Example 2: Connecting to Databases based on Parameter Name

From another common user request over the years, let’s say that your application needs to connect to multiple databases, but your data access service in both cases is an interface called IDatabase, and that’s all the consumers of any database should ever need to know.

To make this concrete, let’s say that our data access is all behind an interface and concrete class pair namedDatabase/IDatabase like so:

        public interface IDatabase { }

        public class Database : IDatabase
        {
            public string ConnectionString { get; set; }

            public Database(string connectionString)
            {
                ConnectionString = connectionString;
            }

            public override string ToString()
            {
                return string.Format("ConnectionString: {0}", ConnectionString);
            }
        }

For a registration policy, let’s say that the parameter name of an IDatabase dependency in a constructor function should match an identifier of one of the registered IDatabase services. That policy would be:

        public class InjectDatabaseByName : ConfiguredInstancePolicy
        {
            protected override void apply(Type pluginType, IConfiguredInstance instance)
            {
                instance.Constructor.GetParameters()
                    .Where(x => x.ParameterType == typeof (IDatabase))
                    .Each(param =>
                    {
                        // Using ReferencedInstance here tells StructureMap
                        // to "use the IDatabase by this name"
                        var db = new ReferencedInstance(param.Name);
                        instance.Dependencies.AddForConstructorParameter(param, db);
                    });
            }
        }

And because I’m generally pretty boring about picking test data names, let’s say that two of our databases are named “red” and “green” with this container registration below:

            var container = new Container(_ =>
            {
                _.For<IDatabase>().Add<Database>().Named("red")
                    .Ctor<string>("connectionString").Is("*red*");

                _.For<IDatabase>().Add<Database>().Named("green")
                    .Ctor<string>("connectionString").Is("*green*");
                
                _.Policies.Add<InjectDatabaseByName>();
            });

For more context, the classes that use IDatabase would need to have constructor functions like these below:

        public class BigService
        {
            public BigService(IDatabase green)
            {
                DB = green;
            }

            public IDatabase DB { get; set; }
        }

        public class ImportantService
        {
            public ImportantService(IDatabase red)
            {
                DB = red;
            }

            public IDatabase DB { get; set; }
        }

        public class DoubleDatabaseUser
        {
            public DoubleDatabaseUser(IDatabase red, IDatabase green)
            {
                Red = red;
                Green = green;
            }

            // Watch out for potential conflicts between setters
            // and ctor params. The easiest thing is to just make
            // setters private
            public IDatabase Green { get; private set; }
            public IDatabase Red { get; private set; }
        }

Finally, we can exercise our new policy and see it in action:

            // ImportantService should get the "red" database
            container.GetInstance<ImportantService>()
                .DB.As<Database>().ConnectionString.ShouldBe("*red*");

            // BigService should get the "green" database
            container.GetInstance<BigService>()
                .DB.As<Database>().ConnectionString.ShouldBe("*green*");

            // DoubleDatabaseUser gets both
            var user = container.GetInstance<DoubleDatabaseUser>();

            user.Green.As<Database>().ConnectionString.ShouldBe("*green*");
            user.Red.As<Database>().ConnectionString.ShouldBe("*red*");

How I prefer to do this – my strong preference would be to use separate interfaces for the different databases even if that type is just an empty type marker that implements the same base. I feel like using separate interfaces makes the code easier to trace and understand than trying to make StructureMap vary dependencies based on naming conventions or what namespace a concrete type happens to be in. At least now though, you have the choice of my way or using policies based on naming conventions.

Example 3: Make objects singletons based on type name

Unlike the top two examples, this is taken from a strategy that I used in FubuMVC for its service registration. In that case, we wanted any concrete type whose name ended with “Cache” to be a singleton in the container registration. With the new IInstancePolicy feature in StructureMap 4, we could create a new policy class like so:

        public class CacheIsSingleton : IInstancePolicy
        {
            public void Apply(Type pluginType, Instance instance)
            {
                if (instance.ReturnedType.Name.EndsWith("Cache"))
                {
                    instance.SetLifecycleTo<SingletonLifecycle>();
                }
            }
        }

Now, let’s say that we have an interface named IWidgets and a single implementation called WidgetCache that should track our widgets in the application. Using our new policy, we should see WidgetCache being made a singleton:

        [Test]
        public void set_cache_to_singleton()
        {
            var container = new Container(_ =>
            {
                _.Policies.Add<CacheIsSingleton>();

                _.For<IWidgets>().Use<WidgetCache>();
            });

            // The policy is applied *only* at the time
            // that StructureMap creates a "build plan"
            container.GetInstance<IWidgets>()
                .ShouldBeTheSameAs(container.GetInstance<IWidgets>());

            // Now that the policy has executed, we 
            // can verify that WidgetCache is a singleton
            container.Model.For<IWidgets>().Default
                .Lifecycle.ShouldBeOfType<SingletonLifecycle>();
        }

 

StructureMap in 2015/16

I’ve been absurdly bogged down most of this calendar year rewriting the Storyteller tool we use at work for acceptance and regression testing. Now that I’m past that crunch, I’m finally able to focus on other things like StructureMap, this blog, and the still unfinished StructureMap documentation. That being said, here’s what’s going on with StructureMap now and in the near future.

Documentation

StructureMap and I have earned a bad reputation over the years for being under-documented and having out of date documentation. As of about an hour ago, I finished converting the existing StructureMap 3.0 documentation site to the far better “living documentation” tooling I built as part of my Storyteller work earlier this year. There are still far too many holes in that site, but I’m hoping to knock out a couple topics a week until they’re complete. With the new tooling, I think it would be much easier for other folks to contribute to the documentation effort.

Strong Naming and StructureMap. Sigh.

My position on strong naming with StructureMap 3 and beyond is that I do not want the main packages to be strong named. I have said that I would consider supporting a signed version of StructureMap 3 in a parallel nuget if someone did the pull request for that support. Lo and behold, someone finally did that, so look for the structuremap-signed package if you absolutely have to have a strong named version of StructureMap. That being said, I still fervently recommend that you do not use the signed version unless you absolutely have to in your situation.

StructureMap 3.2 in 2015

I’m just about to start some work on some new features and internal improvements for StructureMap that will make up a 3.2 release. Using Semantic Versioning rules, there should be no breaking API changes from 3.* to 3.2. Right now, I think the major changes are:

  1. Optimize the type scanning and convention registration. This was the one big subsystem that I left essentially untouched in the push to 3.0 and sure enough, it’s not holding up well for some users. I have some ideas about how to improve the performance and usability of the type scanning that I have already started in a private branch.
  2. Optimize and tighten up the “TryGetInstance()” runtime behavior under heavy multi-threaded loads. I don’t use this feature myself and I try to discourage its usage overall, but all the ASP.Net frameworks (MVC & Web API) use it in their integration and that’s been problematic to a couple folks.
  3. Some new syntactical sugar to verify specific container registrations
  4. New types of Container wide conventions or policies that act against the entire container
  5. Take advantage of default parameter values
  6. Features to make StructureMap easier to configure from mix and match sources for highly modular architectures

StructureMap 4 in 2016(?)

I *think* that StructureMap 4.0 is going to be all about the new stuff:

  • Use Roslyn runtime code generation in place of the current strategy of building then compiling Expression’s at runtime. I don’t know that this is going to result in faster code, but I am hopeful that it makes the guts of StructureMap’s internals more approachable. Really though, that’s because I want to use the Roslyn functionality on a proposed replacement for FubuMVC next year.
  • Maybe use Roslyn’s support for compiler symbols in place of the existing type scanning?
  • Support CoreCLR

Re-tooled the Codebase

I changed up the build automation tooling for StructureMap a couple weeks ago in an attempt to make the code easier to work with for more mainstream .Net developers.

I started from:

  • Rake (Ruby) as a build scripting tool
  • The old Ripple tool from the FubuMVC family of projects for Nuget support
  • The build script had to be executed at least once before working with the code to generate some required files and fetch all the necessary nuget requirements
  • Good ol’ fashioned NUnit for unit testing

The usage of Ruby for build automation has been off-putting to many .Net developers and the mass majority of .Net developers seem to prefer being able to open Visual Studio.Net and just go to work. Based on the twin desires to make the StructureMap build faster and easier for most .Net developers, the new build tooling changed to:

  • Use Paket as the nuget management tool with its auto-restore capability
  • After some conversations with the NancyFx team over the years, I stole their idea of using Rake but making it completely optional for potential contributors
  • Replaced NUnit with Fixie, a much better and faster testing library from some of the Headspring folks here in Austin

Long Lived Codebases: A Crime Against Computer Science

All code samples are links to the exact lines of code in GitHub. Every thing I’ve ever done to embed code into blog posts has been a PITA, so I’m just punting this time.

This continues the adaptation of my CodeMash 2015 talk about my experiences developing StructureMap over the past decade and change. This series started last week with The Challenges. This post is about the wretchedly poor original implementation of StructureMap’s “nested container” feature and how I re-architected the StructureMap internals in the 3.0 release to greatly improve the performance of this feature. I ran out of steam while writing this, so I ended up breaking this out into two posts.

A little background on nested containers

Sometime around early 2009 my team and I were building a small quasi-service bus for our system that processed messages sent to a queue. In our simple case, the processing of each message would be treated as a single logical transaction. At the time, we were using NHibernate to do all our persistence, so the ISession interface is your de facto unit of work. What we needed was for every object that would participate in the handling of a single message to use the right ISession for that message handling transaction — even if the object was resolved lazily from the StructureMap container.

What we needed was a new kind of container scoping for a logical operation independent of thread or HttpContext or any of the older mechanisms that the IoC containers typically used at that time. Inspired by a similar feature in Windsor* (I think), I conceived of what is now the Nested Container feature in StructureMap that I quickly rolled into the 2.6 release just so we could use it in our homegrown service bus at work.

From a functionality perspective, the nested container feature has been a complete success. It’s used by my own FubuMVC and FubuTransportation frameworks plus other development frameworks like MassTransit, NServiceBus, and even ASP.Net MVC and Web API through OSS adapters. That being said, the original implementation of nested containers in the 2.6.* versions was a mess that suffered from poor performance and usability bugs that took me years to address — so bad that the 3.0 release was largely wrapped around some very significant architectural changes specifically to improve the nested container feature.

* People sometimes get upset by the number of different IoC containers in .Net, but there is some real value in competition between different technical solutions to push and inspire each other. I’ve always thought that development tools in .Net would be significantly better overall if the wider .Net community would be more willing to adopt tools originating outside of Microsoft so that MS would be forced to compete for adoption. 

The Original Implementation

During my talk at CodeMash, I stated that I believe the original implementation of the nested container feature in StructureMap caused other developers more harm than any other thing I’ve ever done. So what was so bad about the original version?

There was a pretty nasty bug related to object scoping in regards to singleton scoped objects that wasn’t really addressed outside of published workarounds until the 3.0 release 3-4 years later. The biggest issues though were performance and thread contention at runtime.

One of the original requirements for the nested container was to enable users to override service registrations in a nested container without having any impact on the original, parent container.* For context, the acceptance test for this behavior demonstrates what I mean. To pull this requirement off, I made the fateful decision to make a complete copy of the parent’s internal configuration model to pass into the nested container.

To illustrate why this turned out to be such an awful approach, see the code for the method PipelineGraph.ToNestedGraph() in the 2.6 branch that’s used to create the isolated configuration model for a new nested container. In particular, see how that code is making deep, programmatic clones of several structures. See also the code lock(this) that creates an exclusive lock around the parent object as it performs the work inside of the code block (I had to create a lock around the dictionary being cloned so that nothing else could alter that dictionary while I was in the process of iterating through it).** Doing the deep clone of the configuration models is expensive, especially when StructureMap was used in bigger applications. Even worse though, the shared lock that I had to do in order to copy the internal configuration structures meant that only one thread in the entire application could be creating a nested container at one time — which is a pretty big problem when you’re talking about a web application under significant load that wants to create an individual nested container for each unique HTTP request.

* FubuMVC exploits this ability to inject services that represent the current HTTP request into a nested container just before building the handlers for that HTTP request so that you can use constructor injection “all the way down.”

** Yes, I do buy that this is an example of where immutability can be valuable in concurrent code. Do also cut me a little bit of slack because this code was written long before .Net 4.0, the TPL, and the newer concurrent collection classes that came with it.

Re-architecting Nested Containers in 3.0 

It took about three years (and another year before a public release), but I was finally able to permanently fix (knock on wood!) the performance, thread contention, and scoping bugs related to the nested container feature in the 3.0 release. In my testing against one of our biggest codebases at work, I measured a two order of magnitude improvement in the time it took to create a new nested container. I was also able to completely eliminate the thread contention issues.

How was I able to do make those improvements? Heres the new version of PipelineGraph.ToNestedGraph() as it exists in the 3.0 code today — note that all it does is create a few new objects and pass in references to some existing objects. No deep cloning, no crazy data shuffling, and certainly no shared lock.

The nested container now has its own configuration model for its overrides and a reference to its parent’s configuration model. In the new world order, the nested container fulfills requests by using a sort of chain of responsibility pattern internally to locate the right action. If you ask a nested container for a service, it will:

  1. Look in its own configuration to see if it has an explicit override for that service. If one exists, build that configuration.
  2. If the nested container has no explicit override, it looks into its parent for the configuration for that service. Assuming one is found, the nested container builds out that configuration

This is over-simplified of course, but that’s the gist of the new structure and design.

I’ve had to revisit several of my OSS infrastructure projects lately (StructureMap’s nested container and shared locking problems, FubuMVC’s startup time, and now StoryTeller‘s throughput speed) to address performance issues. Depending upon my ambition level, I may write a blog post on those experiences.

How and Why?

So what factors might have led me to blunder so badly with the first implementation? What are the signs that I didn’t pick up on at the time that should have told me to go a different way than the flawed original approach? Why did it take me so long to get to a better state? How did I transform the StructureMap code into a very different internal structure to enable the better nested container performance? Why did I chicken out on a complete rewrite of StructureMap a few years back? In the next post I’ll attempt to answer those questions…

Ok, to be perfectly honest, I just ran out of steam and wanna hit “publish.” Till next time, laters.

My Talk on Long-Lived Codebases at Codemash

When I go to conferences I see a lot of talks that follow the general theme of I/my team/our product/our process/this tool is wonderful. In contrast to that, I’m giving a talk Friday at Codemash entitled “Lessons Learned from a Long-Lived Codebase” about my experiences with the evolution of the StructureMap codebase in its original production usage in 2004 all the way up to the very different tool that it is today. Many structural weaknesses in your code structure and architecture don’t become apparent or even harmful until you either need to make large functional changes you didn’t foresee or the code gets used in far higher volume systems. I’m going to demonstrate some of the self-inflicted problems I’ve incurred over the years in the StructureMap and what I had to do to ameliorate those issues in the hopes of helping others dodge some of that pain.

Because StructureMap is such an old tool that’s been constantly updated, it’s also a great microcosm of how our general attitudes toward software development, designing API’s, and how we expect our tools to work have changed in the past decade and I’ll talk about some of that.

In specific, I’m covering:

  • Why duplication of even innocuous logic can be such a problem for changing the system later
  • Abstractions should probably be based strictly on roles and variations and created neither too early nor too late
  • Why your API should be expressed in terms of your user’s needs rather than in your own tool’s internals
  • Trying to pick names for concepts in your tool that are not confusing to your users
  • For the usage of any development tool that’s highly configurable there’s a tension between making the user be very explicit about what they want to do versus providing a much more concise or conventional usage that is potentially too “magical” for many users.
  • How the diagnostics and exception messages in StructureMap have evolved in continuous attempts to reduce the cost of supporting StructureMap users;)
  • Using “living documentation” to try to keep your basic documentation reasonably up to date
  • Organizing whatever documentation you do have in regards to what the users are trying to do rather than being a dry restatement of the implementation details
  • The unfortunate tension between backward compatibility and working to improve your tool
  • Automated testing in the context of a long lived codebase. What kinds of tests allow you to improve the internals of your code over time, where I still see value in TDD for fine grained design, and my opinions about how to best write acceptance tests that came out of my StructureMap work over the years
  • Lastly, the conversation about automated testing is a great sequeway to talk about the great “Rewrite vs. Improve In-Place” discussion I faced before the big StructureMap 3.0 release earlier this year.

This is a big update to a talk I did at QCon San Francisco in 2008. Turns out there was plenty more lessons to learn since then;)

I’d be willing to turn this talk into a series of more concrete blog posts working in the before and after code samples if I get at least 5-6 comments here from people that would be interested in that kind of thing.