我将 AutoMapper 6.2.2 与 .NET Core 2.0 及其默认依赖注入(inject)机制结合使用,以在模型和 DTO 之间进行映射。
我的 AutoMapper 配置中需要 DI,因为我必须执行 AfterMap<Action>
这需要一些注入(inject)的组件。
问题是,对于某些具有参数匹配某些源成员的构造函数的模型,当我为 AutoMapper 启用 DI(添加 services.AddAutoMapper()
)时,这些构造函数默认被调用并提供数据,然后中断我的操作英孚。
public class UserDTO
{
public string Name { get; set; }
public string Email { get; set; }
public ICollection<RoleDTO> Roles { get; set; }
}
public class User
{
public string Name { get; set; }
public string Email { get; set; }
public ICollection<RoleInUser> RoleInUsers { get; } = new List<RoleInUser>();
public ICollection<Role> Roles { get; }
public User()
{
Roles = new JoinCollectionFacade<Role, User, RoleInUser>(this, RoleInUsers);
}
public User(string name, string email, ICollection<Role> roles) : this()
{
Roles.AddRange(roles);
}
}
public class UserProfile : Profile
{
public UserProfile()
{
CreateMap<UserDTO, User>()
.ForMember(entity => entity.Roles, opt => opt.Ignore())
.AfterMap<SomeAction>();
}
}
在前面的片段中,User(name, email, roles)
使用角色列表调用。
我的映射器配置如下(注意 DisableConstructorMapping()
选项)
protected override MapperConfiguration CreateConfiguration()
{
var config = new MapperConfiguration(cfg =>
{
cfg.DisableConstructorMapping();
// Add all profiles in current assembly
cfg.AddProfiles(Assemblies);
});
return config;
}
还有我的Startup
一切都设置好了:
var mapperProvider = new MapperProvider();
services.AddSingleton<IMapper>(mapperProvider.GetMapper());
services.AddAutoMapper(mapperProvider.Assemblies);
修改配置文件以配置与 ConstructUsing
一起使用的 ctor
public UserProfile()
{
CreateMap<UserDTO, User>()
.ForMember(entity => entity.Roles, opt => opt.Ignore())
.ConstructUsing(src => new User())
.AfterMap<SomeAction>();
}
它按预期工作,但这迫使我在每个 Map 配置中包含这个样板语句, 而且模型很大。
没有依赖注入(inject)(最近出现了这个需求),它与第一个代码片段一起工作顺利(不需要 ConstructUsing
)。
我已经搜索过这个场景,但没有找到任何东西。正在添加 ConstructUsing
到每张 map 要走的路?有没有更好的选择?或者也许我正在做某事
完全错误...
最佳答案
一年后,我在使用 AutoMapper 8.0.0 时遇到了这个问题。如果有人还在关注这个,有两种方法:
- 添加
ConstructUsing
给你的每一个CreateMap<Src, Des>
. - 修改/添加到您的
ConfigureServices
这一行:services.AddAutoMapper(cfg => cfg.DisableConstructorMapping());
但是您必须在每个需要映射的类中创建一个空白构造函数。
关于c# - 避免构造函数映射字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48790180/