2017-02-11 21 views
1

Здравствуйте, я пытаюсь реализовать шаблон «ViewModelFactory», и мне было интересно, что это лучший способ его достижения, учитывая ограничения текущего контейнера IoC.ASP.NET Core и ViewModelFactory

public class UserCreateViewModelFactory 
{ 
    private readonly DbContext db; 

    public UserCreateViewModelFactory(DbContext db){ this.db = db;} 

    public void Create(CreateUserViewModel viewModel) 
    { 
      //Creates the user 
    } 
} 

У меня есть класс, который легко вводится в мои контроллеры ctor. Головная боль придет время, когда мне нужно больше ViewModelBuilders, поэтому я хочу, чтобы избежать двух вещей:

  1. Bloat CTOR с инъекциями
  2. Вздутие контейнер с регистрацией

Я хочу, чтобы иметь возможность вводить IViewModelFactory на мой контроллер и затем использовать его как это:

[HttpGet] 
public IActionResult GetUsers(int id) 
{ 
    return View(viewModelFactory.Build<GetUserViewModel>(id)); 
} 

Обратите внимание, что при вызове Build(T) он должен назвать правильный IViewModelFactory осуществления.

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

+0

Можете ли вы объяснить, почему вы хотите отвлечь создание моделей вида? Модель просмотра - это DTO; это то, что контроллер обычно должен обновлять сам. Обычно нет причин абстрагироваться от создания DTO. – Steven

+0

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

+0

Ваше приложение может извлечь выгоду из таких проектов, как [этот] (https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92). – Steven

ответ

0

После некоторого исследования I наконец, придумал хорошее решение этой проблемы.

Решение в основном расширяет возможности IoC по умолчанию посредством метода расширения IServiceCollection.ConnectImplementations().

Во время регистрации я буду искать свои конкретные классы и подключать их с соответствующими интерфейсами (например, другими контейнерами). Затем я использую посредник/прокси, в который вводится IServiceCollection, и знает, какой конкретный класс должен строить модель представления.

Полное решение лучше объяснено this gist Я создал.

1

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

Если ваш контроллер создает множество режимов просмотра, и вы получаете множество строителей, которые вам нужно вводить - это можно рассматривать как признак нарушения принципа единой ответственности. В этом случае вам нужно отделить логику контроллера от разных контроллеров.

Так что я хочу, чтобы избежать два вещей:

Вздутия т е р с инъекциями

  • Отдельный класс с раздутым конструктором других классов с более конкретной ответственностью, которая занимает меньшее количество зависимостей.
  • или оберните зависимости с одним или двумя, тремя классами на основе их отношения

Вздутие контейнера с регистрацией

  • Это не может быть проблемой, так как контейнеры зависимостей, как правило, предназначены для зарегистрировать весь «график объекта» вашей заявки
+0

Это тоже вопрос организации, так как контроллеры могут использовать другие зависимости. И это не обязательно пение нарушения SRP, это зависит от потребностей домена. Хорошим примером является использование CQRS + Mediator. Этот ответ не очень полезен, поскольку он не учитывает ограничения проблем (как указано). –

+0

Контроллер - это просто класс - если у класса слишком много зависимостей, что является главной заботой вашего вопроса, то это нарушает принцип единой ответственности. У класса должна быть только одна причина для изменения, поэтому, если у вашего контроллера есть другая логика создания разных режимов просмотра - тогда, если какая-то логика должна измениться, вам нужно изменить код контроллера. – Fabio

+0

Это просто неправда. Количество параметров не является нарушением SRP. Хотя это может указывать на запах кода и, возможно, на нарушение SRP, потому что код «может» делать больше, чем он должен делать. Возьмите, например, ProductController, он должен отвечать за маршрутизацию/возврат просмотров к объекту Product. Возможно, у меня есть бизнес-требование, которое позволяет мне редактировать/отображать Продукт по-разному. В этом случае моя «одна причина для изменения» заключается в предоставлении функциональности, относящейся к моему домену, который должен находиться в этом контроллере. –

 Смежные вопросы

  • Нет связанных вопросов^_^