How inject service in AutoMapper profile class

早过忘川 提交于 2019-12-18 14:46:08

问题


I need to use a service layer in the AutoMapper profile class in ASP.NET Core but when I inject service in the constructor it does not work. For example:

public class UserProfile : Profile
{
    private readonly IUserManager _userManager;

    public UserProfile(IUserManager userManager)
    {
        _userManager = userManager;

        CreateMap<User, UserViewModel>()
           .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}"));
    }
}

And in Startup Class:

 public class Startup
{
    public IConfigurationRoot Configuration { set; get; }

    public Startup(IHostingEnvironment env)
    {
       //some code
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
        services.AddMvc();
        services.AddScoped<IUsersPhotoService, UsersPhotoService>();
        services.AddAutoMapper(typeof(UserProfile));
    }
}

How do to do it?


回答1:


To solve your problem you just need to wire IUserManager in DI, and make sure UserProfile dependency is resolved.

public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddSingleton<IUserManager, UserManager>();
    services.AddSingleton(provider => new MapperConfiguration(cfg =>
    {
        cfg.AddProfile(new UserProfile(provider.GetService<IUserManager>()));
    }).CreateMapper());
}

And having that said, I would probably try to keep single responsibility per class, and not have any services injected into mapping profiles. You can populate your objects just before the mapping instead. This way it might be easier to unit test as well.




回答2:


It's better to use custom IValueResolver for this purposes because it is fully supports IServiceCollection integration (using AutoMapper.Extensions.Microsoft.DependencyInjection).

You may need to implement a custom value resolver:

public class UserViewModelValueResolver: IValueResolver<...>
{
    public readonly IUserManager userManager;
    public UserViewModelValueResolver(IUserManager userManager)
    {
        this.userManager = userManager;
    }
    ...
}

And the registration in services may be reduced to:

public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddSingleton<IUserManager, UserManager>();
}

Then you can get a mapper instance inside a controller by injecting IMapper via a constructor.

Based on: AutoMapper: Handling Profile Dependencies using Custom Value Resolvers - Tech Net



来源:https://stackoverflow.com/questions/44877379/how-inject-service-in-automapper-profile-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!