C# 如何使用AutoMapper动态映射内部类型
我定义了以下四个类C# 如何使用AutoMapper动态映射内部类型,c#,automapper,C#,Automapper,我定义了以下四个类 public class Source { public object Value { get; set; } } public class Destination { public object Value { get; set; } } public class SourceDataType { //... } public class De
public class Source
{
public object Value { get; set; }
}
public class Destination
{
public object Value { get; set; }
}
public class SourceDataType
{
//...
}
public class DestinationDataType
{
//...
}
我将Automapper
配置如下:
AutoMapper.Mapper.CreateMap<Source, Destination>();
AutoMapper.Mapper.CreateMap<SourceDataType, DestinationDataType>();
目标类型与预期相同。我希望Automapper
能够利用SourceDataType
和DestinationDataType
之间的映射,将SourceDataType
瞬间映射到DestinationDataType
瞬间。但是,为目标对象指定了一个SourceDataType
值
我还尝试了DynamicMap
,但获得了相同的结果
var destination = AutoMapper.Mapper.DynamicMap<Source, Destination>(source);
var destination = AutoMapper.Mapper.DynamicMap<Destination>(source);
var destination=AutoMapper.Mapper.DynamicMap(源);
var destination=AutoMapper.Mapper.DynamicMap(源);
有没有办法配置
Automapper
来动态映射内部类 这里有两个问题:
首先,您没有定义SourceDataType
和DestinationDataType
之间的任何关系,因此AutoMapper无法知道如何转换这些类型
其次,这两个属性的类型是object
,并且(据我所知)AutoMapper不会基于动态类型进行转换
您可以通过使用;但是,我对此有所保留,因为属性的类型为object
无论如何,您可以尝试根据以下映射添加一些内容:
Mapper.CreateMap<object, object>().ConvertUsing(src =>
{
if (src is SourceDataType)
return new DestinationDataType(); // Put your conversion code here.
else
return src;
});
Mapper.CreateMap().ConvertUsing(src=>
{
if(src是SourceDataType)
返回新的DestinationDataType();//将转换代码放在这里。
其他的
返回src;
});
就像我说的,我不喜欢这样,因为
对象
将匹配所有属性类型。这是可以解决的,尽管如果越来越多的类型被添加到混合中,它将变得无法维护和复杂。无论如何,对于您的情况,这将起作用:
[Test]
public void CustomMapping()
{
//arrange
Mapper.CreateMap<Source, Destination>()
.ForMember(d=>d.Value, opt=>opt.ResolveUsing(ResolveValue));
Mapper.CreateMap<SourceDataType, DestinationDataType>();
var source = new Source { Value = new SourceDataType() };
//act
var destination = Mapper.Map<Source, Destination>(source);
//assert
destination.Value.Should().Be.OfType<DestinationDataType>();
}
private object ResolveValue(ResolutionResult result)
{
var source = result.Context.SourceValue as Source;
if (result.Context.IsSourceValueNull || source == null || !(source.Value is SourceDataType))
{
return null;
}
var sourceValue = source.Value as SourceDataType;
return result.Context.Engine.Map<DestinationDataType>(sourceValue);
}
[测试]
public void CustomMapping()
{
//安排
Mapper.CreateMap()
.ForMember(d=>d.Value,opt=>opt.ResolveUsing(ResolveValue));
CreateMap();
var source=new source{Value=new SourceDataType()};
//表演
var destination=Mapper.Map(源);
//断言
destination.Value.Should();
}
私有对象ResolveValue(ResolutionResult结果)
{
var source=result.Context.SourceValue作为源;
if(result.Context.IsSourceValueNull | | source==null | |!(source.Value为SourceDataType))
{
返回null;
}
var sourceValue=source.Value作为SourceDataType;
返回result.Context.Engine.Map(sourceValue);
}
关于复杂度随着类型的增加而增加的问题,您是对的。我必须使用对象
属性的原因是我在编译时不知道类型。我想我必须把所有可能的类型组合放在ResoleValue
方法中。@FrankLiu:这可能太过分了。也许你可以用泛型重新考虑设计。是的,我将研究泛型源和目标解决方案。谢谢你。
[Test]
public void CustomMapping()
{
//arrange
Mapper.CreateMap<Source, Destination>()
.ForMember(d=>d.Value, opt=>opt.ResolveUsing(ResolveValue));
Mapper.CreateMap<SourceDataType, DestinationDataType>();
var source = new Source { Value = new SourceDataType() };
//act
var destination = Mapper.Map<Source, Destination>(source);
//assert
destination.Value.Should().Be.OfType<DestinationDataType>();
}
private object ResolveValue(ResolutionResult result)
{
var source = result.Context.SourceValue as Source;
if (result.Context.IsSourceValueNull || source == null || !(source.Value is SourceDataType))
{
return null;
}
var sourceValue = source.Value as SourceDataType;
return result.Context.Engine.Map<DestinationDataType>(sourceValue);
}