我有一个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
”并使用UserServices
类TestEmailServices
代替EmailServices
。
我该怎么做呢?我希望能够做到这样的事情:
public class UserServices : IUserServices
{
private readonly IEmailServices _emailServices = kernel.Get<EmailServices>();
...
}
但在这种情况下,我不确定kernel
将来自哪里。我问的是有意义的,还是我在这里咆哮错误的树?
由于
答案 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内核或者你需要一个包装类,我不知道如何,但我认为这是最干净的解决方案。