DDD领域模型AutoMapper实现DTO(七)
DTO的应用场景:
定义产品类:
public class Product { public string ProductName { get; set; } public decimal ProductUnitPrice { get; set; } }
NueGet 添加AutoMapper映射组件。
定义ProductDTO对象:
public class ProductDTO { public string ProductName { get; set; } public decimal ProductUnitPrice { get; set; } }
定义两个类:
public class Address { public string AddressState { get; set; } public string AddressCity { get; set; } public string AddressStreet { get; set; } }
public class Customer
{
public string CustomerName { get; set; }
public string CustomerMobile { get; set; }
public Address CustomerAddress { get; set; }
}
多个对象的映射类:
public class CustomerDTO { public string Name { get; set; } public string Mobile { get; set; } public string State { get; set; } public string City { get; set; } public string Street { get; set; } }
映射的代码:
public class Mapping { public static ProductDTO CreateProductMapping() { var map=Mapper.CreateMap<Product, ProductDTO>(); Product p = new Product { ProductName = "P1", ProductUnitPrice = 100 }; var pdto = Mapper.Map<Product, ProductDTO>(p); return pdto; } public static CustomerDTO CreateCustomerMapping() { //创建映射关系 var map = Mapper.CreateMap<Customer, CustomerDTO>(); map.ForMember(ppt => ppt.Name, p => p.MapFrom(s => s.CustomerName)); map.ForMember(ppt => ppt.Mobile, p => p.MapFrom(s => s.CustomerMobile)); map.ForMember(ppt => ppt.State, p => p.MapFrom(s => s.CustomerAddress.AddressState)); map.ForMember(ppt => ppt.City, p => p.MapFrom(s => s.CustomerAddress.AddressCity)); map.ForMember(ppt => ppt.Street, p => p.MapFrom(s => s.CustomerAddress.AddressStreet)); Customer customer = new Customer { CustomerName = "sun", CustomerMobile = "135933", CustomerAddress = new Address { AddressState = "山西", AddressCity = "孝义", AddressStreet = "三贤路" } }; var customerdto = Mapper.Map<Customer, CustomerDTO>(customer); return customerdto; } //简单 public static CustomerDTO CreateCustomerMapppingNew() { var map = Mapper.CreateMap<Customer, CustomerDTO>(); map.ConstructProjectionUsing(s => new CustomerDTO { Name = s.CustomerName, Mobile = s.CustomerMobile, State = s.CustomerAddress.AddressState, City = s.CustomerAddress.AddressCity, Street = s.CustomerAddress.AddressStreet }); Customer customer = new Customer { CustomerName = "sun", CustomerMobile = "13458629365", CustomerAddress = new Address { AddressState = "山西", AddressCity = "孝义", AddressStreet = "三贤路" } }; var customerdto = Mapper.Map<Customer, CustomerDTO>(customer); return customerdto; } }
在上下文接口中(IRepositoryContext)中定义DTO的支持:
//添加DTO对象 void RegisterCreateDTO<TDTO, TAggreateRoot>(TDTO tdto, Action<TDTO> processdto) where TAggreateRoot : class, IAggreateRoot; void RegisterUpdate<TAggreateRoot>(TAggreateRoot aggreateroot) where TAggreateRoot : class, IAggreateRoot; void RegisterUpdateDTO<TDTO, TAggreateRoot>(TDTO tdto, Action<TDTO> processdto) where TAggreateRoot : class, IAggreateRoot;
仓储接口的调整:
void Create<TDTO>(TDTO tdto); TDTO GetByID<TDTO>(Guid id); List<TDTO> GetByCondition<TDTO>(Expression<Func<TAggreateRoot, bool>> condition); void Update<TDTO>(TDTO tdto); void Remove<TDTO>(TDTO tdto);
上下文DTO定义:(让EF上下文实现)
public abstract void RegisterCreateDTO<TDTO, TAggreateRoot>(TDTO tdto, Action<TDTO> processdto) where TAggreateRoot : class, IAggreateRoot; public abstract void RegisterUpdateDTO<TDTO, TAggreateRoot>(TDTO tdto, Action<TDTO> processdto) where TAggreateRoot : class, IAggreateRoot; public abstract void RegisterRemoveDTO<TDTO, TAggreateRoot>(TDTO tdto, Action<TDTO> processdto) where TAggreateRoot : class, IAggreateRoot;
EF上下文中实现:
public override void RegisterCreateDTO<TDTO, TAggreateRoot>(TDTO tdto, Action<TDTO> processdto) { if (processdto != null) processdto(tdto); var aggreateroot = Mapper.Map<TDTO, TAggreateRoot>(tdto); RegisterCreate(aggreateroot); } public override void RegisterUpdateDTO<TDTO, TAggreateRoot>(TDTO tdto, Action<TDTO> processdto) { if (processdto != null) processdto(tdto); var aggreateroot = Mapper.Map<TDTO, TAggreateRoot>(tdto); RegisterUpdate(aggreateroot); } public override void RegisterRemoveDTO<TDTO, TAggreateRoot>(TDTO tdto, Action<TDTO> processdto) { if (processdto != null) processdto(tdto); var aggreateroot = Mapper.Map<TDTO, TAggreateRoot>(tdto); RegisterUpdate(aggreateroot); }
EFRepository EF 仓储中的实现:
public void Create<TDTO>(TDTO tdto) { base.RegisterCreateDTO<TDTO, TAggreateRoot>(tdto, null); } public List<TDTO> GetByCondition<TDTO>(Expression<Func<TAggreateRoot, bool>> condition) { //找到聚合根 var aggreatroots = orderdbcontext.Set<TAggreateRoot>().Where(condition).ToList(); //转黄成TDTO列表 var tdtos = new List<TDTO>(); if (aggreatroots.Count > 0) { foreach (var aggreateroot in aggreatroots) { var tdto = Mapper.Map<TAggreateRoot, TDTO>(aggreateroot); tdtos.Add(tdto); } } return tdtos; } public TDTO GetByID<TDTO>(Guid id) { //得到聚合根 var aggreateroot = orderdbcontext.Set<TAggreateRoot>().Where(p => p.Id == id).SingleOrDefault(); //进行类型转换 var tdto = Mapper.Map<TAggreateRoot, TDTO>(aggreateroot); //返回对象 return tdto; } public void Remove<TDTO>(TDTO dto) { RegisterRemoveDTO<TDTO, TAggreateRoot>(dto, null); } public void Update<TDTO>(TDTO dto) { RegisterUpdateDTO<TDTO, TAggreateRoot>(dto, null); }
定义产品DTO类:
public class ProductDTO { public Guid Id { get; set; } public string Name { get; set; } public string Color { get; set; } public string Size { get; set; } public int Amount { get; set; } public decimal UnitPrice { get; set; } public string PCategoryName { get; set; } public string PDescription { get; set; } }
在ProductCategory中实现构造函数:
public ProductCategory() { }
在Product中实现DTO:
public Product(IRepository<Product> irepository) { this.irepository = irepository; //完成映射的创建 ProductMapping(); } //在调用构造函数的时候完成映射的创建 private void ProductMapping() { //从界面的DTO持久化领域对象 var mapin = Mapper.CreateMap<ProductDTO, Product>(); //指定属性的对应关系 mapin.ConstructProjectionUsing(p => new Product { ProductName = p.Name, Size = p.Size, Color = p.Color, Count = p.Amount, UnitPrice = p.UnitPrice, ProductCategory = new ProductCategory { Id = Guid.NewGuid(), CategoryName = p.PCategoryName, Description = p.PDescription } }); //返回界面的东西 var mapout = Mapper.CreateMap<Product, ProductDTO>(); mapout.ConstructProjectionUsing(p => new ProductDTO { Name = p.ProductName, Size = p.Size, Color = p.Color, UnitPrice = p.UnitPrice, PCategoryName = p.ProductCategory.CategoryName, PDescription = p.ProductCategory.Description, Amount = p.Count }); }
得到产品DTO 的方法:
/// <summary> /// 得到产品DTO /// </summary> /// <param name="productname"></param> /// <returns></returns> public Product GetProducyByName(string productname) { return irepository.GetByCondition(p => p.ProductName == productname) .FirstOrDefault(); }
通过DTO 创建Product:
/// <summary> /// 通过DTOCreate /// </summary> /// <param name="productdto"></param> public void CreateProduct(ProductDTO productdto) { productdto.Id = Guid.NewGuid(); irepository.Create(productdto); }
服务 DTO 的创建:
/// <summary> /// 服务DTO的创建 /// </summary> /// <param name="productdto"></param> public void Createproduct(ProductDTO productdto) { product.CreateProduct(productdto); context.Commit(); }
/// <summary>
/// DTO的查询
/// </summary>
/// <param name="productname"></param>
/// <returns></returns>
public ProductDTO GetProductDTOByName(string productname)
{
return product.GetProductDTOByName(productname);
}
通过DTO创建测试:
[TestMethod] public void CreateProduct() { //Product product = new Product(new ProductRepository()); ProductAppService product = new ProductAppService(); //product.CreateProduct("P1", "Red", "Small", 100, 55, "C1", "T恤类产品"); //product.CreateProduct("P2", "Green", "Big", 200, 40, "C2", "运动类产品"); ProductDTO productdto = new ProductDTO(); productdto.Name = "P3"; productdto.Color = "Blue"; productdto.Size = "Middle"; productdto.Amount = 5000; productdto.UnitPrice = 10; productdto.PCategoryName = "C3"; productdto.PDescription = "正装"; product.Createproduct(productdto); context.Commit(); Assert.IsNotNull(product.GetProductByName("P3")); } [TestMethod] public void GetproductDTOByName() { ProductAppService productappservice = new ProductAppService(); var productdto = productappservice.GetProductDTOByName("P3"); Assert.AreEqual("P3", productdto.Name); Assert.AreEqual("C3", productdto.PCategoryName); }