Is this a decent implementation

Apr 28, 2013 at 6:32 AM
I'm implementing IContainer from NServiceBus.
http://support.nservicebus.com/customer/portal/articles/852357-containers

Not shown in the docs, there is an interface method
void Configure<T>(Func<T> component, DependencyLifecycle dependencyLifecycle);

If thought this would map nicely to:
public void Register<TService>(Func<TService> instanceCreator, Lifestyle lifestyle) where TService : class
But the IContainer interface doesn't have the class constraint.

As to not disturb either interface, I read the SimpleInjector source and came up with the following implementation. Is it ok?
public void Configure<T>(Func<T> component, DependencyLifecycle dependencyLifecycle)
{
    var registration =
        Translate(dependencyLifecycle)
            .CreateRegistration(typeof (T), () => component(), container);

    container.AddRegistration(typeof(T), registration);
}

private Lifestyle Translate(DependencyLifecycle dependencyLifecycle)
{
    switch (dependencyLifecycle)
    {
        case DependencyLifecycle.InstancePerCall:
            return Lifestyle.Transient;
        case DependencyLifecycle.SingleInstance:
            return Lifestyle.Singleton;
        case DependencyLifecycle.InstancePerUnitOfWork:
            return new LifetimeScopeLifestyle(disposeInstanceWhenLifetimeScopeEnds: true);
        default:
            throw new ArgumentException("Unhandled lifecycle - " + dependencyLifecycle);
    }
}
Coordinator
Apr 28, 2013 at 7:19 AM
It seems you took your time to understand what Simple Injector is doing under the covers. I am not that familiar with NServiceBus, so I don't know what the exact contract is of the Configure mrthod, but drom a Simple Injector perspective your code is fine.

But do take a good look at what InstancePerUnitOfWork means. Although the LifetimeScope is a good fit, I could imagine the WebRequestLifestyle to be a better fit when ran inside an ASP.NET application. But perhaps it's unusual to run this inside a web application. So perhaps it doesn't make much sense what I'm saying.
Apr 28, 2013 at 2:27 PM
Thanks.

Looking through the source code, it looks like it's main use is in a console app. What would happen if someone used new LifetimeScopeLifesyle in an ASP.Net app?
Coordinator
Apr 28, 2013 at 6:55 PM
In general you should use the Web Request Lifestyle in ASP.NET applications, since web requests can span multiple threads (they can be finished on a different thread than where they're started) and the Web Request Lifestyle works as expected. LifetimeScope lifestyle on the other hand should not be used to wrap a complete web request, since it is thread-specific, while the web request could span multiple threads.

This doesn't mean however, that a LifetimeScope lifestyle can't be used in web applications, but you should ensure that it is started and finished on the same thread. You can for instance wrap certain operations within a scope, or use it when operations are started on a background thread (in which case there is no HttpContext.Current). Take for instance this example.
Marked as answer by dot_NET_Junkie on 11/5/2013 at 7:40 AM