Avoid Constructor Display Fields

I use AutoMapper 6.2.2 with .NET Core 2.0 and its default dependency injection mechanism for mapping between models and DTO. I need DI in my AutoMapper configurations because I need to execute AfterMap<Action>, which needs some nested components.

The fact is that for some models that have constructors whose parameters correspond to some source element, when I turn on DI for AutoMapper (add services.AddAutoMapper()), these constructors call and supply data by default, which then interrupts my operations using 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>();
    }
}

The previous snippet User(name, email, roles)is called with a list of roles.

My mapping configuration is as follows (note the parameter 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);

, , ctor ConstructUsing

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

, , , .

( ), ( ConstructUsing).

, . ConstructUsing ? ? , , - ...

+4

Source: https://habr.com/ru/post/1693640/


All Articles