Куда должны идти операторы CreateMap? - PullRequest
11 голосов
/ 23 мая 2010

Я часто использую AutoMapper для сопоставления объектов Model (Domain) с объектами ViewModel, которые затем используются моими представлениями, в шаблоне Model / View / View-Model.

Это включает в себя множество операторов Mapper.CreateMap, которые должны выполняться все, но должны выполняться только один раз в жизненном цикле приложения.

Технически, тогда я должен хранить их где-нибудь в статическом методе, который вызывается из моего метода Application_Start () (это приложение ASP.NET MVC).

Тем не менее, кажется неправильным объединять множество разных картографических задач в одном центральном месте.

Особенно, когда отображение кода становится сложным и требует форматирования и другой логики.

Есть ли лучший способ организовать код отображения так, чтобы он был близок к ViewModel, к которому он относится?

(Мне пришла в голову одна идея - иметь метод CreateMappings на каждой ViewModel и в BaseViewModel, вызывая этот метод при создании экземпляра. Однако, поскольку метод должен вызываться только один раз Жизненный цикл приложения требует дополнительной логики для кэширования списка типов ViewModel, для которых был вызван метод CreateMappings, а затем вызывать его только при необходимости для ViewModel, которых нет в этом списке.)

Ответы [ 3 ]

7 голосов
/ 15 марта 2011

Если вы действительно не хотите использовать загрузчик, тогда, по крайней мере, статический конструктор - это простой способ убедиться, что ваш CreateMap вызывается не более одного раза. (С меньшим количеством возни и большим количеством доказательства потока чем ответ Джонатона.)

public class AccountController : Controller 
{
    static AccountController()
    {
        Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
        Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
    }
}
3 голосов
/ 24 мая 2010

Если вы используете профили, вы можете разместить там все ваши звонки «CreateMap». Кроме того, вы можете создать статический класс начального загрузчика, который содержит вашу конфигурацию, и заставить начальную часть просто вызвать загрузчик.

0 голосов
/ 24 мая 2010

ОК, то, как я сейчас это делаю, таково:

Я добавляю некоторую логику в конструктор моего BaseController, который запускает метод «CreateMappings», но только один раз для каждого типа контроллера:

public abstract class BaseController : Controller
{    
    public BaseController()
    {
        if (!controllersWithMappingsCreated.Contains(GetType()))
        {
            CreateMappings();
            controllersWithMappingsCreated.Enqueue(GetType());
        }
    }

    protected virtual void CreateMappings() { }
}

В каждом конкретном контроллере я использую CreateMappings для объявления отображений для всех Моделей / ViewModels, относящихся к этому контроллеру.

public class AccountController : BaseController
{
    public AccountController() : base() { }

    protected override void CreateMappings()
    { 
        Mapper.CreateMap<Models.User, ViewModels.UserProfile>();
        Mapper.CreateMap<Models.User, ViewModels.ChangePassword>();
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...