【问题标题】:How to get objects out of Ninject OR how to make Ninject construct objects?如何从 Ninject 中取出对象或如何使 Ninject 构造对象?
【发布时间】:2010-11-18 07:17:26
【问题描述】:

如果这里已经有类似的问题,请原谅我,但我找不到。

无论如何,我有一个使用 Ninject 2 作为 DI 的 ASP.NET MVC 2 应用程序。我将控制器上的构造函数设置为没有参数,这意味着它们必须实例化所需的Providers。当我有 Providers 具有自己的依赖项(例如 Repositories)时,问题就出现了,它们还具有自己的依赖项,例如 DataContext

所以,我很好奇我是否可以 A) 从 Ninject 中获取对象,例如 DataContext 并将其传递到我将要创建的极长的实例链中,或者 B ) 让 Ninject 构造我需要传入的对象?

我在 Ninject Wiki 上四处寻找,但找不到令人满意的答案。另外,我几乎没有任何使用 Ninject 的经验,所以请把我当作这方面的菜鸟。

无论如何,提前谢谢!

附:不确定这是否重要,但我这样做是因为“No parameterless constructor defined for this object.”突然出现并破坏了我的应用程序。我不知道是什么原因突然造成的,但是在没有“无参数构造函数”和 Ninject 做它的事情的情况下,应用程序运行良好。如果有人对解决此问题并避免上述所有其他事情有任何建议,我都是你的。

更新(参考@JC)

好吧,我确定我是从 NinjectHttpApplication 继承的,然后我在 Global.asax 中这样做:

protected override IKernel CreateKernel() {
    var Kernel = new StandardKernel();

    Kernel.Bind<DataContext>().ToSelf().InSingletonScope();

    return (Kernel);
}

我没有在这里绑定任何存储库或服务,因为我没有使用接口,因为应用程序在没有 DI 或存储库的情况下诞生,但上周收到了升级。坦率地说,如果我想连接所有东西,我是 50/50,但这不是重点。

我要强调的是,这在一个半星期内运行良好(减去我纠正的错误),它只是突然停止了。我得到了上面的异常所说的内容,但是直到现在,在没有“无参数构造函数”的情况下,应用程序都可以正常工作。我什至不确定是控制器造成的。在整个过程中被实例化的类是否可以成为原因,但是由于控制器触发了处理,因此它被归咎于异常(我只是指说控制器是原因的堆栈跟踪)?

【问题讨论】:

  • 您是在应用程序中设置了 Ninject MVC 还是仅设置了 Ninject? (github.com/ninject/ninject.web.mvc)
  • 我很确定 MVC 版本,因为 Global.asax 中的 MvcApplication 继承自 NinjectHttpApplication。

标签: c# asp.net-mvc dependency-injection ninject


【解决方案1】:

有几种方法可以做到这一点(据我所知):

  1. 让您的应用程序扩展 NinjectMvcApplication 类, 应用程序包含在您的 Global.asax.cs 文件。然后覆盖 CreateKernel 方法,实例化一个 包含绑定的模块 然后返回一个新内核,比如 这个:

    protected override IKernel CreateKernel()
    {
        var modules = new INinjectModule[]
        {
            new YourModule()
        };
    
    
    
    return new StandardKernel(modules);
    
    }

    您的绑定模块应包含控制器及其依赖项的绑定。如果您的控制器实例化 repo 和其他东西以执行其任务,那么它们实际上是依赖项,您应该真正制作构造函数参数。

  2. 另一种方法(更啰嗦) 方法是创建自己的 控制器工厂类 扩展 DefaultControllerFactory 班级。有一堆方法 你可以覆盖但你应该 绝对覆盖是:

    protected override IController GetControllerInstance(
        RequestContext requestContext, Type controllerType);
    

    在此方法的主体中,您将以正常方式使用绑定加载内核,然后要求内核为您提供请求的控制器类型的实例:kernel.Get(controllerType)

当然,您可能不希望为每个请求创建和加载新内核,因此您决定缓存一些内容以提高效率。

我更喜欢使用选项 1,但这只是我自己。

【讨论】:

  • 虽然我想通了,但是因为你努力回答,所以删除我的帖子感觉不对,所以你得到了积分。正因为如此,并且因为你建议更多高级使用我没有使用过的 Ninject,但我知道你在说什么。
  • @JC:+1 好答案,重要提示:使用 Ctrl-K 缩进您的代码 sn-ps(将鼠标悬停在编辑器窗口顶部的按钮上!)
【解决方案2】:

好的,我明白了。在我在上面的更新中提到了@JC 的另一个问题后,我开始考虑更多。我去了我认为问题出在哪里(这不是我假设的控制器)并开始有选择地添加依赖项直到它失败。

我终于找到了导致原因的依赖项并找出了原因。我有一个BaseProvider 用于低级支持对象,OfficeProvider 用于处理Office 对象以及与它们相关的所有内容。好吧,BaseProvider 需要一个OfficeProvider 的实例来构造DashboardView(这是视图的模型);然而,OfficeProvider 需要一个 BaseProvider 的实例来构建自己的视图模型。因此,我导致了一个无限实例化循环,不知何故导致了我最初得到的异常。

吸取的教训,交叉依赖的课程很糟糕......因为现在是凌晨 2:30,我会把我的错误归咎于困倦。

>:3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-13
    • 2021-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多