Tequilalime
Tequilalime

Reputation: 621

From StructureMap to Unity

I've been looking for an answer but couldn't find one. I have a project which uses StructureMap as it's dependency container but now I want to try Microsoft's unity.

However, I couldn't find how to convert this piece of code to unity:

ObjectFactory.Initialize(cfg =>
{
    cfg.For<IViewFactory>().Use<DefaultViewFactory>();

    cfg.Scan(scan =>
    {
        scan.TheCallingAssembly();
        scan.ConnectImplementationsToTypesClosing(typeof(IViewBuilder<>));                          scan.ConnectImplementationsToTypesClosing(typeof(IViewBuilder<,>));
    });
});

I know the cfg.For... part is simply calling container.RegisterType(); but how can I do the scan part in Unity?

Upvotes: 0

Views: 521

Answers (2)

James Simpson
James Simpson

Reputation: 1150

Non library way - By using reflection

Include this method somewhere in your project (maybe within the container registration class)

public static void RegisterImplementationsClosingInterface(UnityContainer container, Assembly assembly, Type genericInterface)
{
    foreach(var type in Assembly.GetExecutingAssembly().GetExportedTypes())
    {
        //   concrete class or not?
        if(!type.IsAbstract && type.IsClass)
        {
            // has the interface or not?
            var iface = type.GetInterfaces()
                .Where(i => i.IsGenericType && i.GetGenericTypeDefinition () 
                    == genericInterface).FirstOrDefault();

            if(iface != null)
            {
                container.RegisterType(iface, type);
            }
        }

    }
}

Calling:

RegisterImplementationsClosingInterface(container, Assembly.GetCallingAssembly(), typeof(IViewBuilder<>));

Upvotes: 1

Hamlet Hakobyan
Hamlet Hakobyan

Reputation: 33381

Look at the Unity Auto Registration. There is also a Nuget package for use.

Here is the sample how to use:

var container = new UnityContainer();

container
     .ConfigureAutoRegistration()
     .ExcludeAssemblies(a => a.GetName().FullName.Contains("Test"))
     .Include(If.Implements<ILogger>, Then.Register().UsingPerCallMode())
         .Include(If.ImplementsITypeName, Then.Register().WithTypeName())
         .Include(If.Implements<ICustomerRepository>, Then.Register().WithName("Sample"))
         .Include(If.Implements<IOrderRepository>,
               Then.Register().AsSingleInterfaceOfType().UsingPerCallMode())
         .Include(If.DecoratedWith<LoggerAttribute>,
               Then.Register()
                      .As<IDisposable>()
                      .WithTypeName()
                      .UsingLifetime<MyLifetimeManager>())
         .Exclude(t => t.Name.Contains("Trace"))
         .ApplyAutoRegistration();

Upvotes: 1

Related Questions