最近我转向了 MVC 3 和 Ninject 2。在大多数代码中,我使用构造函数注入,但有一些地方,我不得不使用 Inject 属性。Ninject 2 注册自己的 IDepencyResolver 界面。我不喜欢 DependencyResolver 类是一部分 System.Web.Mvc 命名空间,因为它的功能与 MVC 并不严格相关,但是现在,当它存在时,我可以做

public SomeClass 
{
    public IUserService UserService { get; set; }

    public SomeClass()
    {
        UserService = DependencyResolver.Current.GetService<IUserService>();

代替

public SomeClass 
{
    [Inject]
    public IUserService UserService { get; set; }

所以我不必参考 Ninject 我的类中的命名空间。应该 DependencyResolver 可以这样使用吗?

有帮助吗?

解决方案

我仅将属性注入用于类正常工作不需要的依赖项,但如果用户设置它们,则可以添加一些功能。此类功能的示例是日志记录。因此,您可以有一个代表记录器的属性,用户可以在其中提供自己的实现,如果他不提供,该类将继续正常工作,但它根本不会记录。

对于其他一切,我使用构造函数注入。通过这种方式,您可以向消费者表明该类对某些其他服务具有必需的依赖关系。

因此,为了回答您有关财产注入的问题,我只需:

public SomeClass 
{
    public IUserService UserService { get; set; }

    public void SomeMethodWhichDoesntEnforceUserService()
    {
        if (UserService != null)
        {
            // Provide some additional functionality
        }
    }
}

如果您的类在没有用户服务的情况下无法正常运行:

public SomeClass 
{
    private readonly IUserService _userService;
    public SomeClass(IUserService userService)
    {
        _userService = userService;
    }

    public void SomeMethodWhichRequiresTheService()
    {
        _userService.DoSomething();
    }
}

因此,在这两种情况下都没有提及任何 DI 细节。这就是控制反转的意义所在。

其他提示

我要问的第一个问题是为什么你不能执行构造函数注入 IUserService 进入 SomeClass?这可能表明设计存在问题。

为了避免直接引用 DependencyResolver 您可以通过 DI 框架实现某种形式的服务定位器抽象,例如 公共服务定位器, ,但作为答案 这个问题 表明,在正确执行 DI 时,此类抽象不是必需的。相反,您应该调整应用程序的设计。

我相信 mvc3 的 ninject.web.mvc 版本现在支持过滤器属性上的构造函数注入。你尝试过吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top