映射包含在通用结构中的List

时间:2014-08-20 16:06:51

标签: c# automapper

上下文

我正在构建一个应用程序来查看和修改自定义Web爬网程序的配置设置。配置包括要爬网的站点。这些网站可以组织成集合。可以在集合级别或站点级别指定某些设置。例如,集合具有TimeOut设置,集合中的网站可以使用集合的TimeOut,也可以指定自己的值。为了促进这一点,我定义了一个类似于Nullable<T>的结构Inheritable<T>,基本上是这样的:

public struct Inheritable<T> {
    public bool IsInherited { get; }
    public T Value { get; }
}

因此,一个Inheritable属性的IsInherited标志设置为true,或者它有自己的值。请注意,这与对象方向上下文中的继承无关。

设置还包括要搜索的模式列表:

public class Pattern {
    public string Name { get; set; }
    public string Expression { get; set; }
}


public class SiteSettings {
    public Inheritable<int> TimeOut { get; set; }
    public List<Pattern> Patterns { get; set; }
    // Many more properties
}

我正在使用AutoMapper将DTO对象转换为viewmodel对象。

以下代码正是如此。它包括可继承的完整实现,可以复制/粘贴到LinqPad(您需要引用AutoMapper dll才能运行它。)

自包含示例:

public class SiteSettingsDto {
    public Inheritable<int> TimeOut { get; set; }
    public List<PatternDto> Patterns { get; set; }
}

public class SiteSettingsViewmodel {
    public Inheritable<int> TimeOut { get; set; }
    public List<PatternViewmodel> Patterns { get; set; }
}

public class PatternDto {
    public string Name { get; set; }
    public string Expression { get; set; }
}

public class PatternViewmodel {
    public string Name { get; set; }
    public string Expression {get; set; }
}

void Main() {
    var siteSettingsDto = new SiteSettingsDto() {
        TimeOut = 5,
        Patterns = new List<PatternDto>() {
            new PatternDto() {
                Name = "Google",
                Expression = "google"
            },
            new PatternDto() {
                Name = "Wikipedia",
                Expression = "wikipedia"
            }
        }
    };

    Mapper.CreateMap<PatternDto, PatternViewmodel>();
    Mapper.CreateMap<SiteSettingsDto, SiteSettingsViewmodel>();

    Mapper.AssertConfigurationIsValid();
    var siteSettingsViewmodel = Mapper.Map<SiteSettingsViewmodel>(siteSettingsDto);
    siteSettingsViewmodel.Dump();
}

public struct Inheritable<T> {
    private readonly T valueField;
    private readonly bool isInheritedField;

    public T Value {
        get { return valueField; }
    }

    public bool IsInherited {
        get { return isInheritedField; }
    }

    public Inheritable(T value) {
        valueField = value;
        isInheritedField = false;
    }

    public Inheritable(bool isInherited) {
        valueField = default(T);
        isInheritedField = isInherited;
    }

    public Inheritable(bool isInherited, T value)
    {
        valueField = value;
        isInheritedField = isInherited;
    }

    public override string ToString() {
        return IsInherited ? "Inherited" : valueField == null ? "": valueField.ToString();
    }

    public static implicit operator Inheritable<T>(T value) {
        return new Inheritable<T>(value);
    }

    public static explicit operator T(Inheritable<T> value) {
        return value.Value;
    }
}

实际问题

我想让Patterns属性也可以继承。当我将Patterns属性设为可继承时,AutoMapper需要额外的指导才能从Inheritable<List<PatternDto>>映射到Inheritable<List<PatternViewmodel>>,但我不能为我的生活找出如何做到这一点。

这就是我的SiteSetting对象现在的样子:

public class SiteSettingsDto {
    public Inheritable<int> TimeOut { get; set; }
    public Inheritable<List<PatternDto>> Patterns { get; set; }
}

public class SiteSettingsViewmodel {
    public Inheritable<int> TimeOut { get; set; }
    public Inheritable<List<PatternViewmodel>> Patterns { get; set; }
}

这是Mapper.AssertConfigurationIsValid()抛出的异常:

  

UserQuery + Inheritable`1 [[System.Collections.Generic.List`1 [[UserQuery + PatternViewmodel,query_mtnney,Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null]],mscorlib,Version上的以下属性= 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]无法映射:

     

模式

     

添加自定义映射表达式,忽略,添加自定义解析程序或修改目标类型UserQuery + Inheritable`1 [[System.Collections.Generic.List`1 [[UserQuery + PatternViewmodel,query_mtnney,Version = 0.0.0.0 ,Culture = neutral,PublicKeyToken = null]],mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]。

     

上下文:

     

映射到属性模式来自UserQuery + Inheritable`1 [[System.Collections.Generic.List`1 [[UserQuery + PatternDto,query_mtnney,Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null]],mscorlib, Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]到UserQuery + Inheritable`1 [[System.Collections.Generic.List`1 [[UserQuery + PatternViewmodel,query_mtnney,Version = 0.0.0.0,Culture = neutral, PublicKeyToken = null]],mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]     从UserQuery + SiteSettingsDto类型映射到UserQuery + SiteSettingsViewmodel

     

抛出了“AutoMapper.AutoMapperConfigurationException”类型的异常。

更新

我已经能够使用以下类型转换器获得我想要的映射,但是当我调用Mapper.AssertConfigurationIsValid()时仍然会遇到上述异常,这很不幸,我仍然想解决它。< / p>

public class InheritablePatternConverter : ITypeConverter<Inheritable<List<PatternDto>>, Inheritable<List<PatternViewmodel>>> {
    public Inheritable<List<PatternViewmodel>> Convert(ResolutionContext context)
    {
        var source = (Inheritable<List<PatternDto>>) context.SourceValue;
        return new Inheritable<List<PatternViewmodel>>(source.IsInherited, Mapper.Map<List<PatternDto>, List<PatternViewmodel>>(source.Value));
    }
}

使用via:

    Mapper.CreateMap<Inheritable<List<PatternDto>>, Inheritable<List<PatternViewmodel>>>().ConvertUsing(new InheritablePatternConverter());

0 个答案:

没有答案