public class Foo
{
public int ID { get; set; }
public string Name { get; set; }
}
public class FooDto
{
public int ID { get; set; }
public string Name { get; set; }
}
public void Map()
{
var config = new MapperConfiguration(cfg => cfg.CreateMap<Foo, FooDto>());
var mapper = config.CreateMapper();
Foo foo = new Foo { ID = 1, Name = "Tom" };
FooDto dto = mapper.Map<FooDto>(foo);
}
2 注冊
在使用 Map 方法之前,首先要告訴 AutoMapper 什么類可以映射到什么類,
var config = new MapperConfiguration(cfg => cfg.CreateMap<Foo, FooDto>());
每個 AppDomain 只能進行一次配置,這意味著放置配置代碼的最佳位置是在應用程式啟動中,例如 ASP.NET 應用程式的 Global.asax 檔案,
從 9.0 開始 Mapper.Initialize 方法就不可用了,
2.1 Profile
Profile 是組織映射的另一種方式,新建一個類,繼承 Profile,并在建構式中配置映射,
public class EmployeeProfile : Profile
{
public EmployeeProfile()
{
CreateMap<Employee, EmployeeDto>();
}
}
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<EmployeeProfile>();
});
public class Foo
{
public int Id { get; set; }
public string MyName { get; set; }
}
public class FooDto
{
public int ID { get; set; }
public string My_Name { get; set; }
}
public void Map()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Foo, FooDto>();
cfg.SourceMemberNamingConvention = new PascalCaseNamingConvention();
cfg.DestinationMemberNamingConvention = new LowerUnderscoreNamingConvention();
});
var mapper = config.CreateMapper();
Foo foo = new Foo { Id = 2, MyName = "Tom" };
FooDto dto = mapper.Map<FooDto>(foo);
}
3.2 配置可見性
默認情況下,AutoMapper 僅映射 public 成員,但其實它是可以映射到 private 屬性的,
var config = new MapperConfiguration(cfg =>
{
cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.SetMethod.IsPrivate;
cfg.CreateMap<Source, Destination>();
});
需要注意的是,這里屬性必須添加 private set,省略 set 是不行的,
3.3 全域屬性/欄位過濾
默認情況下,AutoMapper 嘗試映射每個公共屬性/欄位,以下配置將忽略欄位映射,
var config = new MapperConfiguration(cfg =>
{
cfg.ShouldMapField = fi => false;
});
3.4 識別前綴和后綴
var config = new MapperConfiguration(cfg =>
{
cfg.RecognizePrefixes("My");
cfg.RecognizePostfixes("My");
}
3.5 替換字符
var config = new MapperConfiguration(cfg =>
{
cfg.ReplaceMemberName("?", "A");
});
這功能我們基本上用不上,
4 呼叫建構式
有些類,屬性的 set 方法是私有的,
public class Commodity
{
public string Name { get; set; }
public int Price { get; set; }
}
public class CommodityDto
{
public string Name { get; }
public int Price { get; }
public CommodityDto(string name, int price)
{
Name = name;
Price = price * 2;
}
}
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
}
public class Employee2 : Employee
{
public string DeptName { get; set; }
}
public class EmployeeDto
{
public int ID { get; set; }
public string Name { get; set; }
}
public class EmployeeDto2 : EmployeeDto
{
public string DeptName { get; set; }
}
陣列映射代碼如下:
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Employee, EmployeeDto>().Include<Employee2, EmployeeDto2>();
cfg.CreateMap<Employee2, EmployeeDto2>();
});
IMapper mapper = config.CreateMapper();
var employees = new[]
{
new Employee { ID = 1, Name = "Tom" },
new Employee2 { ID = 2, Name = "Jerry", DeptName = "R & D" }
};
var dto = mapper.Map<Employee[], EmployeeDto[]>(employees);
public class Employee
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string GetFullName()
{
return $"{FirstName} {LastName}";
}
}
public class EmployeeDto
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
}
7 自定義映射
當源型別與目標型別名稱不一致時,或者需要對源資料做一些轉換時,可以用自定義映射,
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime JoinTime { get; set; }
}
public class EmployeeDto
{
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
public int JoinYear { get; set; }
}
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public Department Department { get; set; }
}
public class Department
{
public int ID { get; set; }
public string Name { get; set; }
}
public class EmployeeDto
{
public int ID { get; set; }
public string Name { get; set; }
public int DepartmentID { get; set; }
public string DepartmentName { get; set; }
}
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public Department Department { get; set; }
}
public class Department
{
public int DepartmentID { get; set; }
public string DepartmentName { get; set; }
}
public class EmployeeDto
{
public int ID { get; set; }
public string Name { get; set; }
public int DepartmentID { get; set; }
public string DepartmentName { get; set; }
}
Department 類中的屬性名,直接跟 EmployeeDto 類中的屬性名一致,則可以使用 IncludeMembers 方法指定,
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Employee, EmployeeDto>().IncludeMembers(e => e.Department);
cfg.CreateMap<Department, EmployeeDto>();
});
9 嵌套映射
有時,我們可能不需要展平,看如下例子:
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public Department Department { get; set; }
}
public class Department
{
public int ID { get; set; }
public string Name { get; set; }
public string Heads { get; set; }
}
public class EmployeeDto
{
public int ID { get; set; }
public string Name { get; set; }
public DepartmentDto Department { get; set; }
}
public class DepartmentDto
{
public int ID { get; set; }
public string Name { get; set; }
}
我們要將 Employee 映射到 EmployeeDto,并且將 Department 映射到 DepartmentDto,
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Employee, EmployeeDto>();
cfg.CreateMap<Department, DepartmentDto>();
});