首页 > 解决方案 > 使用 customResolver 从 2 个源映射到目标时 AutoMapper 产生错误

问题描述

我有两个来源

public class Source1 
{
    public int Id {get;set;}
    public int Source2ID { get; set; }
    ... //Other Fields

}

Source2 喜欢

public class Source2 : Entity
{
    public int Id {get;set;}
    public string Name { get; set; }

}

和一个目的地类如下

public class destination
{
    public int Id {get;set;}
    public int Source2ID { get; set; }
    public string Source2Name {get;set;}
    ... //Other Fields

}

我想要实现的是将目标中的 source2 名称与 source1 中可用的 source2ID 映射。

我尝试过的是使用自定义值解析器。

 public class CustomResolver : IValueResolver<Source1, Destination, string>
{

    private readonly IRepository<Source2> _suiteRepository;

    public CustomResolver(IRepository<Source2> suiteRepository )
    {
        _suiteRepository = suiteRepository;
    }

    public string Resolve(Source1 source, Destination destination, string destMember, ResolutionContext context)
    {
        return _suiteRepository.Get(source.Source2ID).Name;
    }
}

然后在配置中,我按如下方式创建地图。

config.CreateMap<Source1, Destination>()
  .ForMember(u => u.Name, options => options.ResolveUsing<CustomResolver>());

以下是调用映射器的代码

var source1 = await _repository
     .GetAll()
     .ToListAsync();

var destinationList = ObjectMapper.Map<List<Destination>>(source1);

但是,这会产生以下错误。

An unhandled exception occurred while processing the request.
MissingMethodException: No parameterless constructor defined for this object.
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, bool publicOnly, bool wrapExceptions, ref bool canBeCached, ref RuntimeMethodHandleInternal ctor)

AutoMapperMappingException: Error mapping types.

Mapping types:
Destination
Source1

Type Map configuration:
Source1-> Destinatinon
Namespace.Source1 -> Namespace.Destination

Property:
Source2Name
lambda_method(Closure , List<Sourc1> , List<Destination> , ResolutionContext )

AutoMapperMappingException: Error mapping types.

我是 AutoMapper 的新手,我搜索了谷歌,但找不到关于此的内容。我不确定是否有更好的方法将这些映射在一起。

谢谢

标签: c#automapper

解决方案


正如 Lucian 重定向的那样,需要首先初始化 CustomResolver。即来自 Automapper 文档

一旦我们有了 IValueResolver 实现,我们需要告诉 AutoMapper 在解析特定目标成员时使用这个自定义值解析器。在告诉 AutoMapper 使用自定义值解析器时,我们有多种选择,包括:

MapFrom<TValueResolver>

MapFrom(typeof(CustomValueResolver))

MapFrom(aValueResolverInstance)

使用第三个选项,解决了这个问题。IE

config.CreateMap<Source1, Destination>()
  .ForMember(u => u.Name, options => options.ResolveUsing(new CustomResolver());

但是在我的情况下,由于我将存储库作为解析器的参数,因此我必须从服务提供者解析作用域存储库。

因为,我使用的是 AbpBoilerplate,所以我的代码看起来像这样。

 using (var repo = Configuration.Modules.AbpConfiguration.IocManager.CreateScope().ResolveAsDisposable<IRepository<Source2>>())
 {

     config.CreateMap<Source1, Destination>()
          .ForMember(u => u.Name, options => options.ResolveUsing(new CustomResolver(repo.Object)));
 }

推荐阅读