问题
I have an ASP.NET MVC 3 application that uses the Ninject.MVC3 extension to setup DI in my MVC application. Namely, there's the NinjectMVC3.cs
file in the App_Start
folder where my bindings are defined. This works well for DI into my application's controllers.
In addition to the ASP.NET MVC web application, my Solution also contains a class library projects, let's call it MyProject.Core
, which has my domain model, services, and so on. In there I have a class called UserServices
that uses a service called EmailServices
, like so:
public class UserServices : IUserServices
{
private readonly IEmailServices _emailServices = new EmailServices();
public void CreateUser(...)
{
// Create user...
_emailServices.SendWelcomeEmail(newUser);
}
}
As you can see, the UserServices
class has a hard-coded dependency on EmailServices
, but I'd like for that to be configured to use DI, as well. Namely, in my ASP.NET MVC application (or unit test project or wherever) I want to be able to say, "Bind IEmailServices
to use TestEmailServices
" and have the UserServices
class use TestEmailServices
instead of EmailServices
.
How do I go about doing this? I'd like to be able to do something like:
public class UserServices : IUserServices
{
private readonly IEmailServices _emailServices = kernel.Get<EmailServices>();
...
}
But I'm not sure where kernel
is going to come from, in this case. Is what I'm asking making any sense, or am I barking up the wrong tree here?
Thanks
回答1:
You should be able to do this with constructor injection, like this:
private readonly IEmailServices _emailServices;
public UserServices(IEmailServices emailServices)
{
_emailServices = emailServices;
}
The service injection into your controllers should be handled automatically by the Ninject custom controller factory, which'll use the configured IoC container to resolve the IUserServices
object when the controller is created, which will in turn be given an IEmailServices
object by the container:
public class MyController : Controller
{
private readonly IUserServices _userServices;
public MyController(IUserServices userServices)
{
_userServices = userServices;
}
}
When you're unit testing, you can manually inject a fake or mock email service into the user service.
回答2:
If you are using MVC 3 anyway, how about registering Ninject with the built-in DependencyResolver?
System.Web.Mvc.DependencyResolver.SetResolver(yourKernel);
Then, you can just use
var svc = System.Web.Mvc.DependencyResolver.Current.GetService<bla>();
where you need it. I don't know off hand if SetResolver accepts the Ninject Kernel directly or if you need a wrapper class, but I'd consider that the cleanest solution.
来源:https://stackoverflow.com/questions/7924043/referencing-ninject-in-class-library-in-asp-net-mvc-3-application