2014年8月5日 星期二

AutoMapper 自訂對應關系

在來源和目的物件中,如果屬性名稱和型態都相同的話,AutoMapper會自動轉換
但通常事情不會這麼單純,很多時後我們會需要指定轉換的方式,用一個簡單的例子來說明

首先是來源的Model物件
public class DemoModel
{
    public int CustId { get; set; }
    public string CustName { get; set; }
    public bool CustGender { get; set; }
}

再來是要轉換的ViewModel物件
public class DemoViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string FullName { get; set; }
    public string Gender { get; set; }
    public DateTime Date { get; set; }
}

轉換的設定方式
Ignore是用來略過對應,不給值
MapFrom是用來指定對應的屬性名稱,或是組合多個屬性值
ResolveUsing是指定自訂的型別轉換方式
UseValue是在轉換的過程中直接給值
NullSubstitute是在原始值為空的時後才給值
Condition傳入一個條件為true才給值
public class Class1
{
    public void GetViewModel()
    {
        Mapper.CreateMap<DemoModel, DemoViewModel>()
            .ForMember(dest => dest.Id, opt => opt.Ignore())
            .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.CustName))
            .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => string.Format("{0}:{1}", src.CustId, src.CustName)))
            .ForMember(dest => dest.Gender, opt => opt.ResolveUsing<GenderResolver>().FromMember(src => src.CustGender))
            .ForMember(dest => dest.Date, opt => opt.UseValue<DateTime>(DateTime.Now));

        DemoModel model = new DemoModel
        {
            CustId = 123,
            CustName = "abc",
            CustGender = true
        };

        DemoViewModel viewModel = Mapper.Map<DemoModel, DemoViewModel>(model);
        Console.WriteLine("id:{0}, name:{1}, fullname:{2}, gender:{3}, date:{4}", viewModel.Id, viewModel.Name, viewModel.FullName, viewModel.Date, viewModel.Gender);
    }

    private class GenderResolver : ValueResolver<bool, string>
    {
        protected override string ResolveCore(bool source)
        {
            return source ? "男" : "女";
        }
    }
}