AutoMapper无法通过反射创建IMemberValueResolver的实例



我收到一个错误,AutoMapper v11.0.1无法创建自定义IMemberValueResolver类型的实例。

这是我的自定义解析器:

public class FooCollectionResolver<TModel, TViewModel> : IMemberValueResolver<object, object, BlockListModel?, IEnumerable<TViewModel>?>
where TModel : class, IPublishedElement
where TViewModel : class
{
public IEnumerable<TViewModel>? Resolve(object source, object destination, BlockListModel? sourceMember, IEnumerable<TViewModel>? destMember, ResolutionContext context)
{ }
}

它获取一个源BlockListModel成员,并返回一个TViewModel的集合。

示例用法:

this.CreateMap<FooModel, FooViewModel>().ForMember(
dest => dest.BlockListModelMember,
src => src.MapFrom<FooCollectionResolver<FooCollectionModel, FooCollectionViewModel>, BlockListModel>(s => s.BlockListModelMember));

FooModel.cs:

public class FooModel 
{
public string Title { get; set; }
public BlockListModel BlockListModelMember { get; set; }
}

FooViewModel.cs

public class FooViewModel 
{
public string Title { get; set; }
public IEnumerable<FooCollectionViewModel> BlockListModelMember { get; set; }
}

FooCollectionModel.cs

public class FooCollectionModel 
{
public string FooMember { get; set; }
}

FooCollectionViewModel.cs

public class FooCollectionViewModel 
{
public string FooMember { get; set; }
}

DI的注册方式如下:

services.AddAutoMapper(cfg =>
{
cfg.AddMaps(new[]
{
"FooNamespace.Web",
"FooNamespace.Web.Framework",
});
});

该特定映射配置文件包含在FooNamespace.Web中。此配置文件中的任何其他地图都没有问题。

AutoMapper抛出一个错误,即它无法在运行时创建FooCollectionResolver的实例。我相信它试图在使用通用.MapFrom<T>方法时通过反射来创建实例。

例外:

AutoMapperMappingException:无法创建类型为的实例GPE。网状物框架映射。ValueResolvers。FooCollectionResolver`2[FoodCollectionModel,FooCollectionViewModel]

AutoMapper。ResolutionContext。CreateInstance(类型类型(

AutoMapperMappingException:映射类型时出错。

映射类型:FooModel->FooViewModel

类型映射配置:FooModel->FooViewModel

目标成员:BlockListModelMember

有人知道为什么会这样吗?

我可以用内联分辨率函数来实现这一点,例如:

this.CreateMap<FooModel, FooViewModel>()
.ForMember(
dest => dest.BlockListModelMember,
src => src.MapFrom((src, dest, destMember, context) =>
{
// mapping logic
}));

但我想重用这个逻辑,因为它是应用于各种不同模型的相同通用模式,因此通用IMemberValueResolver

当您使用services.AddAutoMapper的特定重载时,它不会将您的值解析程序添加到容器中。您可以使用它来扫描程序集以查找所有相关类型:

services.AddAutoMapper(
typeof(FooCollectionResolver<,>).Assembly,
typeof(SomeOtherType).Assembly /*, more if required */);

如果您查看AddAutoMapperClasses的实现(这是AddAutoMapper扩展方法最终调用的(,您会发现,如果它传递了assembliesToScan的集合,那么它只注册IMemberValueResolver类型(以及其他类型(。

您正在使用的重载传递此参数的null,因此它们不会被注册。

最新更新