Fork me on GitHub

Integration with StructureMap for IoC Edit on GitHub


If you're wondering why FubuMVC uses StructureMap as its sole IoC tool, it's because Jeremy Miller is the primary author of both tools. Owning the entire stack has been convenient on a couple different occasions for performance optimizations.

FubuMVC no longer supports any IoC tool other than StructureMap. We may change that in Jasper, but for now, being StructureMap-only allowed us to greatly simplify and shrink down FubuMVC's internals for the 3.0 release. Moreover, FubuMVC uses StructureMap's optimized type scanning for its own internal bootstrapping.

Configuring Services

First off, let's say that you have your own service with an interface plus an implementation that you want to explicitly register in the underlying StructureMap container:


public interface IMyService{}
public class MyService : IMyService{}

To add this service to the underlying application container, use the FubuRegistry.Services property as shown below:


public class MyFubuApp : FubuRegistry
{
    public MyFubuApp()
    {
        // doing the registration inline
        Services.For<IMyService>().Use<MyService>();
    }
}

The FubuRegistry.Services property is just a StructureMap Registry with some additional convenience methods for very common usages in FubuMVC applications.

If your application is even remotely complicated though, we recommend using a separate Registry class for your custom services like this:


public class MyServiceRegistry : Registry
{
    public MyServiceRegistry()
    {
        For<IMyService>().Use<MyService>();
    }
}

public class MyFubuApp2 : FubuRegistry
{
    public MyFubuApp2()
    {
        // doing the registration inline
        Services.IncludeRegistry<MyServiceRegistry>();
    }
}

All of the service registration is done through StructureMap's Registry DSL mechanism.

At Runtime

When a chain is executed at runtime, StructureMap builds or resolves the entire object graph of the various behaviors. That includes:

To put that into some perspective, you can utilize StructureMap to inject your own service dependencies, FubuMVC services, and even request or message specific services too:


public class MyEndpoint
{
    private readonly IMyService _service;
    private readonly IHttpRequest _request;

    // IHttpRequest would point at the current request
    public MyEndpoint(IMyService service, IHttpRequest request)
    {
        _service = service;
        _request = request;
    }
}
The proposed Jasper architecture will reduce and simplify the usage of StructureMap at runtime by trying to drastically reduce the number of objects built by StructureMap and attempting to make much more of the service resolution lazy.

Per Request or Message Nested container

When FubuMVC executes any behavior chain by handling an HTTP request, processing a message in the service bus, or executing a job, it utilizes StructureMap's nested container feature to both manage the scoping of services and automatically handle the disposal of any service created during a chain execution. Unless a service is registered with a non-default lifecycle, you can safely assume that it is scoped to the request/message/job execution.

Service disposal

As mentioned in the previous section, StructureMap automatically tracks and disposes any objects created directly by the nested container as part of chain execution. Otherwise, services registered as singleton scoped are disposed when the StructureMap IContainer is disposed, which in turn is disposed as part of disposing a FubuRuntime.

Overriding System Dependencies

It is perfectly valid and possible to override FubuMVC's own services in your application. While this has been frequently useful, do this with some caution.

Maybe the most common usage of this is to replace FubuMVC's built in JSON serialization mechanism. The out of the box serialization uses Newtonsoft.Json, but what if you want to use an alternative like Jil instead?

Assuming that you have a class named MyJilJsonSerializer that implements FubuMVC's built in IJsonSerializer interface, you can use your own service like so:


public class MyFubuApp3 : FubuRegistry
{
    public MyFubuApp3()
    {
        Services
            .For<IJsonSerializer>()
            .Use<MyJilJsonSerializer>();
    }
}