【问题标题】:Ninject .ToFactory: Exception: "Exception thrown: 'Ninject.ActivationException' in Ninject.dll"Ninject .ToFactory:异常:“抛出异常:Ninject.dll 中的‘Ninject.ActivationException’”
【发布时间】:2017-06-23 05:59:05
【问题描述】:

我指示 Ninject 在接口上创建工厂:

this.Bind<IModelFactory>().ToFactory().InSingletonScope();

在这个工厂接口中,我定义了工厂:

interface IModelFactory
{
    MyClass CreateMyClassFactory(string param1, DateTime param2);
}

然后我尝试使用工厂创建一个新类:

Class myClass = modelFactory.CreateMyClassFactory(param1, new DateTime(2017,01,01);

...但它抛出了这个异常:

抛出异常:Ninject.dll 中的“Ninject.ActivationException”

附加信息:激活字符串时出错

没有匹配的绑定可用,并且类型不是自绑定的。

激活路径:

2) 将依赖字符串注入MyClass类型的构造函数的参数标题中

1) 请求 HedgeOrderMyClass

建议:

1) 确保您已为字符串定义绑定。

2) 如果绑定是在模块中定义的,请确保该模块已加载到内核中。

3) 确保您没有意外创建多个内核。

4) 如果您使用构造函数参数,请确保参数名称与构造函数参数名称匹配。

5) 如果您使用自动模块加载,请确保搜索路径和过滤器正确。

【问题讨论】:

  • 首先防止工厂抽象,如here 详细解释。

标签: c# ninject factory-pattern


【解决方案1】:

当您指示 Ninject 在接口上创建工厂时,您是在要求它从容器中拉出一个新的类副本,并在运行时填写任何缺失的参数。

这是我们想要的类:

public class MyClass
{

}

只要至少有一个构造函数接受stringDateTime 类型的参数,那么它就可以工作:

public class MyClass
{
    // If this constructor is missing, then it throws an exception!
    MyClass(string param1, DateTime param2, ISomeOtherInterface someOtherInterface)
    {
    }
}

Ninject 知道如何解析ISomeOtherInterface,所以这没问题(假设我们在其他地方使用了Bind&lt;&gt;.To&lt;&gt;)。但它如何解决string param1DateTime param2

工厂方法派上用场了:它将参数从参数中填充到工厂调用中,一切正常。

如果您使用调试器运行,您将看到上面的构造函数被调用,其参数与工厂创建调用中指定的参数相同。

这是一个非常强大的想法,并且避免了必须手动编写所有胶水代码来创建自己的工厂。

【讨论】:

  • 您的 MyClass 构造函数将运行时值与编译时依赖项混合在一起;这个is an anti-pattern.
  • @Steven 有时,我们需要在运行时使用自定义参数从依赖注入容器中拉出一个新类。工厂模式允许这样做。如果你花了 4 年时间专业地使用 C#,你最终会遇到不诉诸工厂模式就无法解决的问题。无论如何,这不是一个反模式——它是官方的 GOF 工厂模式。
【解决方案2】:

这就是我通常使用 Ninject.ActivationException 解决问题的方法:

using Ninject.Extensions.Factory;

// ...

var kernel = new StandardKernel()
kernel.Bind<IMyClass>().ToFactory();

【讨论】:

    猜你喜欢
    • 2013-05-24
    • 2012-01-24
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    相关资源
    最近更新 更多