1. 程式人生 > >NetCore+AutoMapper多個物件對映到一個Dto物件

NetCore+AutoMapper多個物件對映到一個Dto物件

 

目錄

一、定義源對映類和被對映類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