当使用customResolver从2个源映射到目标时,AutoMapper产生错误

时间:2018-12-09 07:51:03

标签: c# 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的新手,我已经搜索过google,但找不到任何相关信息。我不确定是否有更好的方法将它们映射在一起。

谢谢

1 个答案:

答案 0 :(得分:0)

由Lucian重定向,CustomResolver需要首先初始化。即从Automapper文档

  

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

     

MapFrom

     

MapFrom(typeof(CustomValueResolver))

     

MapFrom(aValueResolverInstance)

使用第三个选项,解决了该问题。 即

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

但是,在我的情况下,由于我将存储库用作Resolver的参数,因此我不得不从服务提供商处解析范围限定的存储库。

因为我使用的是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)));
 }