Инъекция зависимостей .NET MVC в модели? - PullRequest
16 голосов
/ 24 июня 2011

Вопрос: Есть ли способ использовать Ninject для внедрения зависимостей в мои модели MVC?

Прежде всего, я новичок в MVC и DI (и stackoverflow, кстати), поэтому я хотел убедиться, что я иду по правильному пути с этой проблемой. Я гуглил ответ в течение нескольких дней, но не могу найти четкого объяснения ... Я использую C #, .NET4, MVC3, Ninject и VS2010.

Вот сценарий: у меня есть новая форма пользователя, где пользователь может установить свои логин, роли и другие данные профиля. Когда это будет отправлено, мне нужно сохранить информацию для входа в систему MembershipProvider, роли в RoleProvider и т. Д. Это становится немного сложным, потому что я использую двойных провайдеров (Active Directory / локальная база данных) в соответствии с требованиями моего проекта, так что есть некоторая логика в определении, к какому провайдеру сохранять, если пользователь уже существует, если ему разрешено самостоятельно идентифицировать любые роли и так далее.

Я чувствую, что эта логика должна быть в методе .Save () на моей модели. Однако затем мне нужно внедрить экземпляры моих провайдеров в мою модель, и Ninject, похоже, не внедряет модели (по крайней мере, не используя настройки по умолчанию, которые входят в комплект NuGet). Отсюда мой начальный вопрос.

Я могу придумать несколько альтернатив ...

  1. Может быть, модель - плохое место для этой логики, и я должен абстрагировать логику в сервис? Но создание сервиса только для этой функции сохранения кажется мне излишним.
  2. Я мог бы просто съесть наворот в моем контроллере ... но мне сказали, что "толстые" контроллеры - плохая практика.
  3. Полагаю, я мог бы вместо этого внедрить своих провайдеров в мой контроллер, а затем передать эти зависимости в мою модель, но это кажется немного странным.

Итак ... Есть ли способ Ninject модели или мне нужно пересмотреть, потому что я новичок в этом?

Ответы [ 2 ]

11 голосов
/ 24 июня 2011

Я бы выбрал первый вариант.Это не излишне - добавление класса и интерфейса - это всего лишь несколько строк кода, и это сохраняет вашу реализацию аккуратной, и, возможно, позже вы захотите добавить больше методов ... обновить пользователя?

Добавить интерфейси класс для обработки того, что использует ваш контроллер - ninject получит этот экземпляр для вас.Я написал IMembershipAndRoleService в качестве примера.

public interface IMembershipAndRoleService
{
    void ProcessNewUser(User newUser);
}

public class YourController : Controller
{
    private readonly IMembershipAndRoleService _membershipAndRoleService;

    public YourController(IMembershipAndRoleService membershipAndRoleService)
    {
        _membershipAndRoleService = membershipAndRoleService;
    }

    [HttpPost]
    public ActionResult NewUserFormAction(NewUserForm newUserForm)
    {
        //process posted form, possibly map / convert it to User then call to save
        _membershipAndRoleService.ProcessNewUser(user);
        //redirect or return view
    }
}

Наконец, сделайте класс, который реализует IMembershipAndRoleService, этот класс будет использовать ваши поставщики Membership и Role ИЛИ другие интерфейсы, которые делают вашу логику в этом классе упрощенной.

5 голосов
/ 24 июня 2011

Если вы используете пакет Ninject.MVC из NuGet, он подключится к MVC DependencyResolver, так что вы можете сделать это, чтобы получить экземпляр модели, внедренный Ninject.

var model = System.Web.Mvc.DependencyResolver.Current.GetService<MyModel>();

Службаархитектура, вероятно, является лучшим способом разработки приложения, но простой вопрос «почему моя модель не внедряется» - это потому, что вам нужно создать ее с помощью контейнера внедрения зависимостей, а не с помощью new ().

...