Convert Structuremap to Unity

Topics: General discussion
Dec 7, 2010 at 10:13 PM

I am in the process in reducing my external library dependencies (log4net and StructureMap) to Entlib 5.0. This worked well for my logging block but can anybody give advice on how to convert the following to a Unity equivalent:

The registry:

   public class MyRegistry : Registry
    {
        public MyRegistry()
        {
            For<ISomeInterface>().Singleton().Use<...>();
            For<ISomeInterface>().HybridHttpOrThreadLocalScoped().AddInstances(...);
        }
    }

And of course the initialization (in global.asax):

 ObjectFactory.Initialize(x => x.AddRegistry(new MyRegistry()));
 ObjectFactory.AssertConfigurationIsValid();

Thanks for any help!

Evert Wiesenekker

 

 

Dec 8, 2010 at 4:30 AM

I am not familiar with StructureMap, my understanding regarding your question is how would you instantiate your MyRegistry using Unity, right? If yes, then first thing you need to do is to configure the container with the required aliases, type registrations, mappings, and other information that it requires in order to resolve objects at run time and inject the appropriate objects and values into dependent objects. You can configure it in two ways either Using Design Time Configuration or Using Run Time Configuration (you can check the code samples from those link). Once configured, then you can now be able to instantiate or resolve objects that you have initially registered in your container. Here's another link regarding Resolving an Object Type in Unity. Hope this helps.

As for any Unity related questions or inquiry we recommend posting them in the Unity discussion site - http://unity.codeplex.com/discussions, this will also help you to get answers to other Unity developers out there. :-)

Gino Terrado
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

 

Dec 8, 2010 at 5:17 AM

I'm not too familiar with StructureMap, but I can guess at what that code is doing. Mostly. StructureMap has the concept of Registries, which are classes used to initialize the container. Unity doesn't have a Registry concept, it just has a direct container API. If you wish to keep the idea of a registry type where you put your initialization logic, I've had a lot of luck lately using Unity extensions to do this.

To create the extension, do this:

public class MyRegistry : UnityContainerExtension
{
    protected override void Initialize()
    {
        // use container API here to register your types0
       
    }
}

To add it to the container, do:

container.AddNewExtension<MyRegistry>();

Unity doesn't have an equivalent of the AssertConfigurationIsValid method, so you'll have to do without that one, but that method is for diagnostics anyway, so you're ok without it.

As for the details of registration, the "For<interface>.lifetime().Use<impl>()" form of APIs in StructureMap end up in Unity as:

container.RegisterType<interface, impl>(
    new LifetimeManager());

Where you need to pick the appropriate LifetimeManager class to match what you were doing in StructureMap. If you don't give a lifetime manager, Unity defaults to Transient. I believe StructureMap defaults to what we call PerResolveLifetimeManager. Singleton corresponds to ContainerControlledLifetimeManager. I'm not familiar with what that HybridHttpOrThreadLocalScoped does, but I expect we don't have a direct analogue, but if you tell me what it does it'll be pretty easy to replicate in a custom lifetime.

Also, what does AddInstances do?

Anyway, you can either call these directly on an instance of IUnityContainer, or if you want to go the separate registry route via an extension above, just call those methods on the Container property of the extension. That'll get the container set up.

Oh, also, if you're using any of the assembly scanning stuff in StructureMap, we don't have a pre-written analogue to that stuff, but it's pretty easy to write something similar, you just need to do it once and it's done.

Hope this helps,

-Chris

Dec 8, 2010 at 9:45 AM
Edited Dec 8, 2010 at 10:09 AM

Thank you both for your very fast and helpful answers, I am sure I can convert it to Unity now (Dependency Injection is still a newbie area for me so your help is appreciated).

I am sorry I posted it in the wrong group, I already was wondering why the wasn't a Unity discussion 'checkbox', so I posted it to General.

By the way:

Your Question 1:

The mode 'HybridHttpOrThreadLocalScoped' means it uses the HttpContext when available. If not, it falls back to caching per thread.

Your Question 2:

AddInstances gives you the the ability to create named instances, but I use it to supply a Factory to create the instance for me, so:

AddInstances(instance => instance.ConstructedBy(context => context.GetInstance<ISomeFactoryBuilder>().GetSomeFactory().CreateSomething()));

 

Best regards,

Evert