我正在构建一个应用程序来查看和修改自定义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());