Я часто использую AutoMapper для отображения, Модель (Домен) возражает против объектов ViewModel, которые затем используются моими Представлениями в шаблоне Model/View/View-Model.
Это включает много операторов 'Mapper. CreateMap', которые все должны быть выполнены, но должны только быть выполнены однажды в жизненный цикл приложения.
Технически, затем, я должен сохранить их всех в статическом методе где-нибудь, который называют от моего Application_Start () методом (это - приложение MVC ASP.NET).
Однако кажется неправильным собрать в группу много различных проблем отображения в одной центральной части.
Особенно, когда отображение кода становится сложным и включает форматирование и другую логику.
Существует ли лучший способ организовать отображающийся код так, чтобы это было сохранено близко к ViewModel, которого он касается?
(Я придумал одну идею - наличие метода 'CreateMappings' на каждом ViewModel, и в BaseViewModel, назвав этот метод на инстанцировании. Однако, так как метод нужно только назвать однажды в жизненном цикле приложения, требуется некоторую дополнительную логику для кэширования списка типов ViewModel, для которых назвали метод CreateMappings, и затем только назовите его при необходимости для ViewModels, которые не находятся в том списке.)
Если вы используете профили, вы можете разместить там все свои вызовы CreateMap. Кроме того, вы можете создать статический класс загрузчика, который содержит вашу конфигурацию, а часть запуска просто вызовет загрузчик.
Хорошо, я сейчас это делаю так:
Я добавляю логику в конструктор моего BaseController, который запускает метод CreateMappings, но только один раз для каждого контроллера Тип:
public abstract class BaseController : Controller
{
public BaseController()
{
if (!controllersWithMappingsCreated.Contains(GetType()))
{
CreateMappings();
controllersWithMappingsCreated.Enqueue(GetType());
}
}
protected virtual void CreateMappings() { }
}
В каждом конкретном контроллере я использую CreateMappings для объявления сопоставлений для всех Models / ViewModels, относящихся к этому контроллеру.
public class AccountController : BaseController
{
public AccountController() : base() { }
protected override void CreateMappings()
{
Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
}
}
Я также нашел несколько интересных альтернатив с использованием атрибутов здесь и здесь , однако они кажутся мне немного сложными.