AutoMapper:在自定义ITypeConverter

时间:2016-09-25 23:32:51

标签: c# automapper

我在AutoMapper中遇到一个自定义ITypeConverter的问题,关于循环引用。请参考以下示例:假设House中包含List<Person>Persons中的每一个都属于House。我们可以这样建模:

public class House 
{
    public int PropertyA { get; set; }
    public string PropertyB { get; set; }
    public List<Person> People { get; set; }
}

public class Person
{
    public int PropertyA { get; set; }
    public string PropertyB { get; set; }
    public House House { get; set; }
}

也许我们有一些看起来像这样的DTO:

public class HouseDto
{
    public string PropertyB { get; set; }
    public List<PersonDto> People { get; set; }
}

public class PersonDto
{
    public string PropertyB { get; set; }
    public HouseDto House { get;set; }
}

由于AutoMapper的基于约定的映射非常慢,我选择使用自定义类型转换器以避免AutoMapper使用的所有反射。所以我有两个这样的转换器:

public class HouseConverter : ITypeConverter<House, HouseDto>
{
    private readonly IMapper _mapper;

    public HouseConverter(IMapper mapper)
    {
        _mapper = mapper;
    }

    public HouseDto Convert(House source, HouseDto destination, ResolutionContext context)
    {
        if (source == null) return null;

        destination = destination ?? new HouseDto();
        destination.PropertyB = source.PropertyB;
        destination.People = _mapper.Map<List<PersonDto>>(source.People);

        return destination;
    }
}

public class PersonConverter : ITypeConverter<Person, PersonDto>
{
    private readonly IMapper _mapper;

    public PersonConverter(IMapper mapper)
    {
        _mapper = mapper;
    }

    public PersoneDto Convert(Person source, PersonDto destination, ResolutionContext context)
    {
        if (source == null) return null;

        destination = destination ?? new PersonDto();
        destination.PropertyB = source.PropertyB;
        destination.House = _mapper.Map<HouseDto>(source.House);

        return destination;
    }
}

显然这会导致StackOverflowException,因为关系会创建循环引用。为了避免这种情况,AutoMapper具有MaxDepth选项,您可以在使用内置映射方法时使用,但是当您开始使用自己的转换器时,此功能显然会丢失。我想了解一下在自定义转换器中实现此功能的正确方法。

问题在于:在AutoMapper v5.0之前,自定义转换器可以访问包含MaxDepth值的ResolutionContext,看起来它还包含当前深度好。这将允许我检测达到深度限制并停止任何进一步的递归。但是,随着5.0中ResolutionContext的更改,我无法找到访问MaxDepth或当前深度的任何方法。 这些值是否仍然可以以某种方式提供给ITypeConverter,或者我们现在希望自己实现这些值?在线文档并没有提供有关此特定用法的大量详细信息。

0 个答案:

没有答案