我第一次使用自动映射。
我正在研究c#应用程序,我想使用自动映射器。
(我只是想知道如何使用它,所以我没有asp.net应用程序既没有MVC应用程序。)
我有三个类库项目。
我想在服务项目中编写转移过程。
所以我想知道如何以及在哪里配置自动映射器?
答案 0 :(得分:24)
您可以将配置放在任何位置:
public class AutoMapperConfiguration
{
public static void Configure()
{
Mapper.Initialize(x =>
{
x.AddProfile<MyMappings>();
});
}
}
public class MyMappings : Profile
{
public override string ProfileName
{
get { return "MyMappings"; }
}
protected override void Configure()
{
......
}
但必须由应用程序在某些时候使用库来调用它:
void Application_Start()
{
AutoMapperConfiguration.Configure();
}
答案 1 :(得分:19)
所以基于Bruno的答案和John Skeet's post about singletons我提出了以下解决方案,只运行一次并在类库中完全隔离,这与接受的答案不同,后者依赖于库的使用者来配置父项目中的映射:
public static class Mapping
{
private static readonly Lazy<IMapper> Lazy = new Lazy<IMapper>(() =>
{
var config = new MapperConfiguration(cfg => {
// This line ensures that internal properties are also mapped over.
cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;
cfg.AddProfile<MappingProfile>();
});
var mapper = config.CreateMapper();
return mapper;
});
public static IMapper Mapper => Lazy.Value;
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Source, Destination>();
// Additional mappings here...
}
}
然后在您需要将一个对象映射到另一个对象的代码中,您可以这样做:
var destination = Mapping.Mapper.Map<Destination>(yourSourceInstance);
注意:此代码基于AutoMapper 6.2,可能需要对旧版AutoMapper进行一些调整。
答案 2 :(得分:4)
我建议您使用instance based approach using an IMapper
。这样,你的库外没有人必须调用任何配置方法。您可以定义MapperConfiguration
并从类库中创建映射器。
var config = new MapperConfiguration(cfg => {
cfg.AddProfile<AppProfile>();
cfg.CreateMap<Source, Dest>();
});
IMapper mapper = config.CreateMapper();
// or
IMapper mapper = new Mapper(config);
var dest = mapper.Map<Source, Dest>(new Source());
答案 3 :(得分:0)
我使用了 Patel Vishal 的解决方案并根据我的需要对其进行了定制。 它是一个通用类,可确保每个对象映射仅在内存中保存一个映射实例。
public static class ObjectMapper<TModel, TData>
where TModel : class, DTO.IBaseModel, new()
where TData : class, IBaseModel, new()
{
private static readonly MapperConfiguration _mapperConfiguration;
public static IMapper Mapper => new Mapper(_mapperConfiguration);
static ObjectMapper()
{
_mapperConfiguration ??= CreateMap();
}
private static MapperConfiguration CreateMap()
{
return new (cfg =>
{
cfg.CreateMap<TData, TModel>();
});
}
}
我在 BaseService
public virtual TModel Convert(TData t)
{
return ObjectMapper<TModel, TData>.Mapper.Map<TModel>(t);
}
如你所见,它是一个虚方法。如果继承服务需要定制,可以覆盖映射。
答案 4 :(得分:0)
我也遇到过这种要求。我在 .Net 6.0 中所做的是,我创建了一个库项目并创建了配置文件类:
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<Entity, Dto>();
CreateMap<Dto, Entity>();
......
}
}
在 api 或 web 项目中,我只是创建了一个子类来继承上面的配置文件,并在 startup.cs services.AddAutoMapper(typeof(Startup)); 中注册它。