Unity and dependence on collection of objects
In my case some class depends not on a single object, but on collection of them:
public class ImportController { ...
public ImportController(IEnumerable<IImportManager> managers) { ... }
}
public class ProductAImportManager : IImportManager { ... }
public c开发者_运维百科lass ProductBImportManager : IImportManager { ... }
public class ProductCImportManager : IImportManager { ... }
I want to instantiate ImportController using Unity, so how should I register the dependencies?
If I use something like
unityContainer.RegisterType<IImportManager, ProductAImportManager>();
unityContainer.RegisterType<IImportManager, ProductBImportManager>();
second call just overrides the first one.
Is there any way to ask Unity to find all types registered that implements IImportManager interface, instantiate these types and pass the sequence of objects to my constructor?
Unity has somewhat bizarre resolution rules when it comes to multiple registrations.
Registrations made without a name (i.e.
container.RegisterType<IInterface, Implementation>()
) can only be resolved withcontainer.Resolve
.Registrations made with a name can only be resolved with
container.ResolveAll<IInterface>()
.
The trick I use to depend on a collection of registrations is a two line method that calls ResolveAll
behind the scenes:
public static class UnityExtensions {
public static void RegisterCollection<T>(this IUnityContainer container) where T : class {
container.RegisterType<IEnumerable<T>>(new InjectionFactory(c=>c.ResolveAll<T>()));
}
}
Usage is simple from here on in.
//First register individual types
unityContainer.RegisterType<IImportManager, ProductAImportManager>("productA");
unityContainer.RegisterType<IImportManager, ProductBImportManager>("productB");
//Register collection
unityContainer.RegisterCollection<IImportManager>();
//Once collection is registered, IEnumerable<IImportManager>() will be resolved as a dependency:
public class ImportController { ...
public ImportController(IEnumerable<IImportManager> managers) { ... }
}
You can, with named types and arrays:
unityContainer.RegisterType<IImportManager, ProductAImportManager>("a");
unityContainer.RegisterType<IImportManager, ProductBImportManager>("b");
public class ImportController { ...
public ImportController(IImportManager[] managers) { ... }
}
精彩评论