如何在AutoMapper配置文件类中注入服务

时间:2017-07-03 03:28:29

标签: asp.net-core automapper

我需要在AutoMapper中的ASP.NET Core个人资料类中使用服务层,但是当我在构造函数中注入服务时,它不起作用。例如:

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

Startup班级:

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

怎么做?

3 个答案:

答案 0 :(得分:20)

要解决您的问题,您只需在DI中连接IUserManager,并确保已解决UserProfile依赖关系。

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

说到这里,我可能会尝试保持每个班级的单一责任,而不是将任何服务注入到映射配置文件中。您可以在映射之前填充对象。这样也可以更容易进行单元测试。

答案 1 :(得分:5)

为此目的最好使用自定义IValueResolver,因为它完全支持IServiceCollection集成(使用AutoMapper.Extensions.Microsoft.DependencyInjection)。

您可能需要实现自定义值解析器:

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

服务注册可以简化为:

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

然后,您可以通过构造函数注入IMapper来获取控制器内的映射器实例。

基于:AutoMapper: Handling Profile Dependencies using Custom Value Resolvers - Tech Net

答案 2 :(得分:1)

我知道这个问题不是最近的,但是有一个针对这个问题的nuget包:AutoMapperBuilder

您可以通过替换以下行来获得所需的内容:

services.AddAutoMapper(typeof(UserProfile));

带有这些:

services.AddAutoMapperBuilder(builder =>
{
     builder.Profiles.Add(new UserProfile(services.BuildServiceProvider().GetRequiredService<IUserManager>()));
});