AutoMapper как избежать инициализации - PullRequest
4 голосов
/ 14 ноября 2011

Как мне не требовать такой код:

public static class BusinessLogicAutomapper
{
    public static bool _configured;

    public static void Configure()
    {
        if (_configured)
            return;

        Mapper.CreateMap<Post, PostModel>();
        _configured = true;
    }
}

в моей сборке BL и необходимость вызова Configure() из моего Global.asax в моем приложении MVC?

Я имею в виду, я ожидаю такой звонок:

    public PostModel GetPostById(long id)
    {
        EntityDataModelContext context = DataContext.GetDataContext();
        Post post = context.Posts.FirstOrDefault(p => p.PostId == id);

        PostModel mapped = Mapper.Map<Post, PostModel>(post);
        return mapped;
    }

до Mapper.Map<TIn,TOut> для создания картографа, если он не существует, вместо того, чтобы создавать его вручную (я даже не должен знать об этой внутренней работе). Как обойти декларативное создание картографов для AutoMapper?

Было бы желательным решение, естественное для AutoMapper, но расширение или некоторые архитектурные изменения во избежание такой инициализации также сработали бы.

Я использую MVC 3, .NET 4, а не IoC / DI (пока, по крайней мере)

Ответы [ 2 ]

2 голосов
/ 14 ноября 2011

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

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

public static class ReflectionHelper
{
      public static T CreateFrom<T,U>( U from )
          where T : class, new
          where U : class
      {
            var to = Activator.CreateInstance<T>();
            var toType = typeof(T);
            var fromType = typeof(U);

            foreach (var toProperty in toType.GetProperties())
            {
                var fromProperty = fromType.GetProperty( toProperty.Name );
                if (fromProperty != null)
                {
                   toProperty.SetValue( to, fromProperty.GetValue( from, null), null );
                }
            }

            return to;
      }

Используется как

    var model = ReflectionHelper.CreateFrom<ViewModel,Model>( entity );

    var entity = ReflectionHelper.CreateFrom<Model,ViewModel>( model );

Оригинал

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

public class BusinessLogicAutomapper
{
    static BusinessLogicAutomapper
    {
        Mapper.CreateMap<Post, PostModel>();
        Mapper.AssertConfigurationIsValid();
    }
}
1 голос
/ 14 ноября 2011

проверить профили Automapper.

У меня есть эта настройка в моем Global.asax - она ​​запускается один раз статически, так что все готово к работе во время выполнения.

У меня также есть 1 юнит-тест, который охватывает все карты, чтобы проверить их правильность.

Хороший пример этого - блог Айенде енота

https://github.com/ayende/RaccoonBlog

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