注入包含所有已注册的接口实现的Enumerable
给定以下界面:
public interface IMyProcessor { void Process(); }
我希望能够注册多个实现并让我的DI容器将其中的可枚举注入到这样的类中:
public class MyProcessorLibrary { private readonly IMyProcessor[] _processors; public MyProcessingThing(IMyProcessor[] processors) { this._processors = processors; } public void ProcessAll() { foreach (var processor in this._processors) { processor.Process(); } } }
这可能吗? 我当前的IMyProcessor
实现静态查找所有IMyProcessor
实现,但如果可以,我宁愿通过容器来实现它。 我正在使用Unity,但我很好奇其他容器是否支持它。
编辑:
谢谢你到目前为止的答案; 要清楚我想将MyProcessorLibrary
注入另一个类,并将其构建为依赖对象树的连接的一部分,例如
public class MyProcessorRepository { public MyProcessorRepository(MyProcessorLibrary processorLibrary) { } } public class MyProcessorService { public MyProcessorService(MyProcessorRepository processorRepository) { } } var container = new UnityContainer(); // Register a bunch of IMyProcessors... var service = container.Resolve();
我不能代表Unity,因为我没有使用它,但我确实可以使用Ninject (参见Multi Injection )。
是的,可以这样做。 您所需要的只是为您在界面中注册的类型提供字符串名称 。 没有字符串名称的Register
仍在内部指定一个名称(据我记得它是“默认” ),当您调用Resolve
时它会被解析, 但是当您调用ResolveAll
时它不会被解析。 因此,您可能需要为所有处理器提供一些名称。
来自msdn (改编)的样本:
// Create container and register types using a name for each one IUnityContainer myContainer = new UnityContainer(); myContainer.RegisterType(); //default myContainer.RegisterType("MyProcessorB"); myContainer.RegisterType("MyProcessorC"); // Retrieve a list of non-default types registered for IMyProcessor // List will only contain the types MyProcessorB and MyProcessorC IEnumerable serviceList = myContainer.ResolveAll (); //usage var library = new MyProcessorLibrary(serviceList); library.ProcessAll();
这是来自Microsoft Unity 2.0文档。 查看您使用的版本。 对其他人来说不太确定IoC。
// Create container and register types using a name for each one IUnityContainer myContainer = new UnityContainer(); myContainer.RegisterType(); myContainer.RegisterType("number2"); // Retrieve a list of non-default types registered for IMyService IEnumerable processors = myContainer.ResolveAll();
编辑:
// update MyProcessorLibrary with this property [Dependency] public IEnumerable MyProcessingThing { get { return _processors; } set { _processors = value; } } //then inject the library class like this var lib = myContainer.Resolve(); myProcessorRepository(lib)
它完全支持MEF。
您必须导出实现此接口的所有类,然后使用[ImportMany]
例:
public interface IMyProcessor { void Process(); } [Export(typeof(IMyProcessor)] public class FirstProc : IMyProcessor { ... } [Export(typeof(IMyProcessor)] public class SecondProc : IMyProcessor { ... } [Export] public class MyTest() { [ImportMany] public IMyProcessor[] MyProcessors { get; set; } }