Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用AutoMapper动态映射内部类型_C#_Automapper - Fatal编程技术网

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);
    }