11

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

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

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

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

这样做的原因是,如果我碰巧需要更多实体,我希望能够在不同的存储库之间共享它们,并且使用 LINQ to SQL 数据上下文工作单元的理念,对我来说创建一个似乎是有意义的Http请求。

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

我已经看到提到IConstructorScorer并能够制作一个始终使用带有 LEAST 参数的构造函数的“倒置”函数,但话又说回来,这将改变注入对其他所有事物的工作方式——默认行为可能是我想要的一切但数据上下文。

那么 - 有没有一种很好、干净的方法来指定这个绑定(并且只有这个绑定)应该使用一个特定的构造函数?我们是否可以像在 Ninject 1 中那样对提供者做同样的事情,或者提供我们自己的“工厂”?还是我应该放弃并尝试将参数输入到有意义的数据上下文中?

4

2 回答 2

7

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

Kernel.Bind<MyDataConext>().ToMethod(c => new MyDataContext())
于 2010-05-02T10:17:48.333 回答
6

想通了——通过绑定到提供者很容易做到;

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
}

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

于 2009-07-22T12:56:10.637 回答