structuremap3

Upgrading Shortbus from StructureMap v2 to v3


I've started using Shortbus, but I'm having some DLL versioning issues between the StructureMap.MVC5 package and Shortbus. Shortbus uses StructureMap 2.6.3 and the MVC5 package is using 2.6.3.

I've tried dependency redirection, but because of the MajorVersion change, Shortbus is causing me a problem.

Since it is an open source project I decided to try and upgrade Shortbus to vewrsion 3 of StructureMap.

I'm stuck on moving this old code:

[Test]
public void StructureMapResolveSingleInstance()
{
    var registered = new Registered();

    ObjectFactory.Initialize(i => i.Register(registered));

    var resolver = new StructureMapDependencyResolver(ObjectFactory.Container);

    var resolved = (Registered) resolver.GetInstance(typeof (Registered));

    Assert.That(resolved, Is.EqualTo(registered));
}

..to version 3. The problem falls on Register and the fact that the ObjectFactory is now considered obsolete.

I assume I need to create my own ObjectFactory as per this answer: https://stackoverflow.com/a/25551005/119624

And include my own registry. Can anyone help me on my way with some code?


Solution

  • I would always advise against the use of the Object Factory if and where possible, however if there are instances where you require access to a container and are unable to inject it via either constructor injection or property setters then you're correct in your assumption that creating your own implementation of the ObjectFactory is the next best thing.

    The link your reference is a good starting point for creating your own ObjectFactory, from here all you'd need to do is register your StructureMap registry like so:

    private static Container defaultContainer()
    {
        return new Container(x =>
        {
            x.AddRegistry<WebsiteRegistry1>();
            x.AddRegistry<WebsiteRegistry2>();
         });
     }
    

    If you're writing a website or web application - which I assume you are if you're using ShortBus then another approach is using a HttpContext bounded nested container. This is where you create a nested version of your container (more on nested containers here) that's stored within the HttpContext object of each page request. You can then return an instance of the container using a static instance to it.

    To see how this can be done I'd recommend you take a look at Jimmy Bogard's ContosoUniversity rewrite here he does just this (see here for usage):

    public class StructureMapValidatorFactory : ValidatorFactoryBase
    {
        public override IValidator CreateInstance(Type validatorType)
        {
            return StructuremapMvc.ParentScope.CurrentNestedContainer.TryGetInstance(validatorType) as IValidator;
        }
    }
    

    The setup for such a usage can be viewed here and here.

    I hope this helps. If you do have any questions regarding this then I'd be happy to help answer them the best I can.

    Side note: If you're using ShortBus I'd recommend also taking a look at Mediatr. It's based off of ShortBus but with a few additional features and much better documentation.