【问题标题】:Ninject factory create T based on enumNinject工厂基于枚举创建T
【发布时间】:2015-04-29 10:29:25
【问题描述】:

我想让 Ninject 根据特定的枚举输入值解析 T 的实例。

我已经阅读了有关 Ninject 的工厂扩展的信息,但我找不到任何让工厂基于枚举解析特定类的示例。

每个类都派生自一个基类,而该派生类有几个不同的接口,Ninject 也必须解决这些接口。

例如,界面应该是这样的:

public interface IProcessFactory
{
    T Create<T>(ProcessIndex processIndex) where T : BaseProcess;
}

如何做到这一点?

【问题讨论】:

    标签: c# ninject


    【解决方案1】:

    开箱即用不支持此功能。您可以通过编写自己的IInstanceProvider 实现来自定义它(另请参阅ninject Wiki entry。然后为您的特定工厂配置它:

    kernel.Bind<IFooFactory>()
          .ToFactory(() => new MyCustomInstanceProvider());
    

    或者,如果您想更改所有.ToFactory() 绑定的行为:在加载Ninject.Extensions.Factory 后重新绑定IInstanceProvider

    kernel.Rebind<IInstanceProvider>().To<MyCustomInstanceProvider>();
    

    但是,如果它不是您经常需要的东西,我会考虑手动编写工厂实现@组合根。

    无论如何,在这两种情况下,您都需要知道如何创建条件绑定。 Ninject 称之为Contextual Binding。 一种方法是使用 Binding-Metadata:

    const string EnumKey = "EnumKey";
    
    Bind<IFoo>().To<AFoo>()
                .WithMetadata(EnumKey, MyEnum.A);
    
    IResolutionRoot.Get<IFoo>(x => x.Get<MyEnum>(EnumKey) == MyEnum.A);
    

    另一种方法是创建自定义IParameter 并在条件绑定中使用:

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

    【讨论】:

    • 最好使用 kernel.Bind().ToFactory(() => new MyCustomInstanceProvider());这让您可以定义应将哪个实例提供程序用于特定的工厂绑定。
    • @treze 谢谢,这是一个很好的观点,我会将它包含在我的帖子中。然而,我们所做的是向我们在很多地方使用的 InstanceProvider 添加更多功能。在那种情况下,我认为实际上最好“全局”提供它而不是每个绑定特定的。
    • 如果你想让它成为你的默认实例提供者,那当然是有意义的
    • 没有提供的解决方案工作。我有一个 Ninject 模块,所有绑定都已完成。我目前有一个严重的性能问题,有一个自定义 ProcessFactory :IProcessFactory,注入了所有进程,其中 Create 方法通过枚举值返回正确的注入实例。这不是我想要的,我希望 Ninject 按需解析正确的实例......
    • @PatrickPeters 你能解释一下提供的解决方案在哪里失败。正确的实例会按需解析和实例化。该解决方案不需要创建T 的所有实现(注入工厂)只是为了创建您想要的(由枚举指定)。
    【解决方案2】:

    有几个选项可用于使用 DI (Ninject) 实现 AbstractFactory。

    在分析了选项后,我想出了Mark Seemann提供的解决方案,见http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/

    我选择了基于容器的工厂解决方案,因为:

    • 性能:按需 DI 按需解析,构造函数中未加载实例
    • 易于重构:当我们想要将当前的 DI 框架 (Ninject) 替换为具有(几乎或什至更好)功能集的更好性能时,唯一需要更改的地方是工厂内部的调用,而不是 NinjectModules/作曲根。

    另见 SO: Simple Injector:Factory classes that need to create classes with dependencies

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 2017-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多