Automapper - CreateMap и ForMember не работают - PullRequest
0 голосов
/ 28 февраля 2020

Я обнаружил действительно странную проблему с Automapper в одном из моих отображений. Приложение написано в ASP. NET MVC 5 с Automapper 9.0.0 и Autofa c 5.0.0.

У меня есть несколько профилей, и в одном из них я использую два метода CreateMap , Один работает, а другой нет. Я потратил много времени на его отладку и просто не могу понять, почему этот не работает.

Код моего профиля:

    public class LocalizationProfile : Profile
    {
        public LocalizationProfile()
        {
            CreateMap<base_country, DictionaryItemDto>()
                .ForMember(x => x.Id, s => s.MapFrom(src => src.iso2))
                .ForMember(x => x.Name, s => s.MapFrom(src => src.name_en));

            CreateMap<base_state, DictionaryItemDto>()
                .ForMember(x => x.Id, s => s.MapFrom(src => src.Abbreviation));
        }
    }

Сервис, где профиль используется:

    public class LocalizationService : ILocalizationService
    {
        private readonly IMapper _mapper;

        public LocalizationService(IMapper mapper)
        {
            _mapper = mapper;
        }

        public IEnumerable<DictionaryItemDto> GetCountries()
        {
            return _mapper.Map<IEnumerable<DictionaryItemDto>>(base_country.Fetch("SELECT * FROM base_country")); ;
        }

        public IEnumerable<DictionaryItemDto> GetStateProvinces(string country)
        {
            var stateQuery = !string.IsNullOrWhiteSpace(country) && country != "Select Country" ?
                                            "SELECT * FROM base_state bs INNER JOIN base_country bc ON bs.CountryId = bc.Id WHERE bc.iso2 = @0" :
                                            "SELECT * FROM base_state WHERE CountryId = 0";

            var basestates = base_state.Fetch(stateQuery, country);
            var mapped = _mapper.Map<IEnumerable<DictionaryItemDto>>(basestates);

            return mapped;
        }
    }

DictionaryItemDto:

    public class DictionaryItemDto
    {
        public string Id { get; set; }
        public string Name { get; set; }

        public DictionaryItemDto() { }

        public DictionaryItemDto(string id, string name)
        {
            Id = id;
            Name = name;
        }
    }

base_country:

    [ExplicitColumns]
    [PrimaryKey("Id", autoIncrement = false)]
    [TableName("base_country")]
    public class base_country : ....Record<base_country>
    {
        public base_country();

        [Column]
        [FieldMetadata(IsNullable = false, MaxLength = 0)]
        public int Id { get; set; }
        [Column]
        [FieldMetadata(IsNullable = true, MaxLength = 2)]
        public string iso2 { get; set; }
        [Column]
        [FieldMetadata(IsNullable = true, MaxLength = 3)]
        public string iso3 { get; set; }
        [Column]
        [FieldMetadata(IsNullable = true, MaxLength = 64)]
        public string name_en { get; set; }

        public void Load(NameValueCollection state, IEnumerable<string> excludedPropertyNames = null, IEnumerable<string> includedPropertyNames = null);
        public void Load(NameValueCollection state);
    }

base_state:

    [ExplicitColumns]
    [PrimaryKey("Id")]
    [TableName("base_state")]
    public class base_state : ....Record<base_state>
    {
        public base_state();

        [Column]
        [FieldMetadata(IsNullable = false, MaxLength = 0)]
        public int Id { get; set; }
        [Column]
        [FieldMetadata(IsNullable = false, MaxLength = 40)]
        public string Name { get; set; }
        [Column]
        [FieldMetadata(IsNullable = false, MaxLength = 2)]
        public string Abbreviation { get; set; }
        [Column]
        [FieldMetadata(IsNullable = false, MaxLength = 0)]
        public int CountryId { get; set; }

        public void Load(NameValueCollection state, IEnumerable<string> excludedPropertyNames = null, IEnumerable<string> includedPropertyNames = null);
        public void Load(NameValueCollection state);
    }

Autofa c Конфигурация модуля :

    public class AutoMapperModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterAssemblyTypes(typeof(AutoMapperModule).Assembly).As<Profile>();
            builder.Register(context => new MapperConfiguration(cfg =>
            {
                foreach (var profile in context.Resolve<IEnumerable<Profile>>())
                {
                    cfg.AddProfile(profile);
                }
            })).AsSelf().SingleInstance();

            builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve))
                .As<IMapper>()
                .InstancePerLifetimeScope();
        }
    }

Конфигурация Autofa c, используемая Global.asax:

    public class AutofacConfig
    {
        public static void Register()
        {
            var builder = new ContainerBuilder();

            builder.RegisterControllers(typeof(MvcApplication).Assembly);
            builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsSelf().AsImplementedInterfaces().InstancePerRequest();
            builder.RegisterModule(new AutoMapperModule());

            // Set the dependency resolver to be Autofac.
            var container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }
    }

Проблема в том, что autopper просто не использует вторую карту (base_state) и это даже не определено в настройках картографов: Отладчик - автомат

Вы когда-нибудь сталкивались с такой проблемой или знаете, что здесь происходит? Я пытался разделить методы CreateMap на два профиля, разделяя службу, но это отображение никогда не работает.

...