I want to let Ninject resolve an instance of T based on a specific enum input value.
I have read about Ninject's factory extension, but I couldn't find any example having the factory resolve a specific class based on an enum.
Each class derives from a base class and that derived class has several, different interfaces that Ninject also has to resolve.
For example this is how the interface should look like:
public interface IProcessFactory
{
T Create<T>(ProcessIndex processIndex) where T : BaseProcess;
}
How can this be achieved ?
This is not supported out of the box. You can customize it by writing your own implementation of IInstanceProvider(also see ninject Wiki entry. Then configure it for your specific factory:
kernel.Bind<IFooFactory>()
.ToFactory(() => new MyCustomInstanceProvider());
Or alternatively, if you want to change the behavior of all .ToFactory()
bindings: Rebind IInstanceProvider
after loading Ninject.Extensions.Factory
:
kernel.Rebind<IInstanceProvider>().To<MyCustomInstanceProvider>();
However, if it's not something you need often i would consider manually writing a factory implementation @ composition root.
Anyway, in both cases you'll need to know how to create a conditional binding. Ninject calls it Contextual Binding. One method is to use Binding-Metadata:
const string EnumKey = "EnumKey";
Bind<IFoo>().To<AFoo>()
.WithMetadata(EnumKey, MyEnum.A);
IResolutionRoot.Get<IFoo>(x => x.Get<MyEnum>(EnumKey) == MyEnum.A);
Another way would be to create a custom IParameter and use in a conditional binding:
Bind<IFoo>().To<AFoo>()
.When(x => x.Parameters.OfType<MyParameter>().Single().Value == A);
There are several options available to implement AbstractFactory using DI (Ninject).
After analyzing the options, I came up with the solution provided by Mark Seemann, see http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/
The Container Based Factory solution is the one I chose, because:
- Performance: on demand DI resolve on request, no instances loaded in the constructor
- Easy for refactor: when we want to replace the current DI framework (Ninject) to a much better performer with (almost or even better) featureset, the only place to change are the calls inside the factory and not in the NinjectModules/Composition Root.
See also at SO: Simple Injector:Factory classes that need to create classes with dependencies
来源:https://stackoverflow.com/questions/29941052/ninject-factory-create-t-based-on-enum