避免构造函数映射字段 [英] Avoid constructor mapping fields

查看:18
本文介绍了避免构造函数映射字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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>();
    }
}

在前面的代码段中,User(name, email, roles) 被调用并带有角色列表.

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

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>();
    }

它按预期工作,但这迫使我在每个 Map 配置中都包含这个样板语句,而且模型还挺大的.

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).

我已经搜索了这个场景,但没有找到任何东西.将 ConstructUsing 添加到每个 Map 是否可行?有没有更好的选择?或者也许我正在做某事完全错误...

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 something completely 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:

  1. ConstructUsing 添加到您的每个 CreateMap.
  2. 修改/添加到您的 ConfigureServices 这一行:services.AddAutoMapper(cfg => cfg.DisableConstructorMapping());
  1. Add ConstructUsing to your every CreateMap<Src, Des>.
  2. 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.

这篇关于避免构造函数映射字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆