AutoMapper map IdPost для публикации - PullRequest
2 голосов
/ 29 марта 2010

Я пытаюсь отобразить int IdPost в DTO на объект Post на объекте Blog на основе правила.

Я бы хотел добиться этого: BlogDTO.IdPost => Blog.Post

Сообщение будет загружено NHibernate: Session.Load (IdPost)

Как мне добиться этого с помощью AutoMapper?

Ответы [ 3 ]

0 голосов
/ 20 апреля 2010
  1. Создать новый Id2EntityConverter

    public class Id2EntityConverter<TEntity> : ITypeConverter<int, TEntity> where TEntity : EntityBase
    {
        public Id2EntityConverter()
        {
            Repository = ObjectFactory.GetInstance<Repository<TEntity>>();
        }
    
        private IRepository<TEntity> Repository { get; set; }
    
        public TEntity ConvertToEntity(int id)
        {
            var toReturn = Repository.Get(id);
            return toReturn;
        }
    
        #region Implementation of ITypeConverter<int,TEntity>
    
        public TEntity Convert(ResolutionContext context)
        {
            return ConvertToEntity((int)context.SourceValue);
        }
    
        #endregion
    }
    
  2. Настройка AM для автоматического создания карт для каждого типа

    public class AutoMapperGlobalConfiguration : IGlobalConfiguration
    {
        private AutoMapper.IConfiguration _configuration;
    
        public AutoMapperGlobalConfiguration(IConfiguration configuration)
        {
            _configuration = configuration;
        }
    
        public void Configure()
        {
            //add all defined profiles
            var query = this.GetType().Assembly.GetExportedTypes()
                .Where(x => x.CanBeCastTo(typeof(AutoMapper.Profile)));
    
            _configuration.RecognizePostfixes("Id");
    
            foreach (Type type in query)
            {
                _configuration.AddProfile(ObjectFactory.GetInstance(type).As<Profile>());
            }
    
            //create maps for all Id2Entity converters
            MapAllEntities(_configuration);
    
           Mapper.AssertConfigurationIsValid();
        }
    
        private static void MapAllEntities(IProfileExpression configuration)
        {
            //get all types from the my assembly and create maps that
            //convert int -> instance of the type using Id2EntityConverter
            var openType = typeof(Id2EntityConverter<>);
            var idType = typeof(int);
            var persistentEntties = typeof(MYTYPE_FROM_MY_ASSEMBLY).Assembly.GetTypes()
               .Where(t => typeof(EntityBase).IsAssignableFrom(t))
               .Select(t => new
               {
                   EntityType = t,
                   ConverterType = openType.MakeGenericType(t)
               });
            foreach (var e in persistentEntties)
            {
                var map = configuration.CreateMap(idType, e.EntityType);
                map.ConvertUsing(e.ConverterType);
            }
        }
    }
    

Обратите внимание на метод MapAllEntities. Тот будет сканировать все типы и создавать карты на лету от целого до любого типа, который имеет EntityBase (который в нашем случае является любым постоянным типом) RecognizePostfix ("Id") в вашем случае может быть заменен RecognizePrefix ("Id")

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

Вы можете сделать это легко с помощью ValueInjecter

было бы что-то вроде этого:

//first you need to create a ValueInjection for your scenario
      public class IntToPost : LoopValueInjection<int, Post>
        {
            protected override Post SetValue(int sourcePropertyValue)
            {
                return Session.Load(sourcePropertyValue);
            }
        }

// and use it like this
post.InjectFrom(new IntToPost().SourcePrefix("Id"), postDto);

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

post.InjectFrom<IntToPost>(postDto);
0 голосов
/ 20 апреля 2010

Вы можете определить действие AfterMap для загрузки объектов, используя NHibernate, в вашем определении отображения. Я использую что-то вроде этого для одинаковой цели:

        mapperConfiguration.CreateMap<DealerDTO, Model.Entities.Dealer.Dealer>()
            .AfterMap((src, dst) =>
                {
                    if (src.DepartmentId > 0)
                        dst.Department = nhContext.CurrentSession.Load<CompanyDepartment>(src.DepartmentId);
                    if (src.RankId > 0)
                        dst.Rank = nhContext.CurrentSession.Load<DealerRank>(src.RankId);
                    if (src.RegionId > 0)
                        dst.Region = nhContext.CurrentSession.Load<Region>(src.RegionId);
                });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...