Получить экземпляр объектов на основе других значений без использования местоположения службы - PullRequest
2 голосов
/ 31 августа 2011

Я использую шаблон единицы работы в своем приложении mvc 3 с Ninject. Я столкнулся с проблемой, когда у меня возникли проблемы с ее решением без использования нового или какого-либо другого местоположения службы.

Я использую абстрактную базовую модель под названием MyModel, которая имеет 2 конкретных подкласса MyModel1 и MyModel2. Их необходимо отправить в представление на основе значения, заданного в записи пользователя.

public class MyController : Controller
{
    private IUnitOfWork _unitOfWork;
    public MyController(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; }

    ...

    public ActionResult MyMethod() {
        var user = _unitOfWork.Get(user)

        if (user.myprop == somevalue)
        {
            return View(new MyModel1());
        }

        return View(new MyModel2());
    }

Это работает нормально (хотя мне это не нравится, это просто и работает. Проблема в том, что использование new является анти-паттерном при использовании Dependancy Injection. Кроме того, теперь я хочу, чтобы модели инициализировались самостоятельно (из базы данных ) поэтому мне нужно вставить IUnitOfWork в конструктор моделей. Конечно, я мог бы сделать это:

if (user.myprop == somevalue)
{
    return View(DependancyResolver.Current.GetService(typeof(MyModel1)));
}

Но расположение службы также является анти-паттерном.

Есть предложения, как это решить?

Ответы [ 2 ]

3 голосов
/ 01 сентября 2011

Использование new не является анти-паттерном для DI, если используется правильно.Нет абсолютно никаких проблем с использованием new для создания контейнеров данных, таких как модели представлений.

Но приложения MVC запрещают иметь логику или код для извлечения данных в ваших моделях представлений, поэтому им нужны зависимости.Все эти вещи принадлежат снаружи в контроллер или некоторые службы.Данные присваиваются предварительно отформатированным для модели вида снаружи.

2 голосов
/ 31 августа 2011

Кроме того, теперь я хочу, чтобы модели сами инициализировались (из базы данных), поэтому мне нужно ввести IUnitOfWork в конструктор модели

Нет. Вы не должны передавать какие-либо модели на ваш взгляд. Вы проходите только просмотр моделей. Вид моделей тупой. Они содержат только предварительно отформатированные данные для отображения. Например, если вы использовали AutoMapper , вы могли бы перенести это в слой отображения, и ваш контроллер мог бы стать:

public ActionResult MyMethod() {
    var user = _unitOfWork.Get(user)
    var userViewModel = Mapper.Map<User, UserViewModel>(user);
    return View(userViewModel);
}
...