使用Ninject 2在基础控制器中进行属性注入

Tho*_*mas 5 ninject ioc-container ninject-2 asp.net-mvc-2

我在Global.aspx中有以下代码

protected override void OnApplicationStarted()
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);
    RegisterAllControllersIn(Assembly.GetExecutingAssembly());
}

protected override IKernel CreateKernel()
{
    return new StandardKernel(new ServiceModule());
}
Run Code Online (Sandbox Code Playgroud)

我还有以下Ninject模块:

internal class ServiceModule : NinjectModule
{
    public override void Load()
    {
        Bind<IProductService>().To<ProductService>().InRequestScope();
    }
}
Run Code Online (Sandbox Code Playgroud)

我还有一个基本控制器:

public class BaseController : Controller
{
    [Inject]
    public IProductService ProductService
    {
        get;
        set;
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码有效.我遇到的问题是我想从基本控制器中删除inject属性,并在Ninject ServiceModule中指定它.换句话说,我如何在ServiceModule中编写绑定规则,告诉Ninject将ProductService注入基本控制器的属性?

如果我删除该属性,我将得到NullReferenceException.

Rub*_*ink 3

基于约定的绑定位于http://github.com/ninject/ninject.extensions.conventions - 一个实现IBindingGenerator. 但这主要与发现接口和服务有关。

一般来说,构造函数注入是一种很好的默认方法。然而,ASP.NET MVC 的工作方式使得这变得更难做到(因此 FubuMVC 等)。因此,财产注入是下一个最佳选择。

您可能会发现使用OnActivationin yourBind可能可以让您做足够的事情 - 如果可以的话,这是迄今为止最简单的。

我将您尝试做的事情描述为基于约定的激活。问题是:

  • 决定要自动注入的内容。你打算注入所有非具体的公共内容吗?你的内核知道的一切?除非您能够对想要做什么有一个清晰的定义,否则注入过程可能会变得不可预测且难以理解。您最终需要进行大量调试并向同事解释。

  • 使其高效。Ninject 在幕后动态生成代码,以使实例的激活更加高效(即,在遍历类寻找[Inject]标记时,它会生成一次代码来执行此操作,然后会像您手写的一样进行抖动)。

查看代码,没有简单的方法 OOTB。看起来添加一个自定义IInjectionHeuristic就可以了。

然而,如果你要深入了解容器,你需要

  1. 暂停一下,看看是否可以通过不走这条路来保持简单
  2. 转到 ninject 邮件列表并搜索类似的内容
  3. 如果您仍然想这样做,请在那里发送邮件。