Asp.net mvc 3 在MVC3的抽象基控制器中使用Ninject进行不带属性的属性注入

Asp.net mvc 3 在MVC3的抽象基控制器中使用Ninject进行不带属性的属性注入,asp.net-mvc-3,ninject,ninject-2,Asp.net Mvc 3,Ninject,Ninject 2,我有以下代码: public abstract class BaseController : Controller { public IUserService UserService { get; set; } } kernel.Bind<BaseController>() .ToSelf() .WithPropertyValue("UserService", x => x.Kernel.GetService(typeof(IUserServi

我有以下代码:

public abstract class BaseController : Controller
{
    public IUserService UserService { get; set; }
}
kernel.Bind<BaseController>()
      .ToSelf()
      .WithPropertyValue("UserService", x => x.Kernel.GetService(typeof(IUserService)));
我的所有控制器都继承自此基本控制器。我首先使用以下代码在Ninject中配置它:

public abstract class BaseController : Controller
{
    public IUserService UserService { get; set; }
}
kernel.Bind<BaseController>()
      .ToSelf()
      .WithPropertyValue("UserService", x => x.Kernel.GetService(typeof(IUserService)));
kernel.Bind()
.ToSelf()
.WithPropertyValue(“UserService”,x=>x.Kernel.GetService(typeof(IUserService));
这不起作用。我假设这是因为BaseController是一个抽象类(请确认我的假设)。因此,我继续将配置修改为:

kernel.Bind<HomeController>()
      .ToSelf()
      .WithPropertyValue("UserService", x => x.Kernel.GetService(typeof(IUserService)));
kernel.Bind()
.ToSelf()
.WithPropertyValue(“UserService”,x=>x.Kernel.GetService(typeof(IUserService));
这确实有效。次要的缺点是,我现在必须以相同的方式配置每个控制器

由于我的ASP.NET MVC 3项目中也有DependencyResolver设置,我还可以删除上述Ninject配置,并修改我的基本控制器,使其看起来像:

    public IUserService UserService
    {
        get
        {
            return DependencyResolver.Current.GetService<IUserService>();
        }
    }
公共IUserService用户服务
{
得到
{
返回DependencyResolver.Current.GetService();
}
}
使用fluent配置与使用DependencyResolver方法相比有什么好处吗?一个比另一个好吗?哪种方法被认为是更好的做法


值得一提的是,我不想在我的基本控制器中进行构造函数注入。

MVC中更好的做法是使用构造函数注入而不是属性注入。你为什么做出这样的选择

使用构造函数注入可以声明构造函数中的所有依赖项都是类完成其工作所必需的

属性注入意味着依赖项是可选的或者存在本地默认实现,因此即使您自己没有提供必要的实现,所有这些都可以工作

您应该真正知道使用属性注入在做什么,否则就别无选择,因此更安全的方法是依赖构造函数注入

现在我将向大家介绍我的观点。其他人可能有其他意见

在MVC 3中引入DependencyResolver是为了“方便”服务定位,但对我来说,它是一个常规的服务定位器,对我来说也是一种反模式。我不使用它,因为我不喜欢它,而且使用它没有任何好处。 我更喜欢像以前一样使用我的控制器工厂,并通过构造函数传递依赖项


此外,idependencysolver在某些IoC容器上存在一些问题(我不知道Ninject是否存在这种情况)。你可以在这里阅读更多内容:

他们说有很多方法可以剥猫皮。可以将基于约定的绑定与
.WithPropertyValue()
.OnActivaction()
一起使用(如上所述)

见鬼,你甚至可以使用服务定位器模式,如果你使用它感到舒服的话

public IUserService UserService
{
    get { return DependencyResolver.Current.GetService<IUserService>(); }
}
公共IUserService用户服务
{
get{return DependencyResolver.Current.GetService();}
}

您应该选择最容易实现、测试和维护的解决方案,当然也可以提供所需的行为。

如果每个控制器都需要相同的依赖关系,那么您的设计似乎有问题。很可能您正在处理基本控制器中的某种横切问题。在这种情况下,财产注射只是治疗症状,而不是治愈疾病。这应该由一个方面(例如过滤器或拦截器)来处理,这样你就不必用不属于那里的东西污染你的控制器。

这个问题不是已经在,尽管形式稍有不同。这个问题涉及MVC 3中的DependencyResolver,而上一个问题没有涉及。还有一个问题是,与如何做相比,哪种方法更好。MVC3/DependencyResolver绝对没有变化。有一种方法被认为更“正确”吗?我可以实现其中的任何一个,它将工作,并做它需要做的事情,但哪一个是最正确的方法?我想说,正确的方法是提供最少努力的方法。在这种情况下,很可能是自定义控制器激活器或服务定位器(依赖项定位器)。但正如@Remo Gloor所指出的,您可能希望完全远离这种体系结构。