在ASP.NET MVC 3应用程序中引用类库中的Ninject

时间:2011-10-28 00:45:21

标签: asp.net-mvc ninject

我有一个ASP.NET MVC 3应用程序,它使用Ninject.MVC3扩展在我的MVC应用程序中设置DI。也就是说,NinjectMVC3.cs文件夹中的App_Start文件定义了我的绑定。这适用于我的应用程序控制器中的DI。

除了ASP.NET MVC Web应用程序之外,我的解决方案还包含一个类库项目,我们称之为MyProject.Core,它具有我的域模型,服务等。在那里,我有一个名为UserServices的类,它使用名为EmailServices的服务,如下所示:

public class UserServices : IUserServices
{        
    private readonly IEmailServices _emailServices = new EmailServices();

    public void CreateUser(...)
    {
        // Create user...

        _emailServices.SendWelcomeEmail(newUser);
    }
}

正如您所看到的,UserServices类对EmailServices具有硬编码依赖关系,但我希望将其配置为使用DI。也就是说,在我的ASP.NET MVC应用程序(或单元测试项目或任何地方)中,我希望能够说“绑定IEmailServices以使用TestEmailServices”并使用UserServicesTestEmailServices代替EmailServices

我该怎么做呢?我希望能够做到这样的事情:

public class UserServices : IUserServices
{        
    private readonly IEmailServices _emailServices = kernel.Get<EmailServices>();

    ...
}

但在这种情况下,我不确定kernel将来自哪里。我问的是有意义的,还是我在这里咆哮错误的树?

由于

2 个答案:

答案 0 :(得分:4)

您应该可以使用构造函数注入来执行此操作,如下所示:

private readonly IEmailServices _emailServices;

public UserServices(IEmailServices emailServices)
{
    _emailServices = emailServices;
}

Ninject自定义控制器工厂应自动处理对控制器的服务注入,该工厂将使用配置的IoC容器在创建控制器时解析IUserServices对象,然后再对其进行处理容器的IEmailServices对象:

public class MyController : Controller
{
    private readonly IUserServices _userServices;

    public MyController(IUserServices userServices)
    {
        _userServices = userServices;
    }
}

当您进行单元测试时,您可以手动将虚假或模拟电子邮件服务注入用户服务。

答案 1 :(得分:0)

如果您正在使用MVC 3,那么如何使用内置的DependencyResolver注册Ninject?

System.Web.Mvc.DependencyResolver.SetResolver(yourKernel);

然后,你可以使用

var svc = System.Web.Mvc.DependencyResolver.Current.GetService<bla>();

你需要它的地方。如果SetResolver直接接受Ninject内核或者你需要一个包装类,我不知道如何,但我认为这是最干净的解决方案。