我想创建.Net Core类库,它将包含以下扩展方法:
public static class MyServiceExtensions
{
public static IServiceCollection AddMyService<TUserDto, TUserDtoKey, TUser, TUserKey>(this IServiceCollection services)
where TUserDto : UserDto<TUserDtoKey>
where TUser : User<TUserKey>
{
services.AddAutoMapper(config =>
{
config.AddProfile<UserMappingProfile<TUserDto, TUserDtoKey, TUser, TUserKey>>();
});
return services;
}
}
我有以下Automapper配置文件:
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 class UserDto<TKey>
{
public TKey UserId { get; set; }
public string UserName { get; set; }
}
public class User<TKey>
{
public TKey Id { get; set; }
public string UserName { get; set; }
}
public class MyUser : User<int>
{
public string Email { get; set; }
}
public class MyUserDto : UserDto<int>
{
public string Email { get; set; }
}
如果我尝试像这样使用它:
services.AddMyService<MyUserDto, int, MyUser, int>();
我收到此错误:
{System.ArgumentException:无法创建GenericMapping.Services.Mapping.UserMappingProfile4 [TUserDto,TUserDtoKey,TUser,TUserKey]的实例,因为Type.ContainsGenericParameters为true . 在System.RuntimeType.CreateInstanceCheckThis()处于System.RuntimeType.CreateInstanceSlow(Boolean publicOnly,Boolean wrapExceptions,Boolean skipCheckThis,Boolean fillCache),位于AutoMapper.Configuration.MapperConfigurationExpression的System.Activator.CreateInstance(Type type,Boolean nonPublic,Boolean wrapExceptions) . AddProfile(Type profileType)位于C:\ projects \ _自动化器\ src \ AutoMapper \ Configuration \ MapperConfigurationExpression.cs:第44行的AutoMapper.ServiceCollectionExtensions . <> c__DisplayClass10_0 . <AddAutoMapperClasses> g__ConfigAction | 4(IMapperConfigurationExpression cfg)在C:\ projects \ automapper-extensions-microsoft-dependencyinjectio \ src \ AutoMapper.Extensions.Microsoft.DependencyInjection \ ServiceCollectionExtensions.cs:位于C:\ projects \ automapper \ src \ AutoMapper \ MapperConfiguration.cs中AutoMapper.MapperConfiguration.Build(Action1 configure)的第83行: AutoMapper.ServiceCollectionExtensions.AddAutoMapperClasses的第307行(IServiceCollection服务,Action1 additionalInitAction) ,IEnumerable1 assembliesToScan)在C:\ projects \ automapper-extensions-microsoft-dependencyinjectio \ src \ AutoMapper.Extensions.Microsoft.DependencyInjection \ ServiceCollectionExtensions.cs:第89行,GenericMapping.Services.Extensions.MyServiceExtensions.AddMyService [TUserDto,TUserDtoKey,TUser ,TUserKey](IServiceCollection服务),位于C:\ Projects \ GenericMapping,GenericMapping \ Startup.cs中的C: :第33行
我该如何解决这个问题?
1 回答
您的问题的根本原因是AddAutoMapper扩展方法的错误使用 . 此方法扫描程序集以查找配置文件(和其他AutoMapper组件),并使用找到的配置在DI容器中注册IMapper组件 . (我建议你看一下its sources来了解究竟发生了什么 . )
您得到异常,因为AddAutoMapper找到UserMappingProfile类,但不知道如何实例化它,因为它有4个打开类型参数 .
解决问题的最简单方法是使您的通用配置文件类成为抽象,并使用所需的类型参数对其进行子类化:
现在您根本不需要MyServiceExtensions,只需
services.AddAutoMapper()
调用,您的配置将自动获取 .但是,如果您坚持使用自己的扩展方法进行配置,则必须避免使用AddAutoMapper,因为它只打算调用一次 . 您可以提供自己的注册逻辑,而不是扫描Profile类的程序集 . 使用构建器模式的示例:
然后映射配置文件注册将如下所示: