AutoMapper(三)

來源:互聯網
上載者:User

標籤:

返回總目錄

自訂類型轉換

有時,需要完全控制一個類型到另一個類型的轉換。一個類型一點都不像另一個類型,而且轉換函式已經存在了,在這種情況下,你想要從一個“寬鬆”的類型轉換成一個更強壯的類型,例如一個string的源類型到一個int32的目標類型。

這裡有兩個類Source和Destination,要把前者映射到後者,代碼如下:

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

截至發稿前,官方文檔這樣描述的“因為AutoMapper不清楚從string到int,Datetime或Type的映射,如果要嘗試映射的話,AutoMapper就會拋出異常(在映射時和配置檢查時)”。為了建立 這些類型的映射,我們必須提供自訂的類型轉換器,我們有三種方法這樣做:

 void ConvertUsing(Func<TSource, TDestination> mappingFunction); void ConvertUsing(ITypeConverter<TSource, TDestination> converter); void ConvertUsing<TTypeConverter>() where TTypeConverter : ITypeConverter<TSource, TDestination>;

但是,我先不實現自訂的類型轉換器試一下:

namespace ThirdAutoMapper{    class Program    {        static void Main(string[] args)        {            Mapper.CreateMap<Source, Destination>();            var source = new Source            {                Value1 = "5",                Value2 = "05/11/2015",                Value3 = "ThirdAutoMapper.Source"            };            var destination = Mapper.Map<Destination>(source);            Console.WriteLine("destination.Value1={0}", destination.Value1);            Console.WriteLine("destination.Value2={0}", destination.Value2);            Console.Read();        }    }}

出現如下錯誤,但從錯誤看來,只有從string到Type類型映射時,出現了錯誤,其他兩種類型呢?

現在我們將源類型和目標類型的第三個屬性Value3注釋掉,同時注釋掉參與映射前的源類型對象的Value3屬性,再來試一下。

果然,發現映射成功。也就說說最新版的AutoMapper預設可以將string類型映射為int和DateTime類型了。但是string還是沒辦法映射為Type類型。

對於以上AutoMapper的API給出的三種轉換方法,第一個選擇只是輸入一個源返回一個目標的函數,這對於簡單場合是有效,但是對於更大的案例會變得難以處理。在更複雜的情況下,我們可以一個自訂的類型轉換器,通過實現ITypeConverter<TSource, TDestination>介面建立:

第一種方法:

public class CustomTypeConverter : ITypeConverter<Source, Destination>{    public Destination Convert(ResolutionContext context)    {        Source src = context.SourceValue as Source;        var dest = new Destination        {            Value1 = System.Convert.ToInt32(src.Value1),            Value2 = System.Convert.ToDateTime(src.Value2),            Value3 = context.SourceType        };        return dest;    }}

然後給AutoMapper提供一個自訂類型的轉換器或者AutoMapper在運行時能執行個體化的簡化類型。對於上面的源/目標類型的映射配置就得以實現了:

修改Main方法中的代碼為:

static void Main(string[] args){    Mapper.CreateMap<Source, Destination>().ConvertUsing<CustomTypeConverter>();    var source = new Source    {        Value1 = "5",        Value2 = "05/11/2015",        Value3 = typeof(Source).ToString()
    };    var destination = Mapper.Map<Destination>(source);    Console.WriteLine("destination.Value1={0}", destination.Value1);    Console.WriteLine("destination.Value2={0}", destination.Value2);    Console.WriteLine(destination.Value3.ToString()==source.Value3);    Console.WriteLine(destination.Value3);    Console.Read();}

 

測試結果如下,映射成功!

第二種方法:

每個類型分別實現ITypeConverter介面:

public class DateTimeTypeConverter:ITypeConverter<string,DateTime>{    public DateTime Convert(ResolutionContext context)    {        return System.Convert.ToDateTime(context.SourceValue);    }}public class TypeTypeConverter : ITypeConverter<string, Type>{    public Type Convert(ResolutionContext context)    {        return context.SourceValue == typeof(Source).ToString() ? typeof(Source) : typeof(Destination);    }}
static void Main(string[] args){    //我看網上很多這種寫法,包括官方文檔,但是我這樣寫編譯錯誤,可能是現在的AutoMapper不支援了吧   // Mapper.CreateMap<string, int>().ConvertUsing( Convert.ToInt32);    Mapper.CreateMap<string, int>().ConvertUsing((context, intNum) => Convert.ToInt32(context.SourceValue));    Mapper.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter().Convert);    Mapper.CreateMap<string, Type>().ConvertUsing<TypeTypeConverter>();    Mapper.CreateMap<Source, Destination>();    //Mapper.CreateMap<Source, Destination>().ConvertUsing<CustomTypeConverter>();    var source = new Source    {        Value1 = "5",        Value2 = "05/11/2015",        Value3 = typeof(Source).ToString()    };    var destination = Mapper.Map<Destination>(source);    Console.WriteLine("destination.Value1={0}", destination.Value1);    Console.WriteLine("destination.Value2={0}", destination.Value2);    Console.WriteLine(destination.Value3.ToString()==source.Value3);    Console.WriteLine(destination.Value3);    Console.Read();}

測試結果,同樣完美通過。

AutoMapper(三)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.