开发者

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 with container.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) { ... }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜