Ссылка на Ninject в библиотеке классов в приложении ASP.NET MVC 3 - PullRequest
4 голосов
/ 28 октября 2011

У меня есть приложение ASP.NET MVC 3, которое использует расширение Ninject.MVC3 для настройки DI в моем приложении MVC. А именно, есть файл NinjectMVC3.cs в папке App_Start, где определены мои привязки. Это хорошо работает для DI в контроллерах моего приложения.

В дополнение к веб-приложению ASP.NET MVC мое решение также содержит проекты библиотеки классов, назовем ее 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 (или в проекте модульного тестирования, или где бы то ни было) я хочу иметь возможность сказать «Bind IEmailServices для использования TestEmailServices» и иметь класс UserServices, использующий TestEmailServices вместо EmailServices.

Как мне это сделать? Я хотел бы иметь возможность сделать что-то вроде:

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

    ...
}

Но я не уверен, откуда взяться kernel, в этом случае. Имеет ли смысл то, что я спрашиваю, или я лаю не на том дереве?

Спасибо

Ответы [ 2 ]

4 голосов
/ 28 октября 2011

Вы должны быть в состоянии сделать это с помощью инжектора конструктора, например:

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;
    }
}

Когда вы тестируете модуль, вы можете вручную ввестифальшивый или поддельный почтовый сервис в пользовательский сервис.

0 голосов
/ 28 октября 2011

Если вы все равно используете MVC 3, как насчет регистрации Ninject с помощью встроенного DependencyResolver?

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

Тогда вы можете просто использовать

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

там, где вам это нужно,Я не знаю, принимает ли SetResolver напрямую ядро ​​Ninject или если вам нужен класс-оболочка, но я считаю, что это самое чистое решение.

...