在Prism中可以使用反射进行模型映射,但是这种映射方式对Model和DTO中相同字段不同类型就无能为力了,或者需要复杂的处理才能达成目标。
使用AutoMapper进行模型映射就简单多了,但是其在Prism中的应用很少,在.Net环境下一般应用于Asp .Net Core居多。经过一番搜索和摸索,在“使用带有DI容器的AutoMapper实例化类型”这篇文章中受到启发,终于实现Prism环境中AutoMapper的使用了。
本文开发环境:VS2019 16.9.5,WPF(.NET 5.0),AutoMapper 10.1.1。
一、模型预设
public class Student { public int Id { get; set; } public string Name { get; set; } public bool? Gender { get; set; } public DateTime Birthday { get; set; } } public class StudentDto { public int Id { get; set; } public string Name { get; set; } public string Birthday { get; set; } }
二、使用反射
还是介绍下使用反射进行模型映射的方法,主要是遍历被转换的模型的属性,获取转换后模型的属性,并对其进行赋值。
public static StudentDto GetStudentDtoByReflection(Student student) { var studentDto = new StudentDto(); var studentDtoType = typeof(StudentDto); var studentType = typeof(Student); var properties = studentType.GetProperties(); foreach (var property in properties) { var propertyInfo = studentDtoType.GetProperty(property.Name); propertyInfo?.SetValue(studentDto, property.GetValue(student)); } return studentDto; }
三、使用AutoMapper
在AutoMapper中需要使用MapperConfiguration进行配置,然后通过该类的对象获取IMapper对象,最后才能进行模型映射。
1、创建Profile
public class StudentProfile : Profile { public StudentProfile() { CreateMap<Student, StudentDto>() .ForMember( dest => dest.Birthday, opt => opt.MapFrom(src => $@"{src.Birthday:yyyy-MM-dd HH:mm:ss}") ); } }
2、封装MapperConfiguration
封装MapperConfiguration,对外提供IMapper对象。
public interface IAutoMapperProvider { IMapper GetMapper(); } public class AutoMapperProvider : IAutoMapperProvider { private readonly MapperConfiguration _configuration; public AutoMapperProvider(IContainerProvider container) { _configuration = new MapperConfiguration(configure => { configure.ConstructServicesUsing(container.Resolve); //扫描profile文件 configure.AddMaps(AppDomain.CurrentDomain.GetAssemblies()); }); } public IMapper GetMapper() { return _configuration.CreateMapper(); } }
3、注入IOC容器
将IAutoMapperProvider注入IOC容器,并对外提供IMapper注入类型。
protected override void RegisterTypes(IContainerRegistry containerRegistry) { //注册AutoMapper containerRegistry.RegisterSingleton<IAutoMapperProvider, AutoMapperProvider>(); containerRegistry.Register(typeof(IMapper), GetMapper); } private IMapper GetMapper(IContainerProvider container) { var provider = container.Resolve<IAutoMapperProvider>(); return provider.GetMapper(); }
4、使用AutoMapper
通过依赖注入,使用IMapper进行模型映射。
public class TestViewModel : BindableBase { private readonly IMapper _mapper; public TestViewModel(IMapper mapper) { _container = container; } }
方法1,映射单个对象。
private StudentDto GetStudentDtoByAutoMapper(Student student) { return _mapper.Map<StudentDto>(student); }
方法2,映射集合。
var studentDtoList = _mapper.Map<IList<Student>, IList<StudentDto>>(studentList);