简体   繁体   English

Ninject工厂根据枚举创建T

[英]Ninject factory create T based on enum

I want to let Ninject resolve an instance of T based on a specific enum input value. 我想让Ninject根据特定的枚举输入值解析T的实例。

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. 我已经阅读了有关Ninject工厂扩展的内容,但是我找不到工厂根据枚举解析特定类的任何示例。

Each class derives from a base class and that derived class has several, different interfaces that Ninject also has to resolve. 每个类派生自一个基类,派生类有几个不同的接口,Ninject也必须解决这些接口。

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: 您可以通过编写自己的IInstanceProvider实现来自定义它(也可以参见ninject Wiki条目 。然后为您的特定工厂配置它:

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 : 或者,或者,如果你想改变所有的行为.ToFactory()绑定:重新绑定IInstanceProvider样之后, 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. 但是,如果它不是您经常需要的东西,我会考虑手动编写工厂实现@ composition root。

Anyway, in both cases you'll need to know how to create a conditional binding. 无论如何,在这两种情况下,您都需要知道如何创建条件绑定。 Ninject calls it Contextual Binding . Ninject称之为Contextual Binding One method is to use Binding-Metadata: 一种方法是使用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: 另一种方法是创建自定义IParameter并在条件绑定中使用:

Bind<IFoo>().To<AFoo>()
            .When(x => x.Parameters.OfType<MyParameter>().Single().Value == A);

There are several options available to implement AbstractFactory using DI (Ninject). 有几个选项可用于使用DI(Ninject)实现AbstractFactory。

After analyzing the options, I came up with the solution provided by Mark Seemann, see http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/ 在分析了这些选项之后,我想出了Mark Seemann提供的解决方案,请参阅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 性能:按需DI根据请求解析,没有在构造函数中加载实例
  • 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. 易于重构:当我们想要将当前的DI框架(Ninject)替换为具有(几乎或甚至更好)功能集的更好的执行者时,唯一需要改变的地方是工厂内的调用而不是NinjectModules / Composition Root。

See also at SO: Simple Injector:Factory classes that need to create classes with dependencies 另请参见SO: Simple Injector:需要创建具有依赖项的类的Factory类

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM