Ninject factory create T based on enum

99封情书 提交于 2019-11-28 11:20:58

问题


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 ?


回答1:


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);



回答2:


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!