【问题标题】:AutoMapper custom type convert using ConstructServicesUsingAutoMapper 自定义类型转换使用 ConstructServicesUsing
【发布时间】:2013-06-21 17:51:08
【问题描述】:

根据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() 使用自定义类型转换器?

【问题讨论】:

  • 这有帮助吗?:Mapper.CreateMap().ConstructUsingServiceLocator().ConvertUsing(new SourceDestinationTypeConverter());
  • 或 Mapper.CreateMap().ConvertUsing(new SourceDestinationTypeConverter());两者都使 Assert 成功,但它们中的任何一个对您的情况有好处吗?
  • 谢谢,但我需要使用 Mapper.Map-Method(而不是 Mapper.CreateMap),因为我需要传入一些运行时参数。
  • 你是否需要使用:Mapper.CreateMap().ConstructUsingServiceLocator(); ?因为我确实使用“Mapper.CreateMap();”来完成这项工作......但我猜你是通过服务定位器传递这些运行时参数?
  • 我仍然面临着关于您想要实现的目标的问题。我已经浏览了几个代码示例(都对您的代码进行了一些修改),并且我设法获得了很多成功的结果。如果我说您正在尝试使用 IoC 容器/对象工厂来创建目标对象的实例以进行转换,我是否正确。 (因为这是 ConstructServicesUsing 的用武之地)。在这里,您传入的是 Converter 对象,它看起来不正确。我在使用 IoC 容器/工厂和自定义转换器时也遇到了问题。

标签: c# automapper typeconverter


【解决方案1】:

我测试了此代码并使用以下代码使其正常工作:

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 到 Type 和 String 到 Int 的映射。 我还必须删除以下行

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

替换为

Mapper.CreateMap<Source, Destination>();

我不知道“ConstructUsingServiceLocator()”选项,但在这种情况下将其忽略是可行的...(我不知道忽略它是否会给您带来其他问题。直到现在我还没有但在使用 Automapper 时使用了此选项。)

请注意,我必须添加“Value3”参数,因为转换会失败...将 NULL 值转换为 Type 可能非常困难...(而且我不知道必须进行哪种转换这里...)

【讨论】:

  • 谢谢,但是 SourceDestinationTypeConverter 的 Convert 方法永远不会被调用。
【解决方案2】:

我遇到了以下错误

InvalidCastException:无法转换类型为“xxxTypeConverter”的对象 键入'AutoMapper.ITypeConverter`2 [System.String,System.DateTime]' 为 CustomTypeConverter 执行 Automapper 示例时。

我通过替换解决了这个问题

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>

【讨论】:

    猜你喜欢
    • 2012-09-10
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-09
    • 1970-01-01
    相关资源
    最近更新 更多