代码改变世界

使用AutoMapper

2018-04-10 10:48  蛮荒古神  阅读(230)  评论(0编辑  收藏  举报

到现在,确切的说,AutoMapper的安装使用非常非常的便捷,就如同傻瓜照相机那样。你只需要从Nuget上下载AutoMapper的包到你的应用程序里,然后添加对AutoMapper命名空间的引用,然后你就可以在你的项目里随意使用它了。以下就是一个非常简单的是例子:

 Mapper.Initialize(x => x.CreateMap<Book, BookViewModel>());

var model = AutoMapper.Mapper.Map<BookViewModel>(book);

 

使用AutoMappeer的好处是显而易见的,首先,不再需要我们去对DTO实例的属性一一赋值,然后无论你在Book对象或者BookViewModel对象里加了一个或者更多的字段,那都不会影响这个段映射的代码,我不再需要去找到每一处转换的地方去更改代码,你的程序会像之前正常运转。 
不过,还是有个问题并没有得到很好的解决,这也是在AutoMapper文档上缺失的,为把Book.Athor.Name字段赋值给BookViewModel.Author字段,需要在每一处需要执行映射的代码地方,同时创建一个如下的显示转换申明代码,所以如果有很多处转换的话,那么我们就会写很多重复的这几行代码:

  Mapper.Initialize(x => x.CreateMap<Book, BookViewModel>()

.ForMember(dest => dest.Author,

opts => opts.MapFrom(src => src.Author.Name)));

所以我们该如何正确的创建映射呢?方式有很多,我这边说下在ASP.NET MVC的程序里如何处理。 
在微软的ASP.NET MVC程序中,它提供了一个Global.asax文件,这个文件里可以放置一些全剧配置,上面对于把Book.Athor.Name字段赋值给BookViewModel.Author字段这个映射配置放置在这个文件里面,那么这段代码只会跑一次但是所有转换的地方都能正确的转换Book.Athor.Name为BookViewModel.Author。当然,Global.asax文件中不建议放很复杂的代码,因为这是ASP.NET程序的入口,一档这个文件里出错,那么整个程序就会over。配置代码可以以这样的形式写,创建一个AutoMapper的配置类:

 

public static class AutoMapperConfig

{

public static void RegisterMappings()

{

AutoMapper.Mapper.Initialize(x => x.CreateMap<Book, BookViewModel>()

.ForMember(dest => dest.Author,

opts => opts.MapFrom(src => src.Author.Name)));

}

}

然后再Global文件注册这个类:

 

protected override void Application_Start(object sender, EventArgs e)

{

AutoMapperConfig.RegisterMappings();

}

 范例

namespace AutoMapper
{
class Program
{
static void Main(string[] args)
{
//Address dto = new Address
//{
// Country = "China",
// City = "Beijing",
// Street = "Dongzhimen Street",
// PostCode = "100001"
//};
//Mapper.Initialize(x => x.CreateMap<AddressDto, Address>());

//AddressDto address = Mapper.Map<AddressDto>(dto);
//Console.WriteLine(address.Country);
//Console.WriteLine(address.City);
//Console.WriteLine(address.Street);
//Console.WriteLine(address.PostCode);

BookStoreDto dto = new BookStoreDto
{
Name = "My Store",
Address = new AddressDto
{
City = "Beijing"
},
Books = new List<BookDto>
{
new BookDto {Title = "RESTful Web Service"},
new BookDto {Title = "Ruby for Rails"},
}
};
Mapper.Initialize(x => x.CreateMap<BookDto, Book>().ForMember(bok => bok.Publisher/*(变量)*/,
map => map.MapFrom(dto1 => new Publisher() { Name = dto1.Publisher/*(DTO的变量)*/})));
//Mapper.Initialize(x => x.CreateMap<BookStoreDto, BookStore>());



;
BookStore bookStore = Mapper.Map<BookStoreDto, BookStore>(dto);
Console.WriteLine(bookStore.Name);
Console.WriteLine(bookStore.Address.City);
Console.WriteLine(bookStore.Books.Count);
Console.WriteLine(bookStore.Books.First().Title);
Console.WriteLine(bookStore.Books.Last().Title);
;
Console.ReadKey();
}
}
public class BookStore
{
public string Name { get; set; }
public List<Book> Books { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Country { get; set; }
public string City { get; set; }
public string Street { get; set; }
public string PostCode { get; set; }
}
public class Book
{
public string Title { get; set; }
public string Description { get; set; }
public string Language { get; set; }
public decimal Price { get; set; }
public List<Author> Authors { get; set; }
public DateTime? PublishDate { get; set; }
public Publisher Publisher { get; set; }
public int? Paperback { get; set; }
}
public class Author
{
public string Name { get; set; }
public string Description { get; set; }
public ContactInfo ContactInfo { get; set; }
}
public class Publisher
{
public string Name { get; set; }
}
public class ContactInfo
{
public string Email { get; set; }
public string Blog { get; set; }
public string Twitter { get; set; }
}
public class BookStoreDto
{
public string Name { get; set; }
public List<BookDto> Books { get; set; }
public AddressDto Address { get; set; }
}
public class AddressDto
{
public string Country { get; set; }
public string City { get; set; }
public string Street { get; set; }
public string PostCode { get; set; }
}
public class BookDto
{
public string Title { get; set; }
public string Description { get; set; }
public string Language { get; set; }
public decimal Price { get; set; }
public DateTime? PublishDate { get; set; }
public string Publisher { get; set; }
public int? Paperback { get; set; }
public string FirstAuthorName { get; set; }
public string FirstAuthorDescription { get; set; }
public string FirstAuthorEmail { get; set; }
public string FirstAuthorBlog { get; set; }
public string FirstAuthorTwitter { get; set; }
public string SecondAuthorName { get; set; }
public string SecondAuthorDescription { get; set; }
public string SecondAuthorEmail { get; set; }
public string SecondAuthorBlog { get; set; }
public string SecondAuthorTwitter { get; set; }
}
}