Given the following interface:
public interface IMyProcessor
{
void Process();
}
I'd like to be able to register multiple implementations and have my DI container inject an enumerable of them into a class like this:
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();
}
}
}
Is this possible? My current implementation of MyProcessorLibrary
looks up all the IMyProcessor
implementations statically, but I'd rather do it through a container if I can. I'm using Unity, but am curious if other containers support it.
Edit:
Thanks for the answers so far; to be clear I want to inject MyProcessorLibrary
into another class, and have it built as part of the wiring up of a tree of dependent objects, e.g.
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<MyProcessorService>();
Yes, it is possible to do this. All you need, is to give string names to the types you are registering with the interface. Register
without a string name still assignes a name (as far as I remember it is "Default") internally, it is resolved when you call Resolve<T>
, but it is not resolved when you call ResolveAll<T>
. So you may need to give all your processors some names.
A sample from msdn (adapted):
// Create container and register types using a name for each one
IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IMyProcessor, MyProcessorA>(); //default
myContainer.RegisterType<IMyProcessor, MyProcessorB>("MyProcessorB");
myContainer.RegisterType<IMyProcessor, MyProcessorC>("MyProcessorC");
// Retrieve a list of non-default types registered for IMyProcessor
// List will only contain the types MyProcessorB and MyProcessorC
IEnumerable<IMyProcessor> serviceList = myContainer.ResolveAll<IMyProcessor>();
//usage
var library = new MyProcessorLibrary(serviceList);
library.ProcessAll();
I can't speak for Unity as I don't use it but it is definitely possible with Ninject (see Multi Injection) which I do use.
This is from Microsoft Unity 2.0 documentation. Check out the version you use. Not sure for others IoC.
// Create container and register types using a name for each one
IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IMyProcessor, MyProcessor1>();
myContainer.RegisterType<IMyProcessor, MyProcessor2>("number2");
// Retrieve a list of non-default types registered for IMyService
IEnumerable<IMyProcessor> processors = myContainer.ResolveAll<IMyService>();
EDIT:
// update MyProcessorLibrary with this property
[Dependency]
public IEnumerable<IMyProcessor> MyProcessingThing
{
get { return _processors; }
set { _processors = value; }
}
//then inject the library class like this
var lib = myContainer.Resolve<MyProcessorLibrary>();
myProcessorRepository(lib)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With