我发现了AutoMapper的一些非常奇怪的行为。这个简单的代码
internal class Program
{
private static void Main(string[] args)
{
Mapper.Initialize(cfg => { cfg.CreateMap<MyClass1, MyClass2>(); });
Mapper.Initialize(cfg => { cfg.CreateMap<MyClass3, MyClass4>(); });
var dto = new MyClass1();
Mapper.Map<MyClass1, MyClass2>(dto);
}
}
public class MyClass1
{
}
public class MyClass2
{
}
public class MyClass3
{
}
public class MyClass4
{
}生成异常:
缺少类型映射配置或不支持映射。 映射类型: MyClass1 -> MyClass2 ConsoleApplication2.MyClass 1 -> ConsoleApplication2.MyClass 2
但是,如果更改两个初始化行的顺序,如下所示
Mapper.Initialize(cfg => { cfg.CreateMap<MyClass3, MyClass4>(); });
Mapper.Initialize(cfg => { cfg.CreateMap<MyClass1, MyClass2>(); });百事大吉。怎么了?到底怎么回事?
发布于 2016-08-16 08:27:15
长话短说,吉米暂时放弃了AutoMapper中的静态内容,转而支持基于实例的映射。然而,正如Jimmy评论的那样:
静态映射器没有被删除,只是在代码中的任何地方调用CreateMap的能力。
问题的答案是,你试图初始化两次,而不是一次。
要回答关于如何将不同配置分散在代码中的下一个问题,可以使用Profile
若要回答如何配置所有这些内容,请参见以下内容:
对于AutoMapper 5.1.1
有一个MapperConfigurationExpression
您可以传递给映射程序,或者Mapper接受一个Action<IMapperConfigurationExpression>。
IMapperConfigurationExpression公开了以下内容:
void AddProfile(Profile profile)因此,您几乎可以这样做,但在IMapper接口上注册所有内容,这似乎是4.2.1的目标。
对于AutoMapper 4.2.1 (简要介绍概要文件)
下面是一个示例配置文件:
using AutoMapper;
using TreasuryRecords.Database.Models;
using TreasuryRecords.Requests.Account.Models;
public class AccountMappings : Profile
{
protected override void Configure()
{
this.CreateMap<RegisterDto, Client>()
.ForMember(x => x.UserName, c => c.MapFrom(x => x.Email));
}
}下面是我如何注册我的个人资料的一个例子:
using System;
using System.Linq;
using System.Reflection;
using AutoMapper;
using TreasuryRecords.Requests.Authenticate.Login;
public static class AutoMapperConfig
{
public static void Configure()
{
Assembly
.GetExecutingAssembly()
.RegisterConfigurations();
typeof(LoginRequest)
.Assembly
.RegisterConfigurations();
}
public static void RegisterConfigurations(this Assembly assembly)
{
var types = assembly.GetTypes();
var automapperProfiles = types
.Where(x => typeof(Profile).IsAssignableFrom(x))
.Select(Activator.CreateInstance)
.OfType<Profile>()
.ToList();
// so here you can pass in the instance of mapper
// I just use the static for ease
automapperProfiles.ForEach(Mapper.Configuration.AddProfile);
}
}我是这样将它添加到DI中的:
public static void RegisterAutoMapper(this IUnityContainer container)
{
container.RegisterType<IMapper>(new InjectionFactory(_ => Mapper.Instance));
}我在这里使用的是统一,但是非常简单,只需在接口Mapper.Instance中注册IMapper即可。
然后注入IMapper并按如下方式使用:
this.mapper.Map<Client>(message.RegistrationDetails);https://stackoverflow.com/questions/38969845
复制相似问题