避免构造函数映射字段

key*_*cad 6 c# automapper .net-core

我正在使用带有.NET Core 2.0的AutoMapper 6.2.2及其默认的依赖注入机制来映射模型和DTO.我需要在我的AutoMapper配置中使用DI,因为我必须执行AfterMap<Action>需要一些注入的组件.

问题是,对于某些具有参数匹配某些源成员的构造函数的模型,当我为AutoMapper(add services.AddAutoMapper())启用DI时,这些构造函数默认调用并提供数据,然后使用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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

在上一个代码段中,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;
    }
Run Code Online (Sandbox Code Playgroud)

我的Startup所有设置都在哪里:

        var mapperProvider = new MapperProvider();
        services.AddSingleton<IMapper>(mapperProvider.GetMapper());
        services.AddAutoMapper(mapperProvider.Assemblies);
Run Code Online (Sandbox Code Playgroud)

修改配置文件以配置要使用的ctor ConstructUsing

    public UserProfile()
    {
        CreateMap<UserDTO, User>()
            .ForMember(entity => entity.Roles, opt => opt.Ignore())
            .ConstructUsing(src => new User())
            .AfterMap<SomeAction>();
    }
Run Code Online (Sandbox Code Playgroud)

它按预期工作,但这迫使我在每个Map配置中包含这个样板语句,并且模型非常大.

没有依赖注入(这需要最近出现),它与第一个片段(不需要ConstructUsing)一起顺利进行.

我搜索过这个场景,但没有找到任何东西.添加ConstructUsing到每个地图的方式去?还有更好的选择吗?或许我做的事情完全错了......

Củ *_*Hào 1

一年后,我在 AutoMapper 8.0.0 中遇到了这个问题。如果有人仍在关注此问题,有两种方法:

  1. 添加ConstructUsing到您的每一个CreateMap<Src, Des>.
  2. 修改/添加到您的ConfigureServices这一行:services.AddAutoMapper(cfg => cfg.DisableConstructorMapping());

但是您必须在每个需要映射的类中创建一个空白构造函数。