[C#]號稱是.net最快的Map工具,TinyMapper

  • 4155
  • 0
  • C#
  • 2017-04-12

簡單介紹一下TinyMapper的使用方式,TinyMapper最強大的部份就是簡單,最強大的缺點也是因為簡單,功能就沒像AutoMapper那麼的多

前言

其實在早期筆者也是用AutoMapper,後來發現似乎AutoMapper用到的功能再怎麼樣也是那兩三種而已,結果突然間在fb看到有人提到了TinyMapper,然後就稍微google一下大神,發現我的老天鵝啊,竟然號稱是.net最快的mapping object的tool耶,我就喜歡這個自信,但看來似乎也沒有人跳出來出來反對,感覺非常的吸引我啊,而其實最吸引我的是功能簡單,我需要的都有了,這對我來說就非常足夠了,所以決定轉而使用這個工具,但如果你的需求這套工具無法滿足的話,那建議還是留在AutoMapper使用就好了。

Nuget安裝

當然就是先安裝一下工具來使用囉,請看下圖示例

有興趣的人,也可以直接去github看一下https://github.com/TinyMapper/TinyMapper,下圖則是從官網截取的效能比較圖

最簡單的Mapping

首先在App_Start加一個MapperConfig來做最基本的配置吧

 public class MapperConfig
    {
        public static void Register()
        {
            TinyMapper.Bind<Sport, SportModel>();
        }
    }

接著就可以直接Map過來了,非常的方便,不管在任何地方遇到這兩個類別,都會按照MapConfig的規則

var sportList = sportSpiRepository.Value.GetAllSport();
return TinyMapper.Map<List<SportModel>>(sportList);

其實我們也可以直接就Map,不用在MapConfig做設置,但請注意這種方式有可能會造成thread safe的問題,所以請一定先指定類別的對應關係

特殊的指定用法

當類別要對應到另一個類別的時候,並不總是欄位名稱都會相符的,有時候我們可能要從Name to LongName的時候,或者我們要忽略某個欄位的對應

public class MapperConfig
    {
        public static void Register()
        {
            TinyMapper.Bind<Sport, SportModel>(config =>
            {
                config.Bind(source => source.Name, target => target.ShortName); //指定特別的對應規則
                config.Ignore(source => source.ShortName); //忽略某欄位的對應
            });
        }
    }

之後我們任何時候這兩個類別的Mapping都會按照config的設定規則。

自定義的Mapping

這種方式對我來說就非常少使用到了,而且用起來也沒有AutoMapper那麼方便,所以這邊如果在專案有大量使用的話,或許AutoMapper會更適合你,先建立一個MapSportModel.cs

public class MapSportModel : TypeConverter
    {
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return destinationType == typeof(SportModel);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            var sourceClass = (SportDto)value;
            var result = new SportModel
            {
                OrderNo=sourceClass.OrderNo,
                Sbc=sourceClass.Sbc,
                WholeName = $"{sourceClass.ShortName}+{sourceClass.Name}"
            };
            return result;
        }
    }
}

從上面可以看出來,如果我們欄位一多,有上百個的話,就全部都要寫上去,不然就只會針對有寫的做mapping,接著還要到來源的class加上attribute

[TypeConverter(typeof(MapSportModel))]
    public class SportDto
    {
        /// <summary>
        /// 定單序號
        /// </summary>
        [Display(Name = "Order No")]
        public int? OrderNo { get; set; } = 1;

        /// <summary>
        /// 簡寫
        /// </summary>
        [Display(Name ="Short Name")]
        [Required]
        public string ShortName { get; set; }

        /// <summary>
        /// 名稱
        /// </summary>
        [Display(Name ="Name")]
        [Required]
        public string Name { get; set; }

        /// <summary>
        /// SBC
        /// </summary>
        [Display(Name ="SBC")]
        public string Sbc { get; set; }
    }

這樣子才能做到要特別有邏輯轉換去一個欄位的對應,在這方面AutoMapper相對起來就方便多了

結論

當初會選擇TinyMapper就是簡單,所以如果覺得功能太弱不符合團隊複雜的mapping的話,那還是繼續使用AutoMapper會更適合。