NetCore+AutoMapper多個對象映射到一個Dto對象

  • 2019 年 10 月 3 日
  • 筆記

 

目錄

一、定義源映射類和被映射類DTO

二、注入AutoMapper

三、配置映射

四、調用AutoMapper完成賦值

五、運行測試

 

一、定義源映射對象

為了體現AutoMapper映射特性,在SocialAttribute中的Name屬性沒有定義在People中,People的Ear屬性也不存在與SocialAttribute和PhysicalAttribute中。

 

 

 程式碼如下:

    /// <summary>      /// 身體屬性      /// </summary>      public class PhysicalAttribute      {          public string Eye { get; set; }          public string Mouth { get; set; }      }

PhysicalAttribute

    /// <summary>      /// 社會屬性      /// </summary>      public class SocialAttribute      {          public int Age { get; set; }          public bool IsMarried { get; set; }          public string Name { get; set; }      }

SocialAttribute

    public class PeopleDto      {          public string Eye { get; set; }          public string Mouth { get; set; }          public string Ear { get; set; }          public int Age { get; set; }          public bool IsMarried { get; set; }      }

PeopleDto

 

二、注入AutoMapper

例子中使用的IOC容器是Autofac,不使用Autofac的話,僅用NetCore框架集成的IOC容器也可以實現。

註冊AutoMapper必要組件:

    public static class AutoMapperInjection      {          public static ContainerBuilder LoadAutoMapper(this ContainerBuilder builder)          {              builder.RegisterType<MapperConfigurationExpression>().SingleInstance();              builder.Register(m => {                  var mapperConfigurationExpression = m.Resolve<MapperConfigurationExpression>();                  var instance = new MapperConfiguration(mapperConfigurationExpression);                  return instance;              });              builder.Register(m => {                  var mapperConfiguration = m.Resolve<MapperConfiguration>();                  return mapperConfiguration.CreateMapper();              });              return builder;            }      }

 

三、配置映射

ForMember:映射兩個類之間的屬性關係。

People類中的Ear屬性並不存在於任何映射源類中,我們可以使用ForMember(m => m.Ear, n => n.Ignore())忽略該屬性,當然也可以不寫這段程式碼,對AutoMapper不會有任何影響,但是為了後期維護更方便,我比較習慣將Dto類的屬性寫全。

SocialAttribute類中的Name屬性不存在與People類中,直接忽略它,Name也不會被AutoMapper賦值。

    public class AutoMapperProfile: Profile      {          public void Mapping(ILifetimeScope scope) {                var expression = scope.Resolve<MapperConfigurationExpression>();              expression.CreateMap<PhysicalAttribute, PeopleDto>()              .ForMember(m => m.Eye, n => n.MapFrom(s => s.Eye))              .ForMember(m => m.Mouth, n => n.MapFrom(s => s.Mouth));              //.ForMember(m => m.Ear, n => n.Ignore());              expression.CreateMap<SocialAttribute, PeopleDto>()                  .ForMember(m => m.Age, n => n.MapFrom(s => s.Age))                  .ForMember(m => m.IsMarried, n => n.MapFrom(s => s.IsMarried));          }      }

四、調用AutoMapper完成賦值

調用AutoMapper,將PhysicalAttribute和SocialAttribute的值賦給PeopleDto

    public class DtoHelper      {          private IMapper mapper;          public DtoHelper(IMapper _mapper) {              mapper = _mapper;          }          public PeopleDto GetDto(PhysicalAttribute physical,SocialAttribute social) {              PeopleDto peopleDto = new PeopleDto();              mapper.Map(social, mapper.Map(physical, peopleDto));              return peopleDto;          }      }

 

五、運行測試

測試框架使用的xUnit

    public class DtoHelperTest      {          [Fact]          public void GetDto() {              //moke              ContainerBuilder builder = new ContainerBuilder();              builder.LoadAutoMapper();              builder.RegisterType<AutoMapperProfile>();              IContainer Container = builder.Build();              using (var scope = Container.BeginLifetimeScope())              {                  scope.Resolve<AutoMapperProfile>().Mapping(scope);                  PeopleDto result = new PeopleDto() { Eye = "雙眼皮", Mouth = "紅潤", Age = 18, IsMarried = false };                  PhysicalAttribute physical = new PhysicalAttribute() { Eye = "雙眼皮", Mouth = "紅潤" };                  SocialAttribute social = new SocialAttribute() { Name = "張三", IsMarried = false, Age = 18 };                  PeopleDto output = new DtoHelper(scope.Resolve<IMapper>()).GetDto(physical, social);                  //Assert.Same(result, output);                  Assert.Equal(JsonConvert.SerializeObject(result), JsonConvert.SerializeObject(output));              }            }      }

通過測試!

 

 參考項目:https://github.com/FB208/CodeSpace/tree/master/CodeSpace.CSharp/WebMvc/DemoClass/AutoMapperDemo