问题描述
我将AutoMapper 6.2.2与.NET Core 2.0及其默认的依赖项注入机制一起使用,以在模型和DTO之间进行映射。
我需要在AutoMapper配置中使用DI,因为我必须执行 AfterMap< Action>
需要一些注入的组件。
I am using AutoMapper 6.2.2 with .NET Core 2.0 and its default dependency injection mechanism to map between models and DTOs.I need DI in my AutoMapper configs because I have to perform an AfterMap<Action>
that needs some injected components.
问题是,对于某些模型,这些模型的构造函数的参数与某些源成员匹配,当我为AutoMapper启用DI(添加 services.AddAutoMapper()
)时,这些构造函数默认情况下会被调用并填充数据,然后破坏我的EF操作。
The thing is, for some models that have constructors which parameters match some source member, when I enable DI for AutoMapper (add services.AddAutoMapper()
), these constructors are by default called and fed with data, that then breaks my operations with EF.
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>();
}
}
在上一片段中,用户(名称,电子邮件,角色)
与角色列表一起调用。
In the previous snippet, User(name, email, roles)
gets called with the list of roles.
我的映射器配置如下(注意 DisableConstructorMapping()
选项)
My mapper configuration is the following (note the DisableConstructorMapping()
option)
protected override MapperConfiguration CreateConfiguration()
{
var config = new MapperConfiguration(cfg =>
{
cfg.DisableConstructorMapping();
// Add all profiles in current assembly
cfg.AddProfiles(Assemblies);
});
return config;
}
和我的 Startup
一切都已设置的地方:
And my Startup
where everything is set up:
var mapperProvider = new MapperProvider();
services.AddSingleton<IMapper>(mapperProvider.GetMapper());
services.AddAutoMapper(mapperProvider.Assemblies);
修改配置文件以配置要与 ConstructUsing一起使用的ctor
Modifying the profile to configure which ctor to use with ConstructUsing
public UserProfile()
{
CreateMap<UserDTO, User>()
.ForMember(entity => entity.Roles, opt => opt.Ignore())
.ConstructUsing(src => new User())
.AfterMap<SomeAction>();
}
它可以按预期运行,但是这迫使我在每个地图配置
,模型很大。
It works as expected, but this forces me to include this boilerplate statement in every Map configuration,and the model is quite big.
不进行依赖注入(最近需要这样做),它可以与第一个代码段顺利运行(不需要 ConstructUsing
)。
Without dependency injection (this need arosed recently), it worked smoothly with the first snippet (no need for ConstructUsing
).
我已经搜索了这种情况,但没有找到任何东西。向每个Map添加 ConstructUsing
的方式了吗?有没有更好的选择?或者也许我在做
完全错误的事情...
I've searched for this scenario but haven't found anything. Is adding ConstructUsing
to every Map the way to go? Is there any better option? Or maybe I'm doing somethingcompletely wrong...
推荐答案
一年后,我在AutoMapper中遇到了这个问题8.0.0。如果有人仍然遵循此方法,则有两种方法:
One year later and I encountered this with AutoMapper 8.0.0. If anyone is still following this, there're 2 ways:
- 添加
ConstructUsing
到您的每个CreateMap< Src,Des>
。 - 修改/添加到您的
ConfigureServices
这行:services.AddAutoMapper(cfg => cfg.DisableConstructorMapping());
- Add
ConstructUsing
to your everyCreateMap<Src, Des>
. - Modify/Add to your
ConfigureServices
this line:services.AddAutoMapper(cfg => cfg.DisableConstructorMapping());
但是您必须在每个需要的类映射中创建一个空白构造函数。
But you have to create a blank constructor in every class needed mapping.
这篇关于避免构造函数映射字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!