I know how I can inject one or a collection of dependency interface instances into a class via constructor injection. However, in my current situation I have a bit different task.
I have several classes, and each of them has an associated "Processor" class. These processors are implementing the same IProcessor
interface, and a common Processor
class will process a collection of objects, using the appropriate processors for each of them. Creating a processor for a type can be expensive, so I'm using factories and instantiate the processor only when it's needed.
The code would look something like this.
public interface IProcessor {
void Process(object item);
}
public class Processor {
private readonly Dictionary<Type, Func<IProcessor>> _processors;
public Processor(IDictionary<Type, Func<IProcessor>> processors) {
_processors = processors;
}
public void Process(IEnumerable items) {
foreach (var item in items) {
var processorFactory = _processors.GetValueOrDefault(item.GetType());
if (processorFactory == null) continue; // for simplicity
var processor = processorFactory();
processor.Process(item);
}
}
}
How could I register the binding for this in Ninject? Or is there any kind of alternative patterns which are more "DI friendly"?
I would like to configure these "processor bindings" at application entry point level.
An alternative would be to have a static dictionary of processor factories in the Processor
class, and register the bindings manually at the entry point, but I would like to avoid using static dependencies. Or would it be still better in this particular case?
UPDATE
Another, kind of hybrid alternative which I arrived to is something like this. I would have a static Factories
dictionary in the Processor
class. There I could have basic, default implementations as a facade.
Then in my Ninject module I could write something like this.
public class MyModule : NinjectModule
{
public override void Load()
{
// ... my "standard" bindings
Processor.Factories[typeof(MyItem1)] = () => Kernel.Get<MyItem1Processor>();
Processor.Factories[typeof(MyItem2)] = () => Kernel.Get<MyItem2Processor>();
}
}
I know that I'm using the "evil" static stuff here, but still can utilize DI quite easily and in a well readable way, utilizing the Kernel
property of the module.
Is it safe to use the Kernel
property of the module inside the Load
method? I mean can a module be loaded into more kernels for example?
Any thoughts are appreciated.
IProcessor
and have theType
returned from the interface, this means that I can bind eachIProcessor
and then simply haveIEnumerable<IProcessor>
in the constructor. From that I build a dictionary of<Type, IProcessor>
– Stephen RossAnimal
type if there are no animals in the collection to process. Otherwise I would do the same and I would have no problems. – Zoltán TamásiIProcessor
interface look like? – Yacoub Massad