Ninject:选择了错误的构造(Ninject: Choosing the wrong const

2019-09-23 07:24发布

我有Ninject v2.2.1.4一个ASP.NET MVC 3应用程序。 一切是伟大的工作,然后突然我们开始看到Ninject尝试使用一个构造函数在参数的构造函数的参数来创建我们的DbContext。 下面是绑定:

kernel.Bind<MyContext>().ToSelf().InRequestScope();

kernel.Bind<IUnitOfWork>().ToMethod(ctx => ctx.Kernel.Get<MyContext>());
kernel.Bind<DbContext>().ToMethod(ctx => ctx.Kernel.Get<MyContext>());

所述MyContext是一个的DbContext对象实现了IUnitOfWork接口为好。 我已经将它设置这种方式使同样的情况下被注入到在单个请求中使用多个存储库。 该MyContext构造是这样的:

public MyContext() { }
public MyContext(string connectionString) { }
public MyContext (long accountID) { }
public MyContext (Connection connection) { }

有针对不同应用不同的构造,因为它们都使用相同的MyContext类。 纵观当被请求MyContext类参数的构造函数会被调用,但不管是什么原因,你会想绑定,事实并非如此。 即使被指定帐户ID与长帐户ID参数的那个叫。 这显然throwns和异常声明说:“没有符合条件的绑定是可用的,并且类型不是自绑定”它实际上抛出试图产生IUnitOfWork时除外。

如果我注释掉最后三个构造一切工作正常,无参数的构造函数使用。 如果我注释掉参数的构造函数中的任意两个也尝试使用其他,而不是无参数之一。

由Ninject提供的建议是:

Suggestions:
  1) Ensure that you have defined a binding for long.
  2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
  3) Ensure you have not accidentally created more than one kernel.
  4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
  5) If you are using automatic module loading, ensure the search path and filters are correct.

我们没有对任何1,因为我们不希望。 我不知道是什么2和5的意思。 我不认为我们已经做了3,我们不这样做4。

任何想法,为什么它不会在这种情况下使用该参数的构造函数。

Answer 1:

@ Xander的答案是正确的,通用的,而是Ninject在V3一些非常具体的解决方案。 Ninject分数构造一个特定的算法是找到一个与它知道如何解决,因为这wiki文章中介绍的大多数参数 [号称是V2.4,这实际上是大众品牌的3.0。 看到代码 。 我想这也是wiki上。 如果不是的话,应该有人把它放在那里。

RE在你见过行为的变化,机会是隐式自我约束正在改变球门柱(分辨率过程中被添加新的注册)或您已经添加了一个绑定,取得了其他构造更吸引人的地方之一。

[Inject]属性高于一切其他条件是你以后在做什么(虽然你实际上并不想在你的代码容器特定的属性)。

WithConstructorArgument建议技术实际上是通过影响ToConstructor -做WCA不会影响选择(我想你不会得到有关冗余规范的投诉。

真正的底线是,你不应该在大一个烂摊子,因为这最终会在@马克西曼的评论提到关于此相关的问题 。


可悲的是,上面的毕竟是一个谎言。 如果你动过V2.2,这个答案将变得正确。 如果你不能或不会,你需要看的等同源和测试,以找出从之前的规则(从内存(和一些谷歌的代码出现在搜索结果在我的研究),它是基于构造计数,但不知道分数是如何消除歧义相等。

敢肯定,在2.2,添加[Inject]是出的快捷方式。



Answer 2:

默认情况下Ninject,与其他同类IoC框架一起,选择最参数的构造。 指定由初始化过程中要使用的构造WithConstructorArgument扩展方法。

kernel.Bind<DbContext>()
      .WithConstructorArgument("connectionString",
             ConfigurationManager.ConnectionStrings["connection"]
                  .ConnectionString)
      .ToMethod(ctx => ctx.Kernel.Get<MyContext>());

要强制Ninject使用默认构造函数的地方[Inject]属性的构造函数:

[Inject]
public MyContext() { }


文章来源: Ninject: Choosing the wrong constructor