0

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?

Tequilalime
  • 611
  • 9
  • 29

2 Answers2

1

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();
Hamlet Hakobyan
  • 32,965
  • 6
  • 52
  • 68
  • Thank you, I'll accept this as the answer but I'm not going to use Unity. This is too much hassle for a simple job which StructureMap does by default without requiring lines and lines and lines of code. – Tequilalime Mar 30 '15 at 11:24
  • The Unity auto registration nuget package has a hard dependency on an old version of the Unity assembly and it doesn't seem like assembly binding redirects solves the issue. At the moment it seems like that package might not be a workable solution for much. – BenCr Apr 11 '17 at 07:38
1

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<>));
James Simpson
  • 1,150
  • 6
  • 11