问题的根本原因是
扩展方法。此方法扫描程序集以查找配置文件(和其他自动应用程序组件)并注册
图像
使用找到的配置的DI容器中的组件。(我建议你看看
its sources
你得到例外是因为
添加自动应用程序
用户映射配置文件
类,但不知道如何实例化它,因为它有4个开放类型参数。
public abstract class UserMappingProfile<TUserDto, TUserDtoKey, TUser, TUserKey> : Profile
where TUserDto : UserDto<TUserDtoKey>
where TUser : User<TUserKey>
{
public UserMappingProfile()
{
CreateMap<TUserDto, TUser>(MemberList.Destination)
.ForMember(x => x.Id, opts => opts.MapFrom(x => x.UserId));
CreateMap<TUser, TUserDto>(MemberList.Source)
.ForMember(x => x.UserId, opts => opts.MapFrom(x => x.Id));
}
}
public class UserMappingProfile : UserMappingProfile<MyUserDto, int, MyUser, int> { }
现在你不需要
MyService扩展
services.AddAutoMapper()
呼叫后,您的配置将自动获取。
添加自动应用程序
因为它只被调用一次。而不是扫描程序集
类,您可以提供自己的注册逻辑。使用生成器模式的示例:
public class UserMappingProfile<TUserDto, TUserDtoKey, TUser, TUserKey> : Profile
where TUserDto : UserDto<TUserDtoKey>
where TUser : User<TUserKey>
{
public UserMappingProfile()
{
CreateMap<TUserDto, TUser>(MemberList.Destination)
.ForMember(x => x.Id, opts => opts.MapFrom(x => x.UserId));
CreateMap<TUser, TUserDto>(MemberList.Source)
.ForMember(x => x.UserId, opts => opts.MapFrom(x => x.Id));
}
}
public interface IMapperConfigurationBuilder
{
IMapperConfigurationBuilder UseProfile<TUserDto, TUserDtoKey, TUser, TUserKey>()
where TUserDto : UserDto<TUserDtoKey>
where TUser : User<TUserKey>;
}
public static class MyServiceExtensions
{
private class MapperConfigurationBuilder : IMapperConfigurationBuilder
{
public HashSet<Type> ProfileTypes { get; } = new HashSet<Type>();
public IMapperConfigurationBuilder UseProfile<TUserDto, TUserDtoKey, TUser, TUserKey>()
where TUserDto : UserDto<TUserDtoKey>
where TUser : User<TUserKey>
{
ProfileTypes.Add(typeof(UserMappingProfile<TUserDto, TUserDtoKey, TUser, TUserKey>));
return this;
}
}
public static IMapperConfigurationBuilder AddMyMapper(this IServiceCollection services)
{
var builder = new MapperConfigurationBuilder();
services.AddSingleton<IConfigurationProvider>(sp => new MapperConfiguration(cfg =>
{
foreach (var profileType in builder.ProfileTypes)
cfg.AddProfile(profileType);
}));
services.AddScoped<IMapper>(sp => new Mapper(sp.GetRequiredService<IConfigurationProvider>(), sp.GetService));
return builder;
}
}
然后映射配置文件注册将如下所示:
services.AddMyMapper()
.UseProfile<MyUserDto, int, MyUser, int>();