问题 如何让Ninject 2为LINQ to SQL DataContext使用无参数构造函数?


我已经开始使用Ninject 2(昨天从Github下载,包括MVC扩展项目)和一个基于以下技术的项目:

  • .Net 3.5 Sp1
  • ASP.NET MVC 1.0
  • LINQ to SQL

这里没有什么神奇之处 - 我有一些存储库接口(命名为IEntityRepository),这些接口是在运行时代码中使用LINQ to SQL实现的(并在单元测试代码中使用哈希表)。这些存储库中的每一个都需要一个从LINQ到SQL的DataContext实例才能与数据库通信,因此这是具体存储库类的构造函数参数。绑定设置如下:

Kernel.Bind<MyDataContext>().ToSelf().InRequestScope();

这样做的原因是我希望能够在不同的存储库之间共享实体,如果我碰巧需要更多它们,并且使用LINQ to SQL datacontext工作原理单元,我觉得创建一个HttpRequest的。

我通常使用MyDataContext的无参数构造函数 - 我不认为这是一个风险,因为它用于测试系统上的内部项目,因此datacontext中的“内置”连接字符串是无害的。但是,因为Ninject 2是“贪婪的”并且想要带有MOST参数的构造函数,所以我不能真正坚持 [Inject] 以任何有意义的方式将参数放入生成的代码中,每当Ninject尝试创建我的一个控制器(需要存储库,需要datacontext)时,我都会收到错误。

我见过提到 IConstructorScorer 并且能够制作一个总是使用带有LEAST参数的构造函数的“反向”,但是再一次,这将改变注入对其他一切的工作方式 - 默认行为可能是除了datacontext之外的所有内容。

那么 - 有一个很好的,干净的方式来指定这个绑定(只有这个绑定)应该使用特定的构造函数吗?我们可以和Ninject 1中的提供商做同样的事情,也许可以提供我们自己的“工厂”吗?或者我应该放弃并尝试将参数提供给有意义的datacontext?


8796
2017-07-21 10:30


起源



答案:


我想你也可以使用'ToMethod'绑定来避免实现自定义提供程序,这就是我使用它的方式:

Kernel.Bind<MyDataConext>().ToMethod(c => new MyDataContext())

7
2018-05-02 10:17



为了完整,我会添加 InRequestScope() 确保DataContext的生命周期适当确定范围。 - Peter Meyer


答案:


我想你也可以使用'ToMethod'绑定来避免实现自定义提供程序,这就是我使用它的方式:

Kernel.Bind<MyDataConext>().ToMethod(c => new MyDataContext())

7
2018-05-02 10:17



为了完整,我会添加 InRequestScope() 确保DataContext的生命周期适当确定范围。 - Peter Meyer


想出来 - 通过绑定到提供者很容易完成;

Kernel.Bind<MyDataContext>().ToProvider<ContextProvider>().InRequestScope();

Ninject现在只要需要构建其中一个讨厌的DataContext对象,就会调用我的ContextProvider。这是我的提供者类的样子:

public class ContextProvider : IProvider
{
    #region IProvider Members

    public object Create(IContext context)
    {
        return new MyDataContext();
    }

    public Type Type
    {
        get { throw new NotImplementedException(); }
    }

    #endregion
}

好像我逃脱了它 - 它工作正常。 :)


6
2017-07-22 12:56