Referencing Ninject in class library in ASP.NET MVC 3 application

邮差的信 提交于 2019-12-01 20:20:31

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!