Интенсивность зависимостей .NET MVC от моделей?

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

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

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

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

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

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

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

Ответы

Ответ 1

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

Добавьте интерфейс и класс для обработки этого, который использует ваш контроллер - 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, этот класс будет использовать ваши поставщики членства и роли или другие интерфейсы, которые делают, упрощая вашу логику в этом классе.

Ответ 2

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

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

Архитектура службы, вероятно, является лучшим способом разработки приложения, но для простого вопроса о том, почему моя модель не вводится, это потому, что вам нужно создать ее через контейнер инъекции зависимостей, а не через новую().