Я обнаружил действительно странную проблему с 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 на два профиля, разделяя службу, но это отображение никогда не работает.