使用ConstructServicesUsing进行AutoMapper自定义类型转换

时间:2013-06-21 17:51:09

标签: c# automapper typeconverter

根据AutoMapper Documentation,我应该可以使用以下方法创建和使用自定义类型转换器的实例:

var dest = Mapper.Map<Source, Destination>(new Source { Value = 15 },
    opt => opt.ConstructServicesUsing(childContainer.GetInstance));

我有以下源和目标类型:

public class Source {
    public string Value1 { get; set; }
    public string Value2 { get; set; }
    public string Value3 { get; set; }
}

public class Destination {
    public int Value1 { get; set; }
    public DateTime Value2 { get; set; }
    public Type Value3 { get; set; }
}

以下类型的转换器:

public class DateTimeTypeConverter : ITypeConverter<string, DateTime> {
    public DateTime Convert(ResolutionContext context) {
        return System.Convert.ToDateTime(context.SourceValue);
    }
}

public class SourceDestinationTypeConverter : ITypeConverter<Source, Destination> {
    public Destination Convert(ResolutionContext context) {
        var dest = new Destination();
        // do some conversion
        return dest;
    }
}

这个简单的测试应断言其中一个日期属性被正确转换:

[TestFixture]
public class CustomTypeConverterTest {
    [Test]
    public void ShouldMap() {
        Mapper.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());
        Mapper.CreateMap<Source, Destination>().ConstructUsingServiceLocator();

        var destination =
        Mapper.Map<Source, Destination>(
        new Source { Value1 = "15", Value2 = "01/01/2000", }, 
            options => options.ConstructServicesUsing(
                type => new SourceDestinationTypeConverter())
        ); // exception is thrown here

        Assert.AreEqual(destination.Value2.Year, 2000);
    }
}

但是在断言发生之前我已经得到了一个例外:

System.InvalidCastException : Unable to cast object of type 'SourceDestinationTypeConverter ' to type 'Destination'

我现在的问题是,如何使用ConstructServicesUsing()

使用自定义类型转换器

2 个答案:

答案 0 :(得分:6)

我测试了这段代码并使用以下代码完成了这项工作:

public void TestMethod1()
    {
        Mapper.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());
        Mapper.CreateMap<string, Type>().ConvertUsing(new StringTypeConverter());
        Mapper.CreateMap<string, int>().ConvertUsing(new StringIntConverter());
        Mapper.CreateMap<Source, Destination>();

        var destination =
        Mapper.Map<Source, Destination>(
        new Source { Value1 = "15", Value2 = "01/01/2000", Value3 = "System.String" },
            options => options.ConstructServicesUsing(type => new SourceDestinationTypeConverter())
        );

        Assert.AreEqual(destination.Value2.Year, 2000);
    }

额外的转换器:

 public class StringTypeConverter : ITypeConverter<string, Type>
{
    public Type Convert(ResolutionContext context)
    {
        return Type.GetType(context.SourceValue.ToString());
    }
}

public class StringIntConverter : ITypeConverter<string, int>
{
    public int Convert(ResolutionContext context)
    {
        return Int32.Parse(context.SourceValue.ToString());
    }
}

Automapper缺少String to Type和String to Int的映射。 此外,我不得不删除以下行

Mapper.CreateMap<Source, Destination>().ConstructUsingServiceLocator();

并将其替换为

Mapper.CreateMap<Source, Destination>();

我不知道“ConstructUsingServiceLocator()”选项,但是在这种情况下将其删除...(我不知道是否将其删除会给你带来其他问题。直到现在我还没有在使用Automapper时使用此选项。)

请注意我必须添加“Value3”参数,因为转换会失败...将NULL值转换为Type会非常困难...(而且我不知道必须发生什么样的转换这里...)

答案 1 :(得分:0)

我遇到错误 InvalidCastException:在为CustomTypeConverter执行Automapper示例时,无法将类型为xxxTypeConverter的对象转换为类型为AutoMapper.ITypeConverter`2 [System.String,System.DateTime]'。 我通过替换来解决了该问题

public class DateTimeTypeConverter : ITypeConverter<string, DateTime>

 public class DateTimeTypeConverter : AutoMapper.ITypeConverter<string, DateTime>

类似

public class TypeTypeConverter : ITypeConverter<string, Type>

使用

public class TypeTypeConverter : AutoMapper.ITypeConverter<string, Type>