AutoMapper Kullanımı
Merhaba, bu yazımda ViewModel ile Entity eşleştirmesini başarılı bir şekilde yapan AutoMapper kütüphanesini inceleyeceğiz.
Kısaca ViewModel’den bahsetmek gerekirse
Sadece ekranda gözükecek yada işimize yarayan propertylerden oluşan bir sınıf…
Automapper bu noktada entitiy ile viewmodel arasındaki transferi gerçekleştiriyor. Bir örnek üzerinden nasıl çalıştığını anlayalım.
Kitap ve Yazar adında iki tane entity’imiz olsun
1 2 3 4 5 6 7 8 9 10 |
public class Book { public int Id { get; set; } public string Title { get; set; } public int AuthorId { get; set; } public int PageSize { get; set; } public string PublishingHouse{ get; set; } public int ISBN { get; set; } public virtual Author Author { get; set; } } |
1 2 3 4 5 6 |
public class Author { public int Id { get; set; } public string Name { get; set; } public string Surname { get; set; } } |
Kitap ekleme sayfasında Book entity’sinin Id ve AuthorId özelliklerine gerek yok ve ekleyeceğimiz kitabın yazar adı gerekli Bunun için bir ViewModel oluşturalım
1 2 3 4 5 6 7 8 |
public class HomeIndexViewModel { public string Title { get; set; } public int AuthorName { get; set; } public int PageSize { get; set; } public string PublishingHouse { get; set; } public int ISBN { get; set; } } |
ViewModel oluştururken SOLID prensiplerine bağlı kalalım yukarıda oluşturduğumuz ViewModel’i sadece Home Controller’daki Index Action’ında kullanalım.
Controller kısmında mapper olmadan şöyle yapıyorduk:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(HomeIndexViewModel vm) { var Book = new Book() { ISBN = vm.ISBN, PageSize = vm.PageSize, YayınEvi = vm.PublishingHouse, Title = vm.Title }; using (ApplicationDbContext db = new ApplicationDbContext()) { db.Books.Add(Book); db.SaveChanges(); } return RedirectToAction("Index"); } |
Mapper yapmak için AutoMapper(sürümü 10) ve AutoFacMvc5 paketlerini nuget üzerinden kuralım
AutoMapper 10’da; api’ya statik üzerinden erişimi kaldırdı dependecy injection kullanarak mapper’ı kullanacağız.
MapperProfile adında bir sınıf oluşturup Profile’dan miras alalım
1 2 3 4 5 6 7 |
public class MapperProfile:Profile { public MapperProfile() { CreateMap<HomeIndexViewModel, Book>().ForMember(dest=>dest.YayınEvi, opt=>opt.MapFrom(src=>src.PublishingHouse)); } } |
CreateMap içine iki adet parametre alıyor <TSource,TDestination> yani ilkine verilerimizin geldiği türü diğerini de dönüşüm yapmak istediğimiz türü yazacağız. Bu kısımda isimleri her iki türde de aynı olanları otomatik eşleştirip aktaracaktır isim farklılığı olanlar için ise ForMember extensionını kullanacağız.
Config yapıp globalasax.cs’de de register yapmalıyız. Bunun için ContainerConfig adında statik bir sınıf oluşturalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public static class ContainerConfig { public static void RegisterObjects() { var builder = new ContainerBuilder(); builder.RegisterControllers(typeof(MvcApplication).Assembly); builder.Register(context => new MapperConfiguration(cfg => { cfg.AddProfile<MapperProfile>(); })).AsSelf().SingleInstance(); builder.Register(c => { var context = c.Resolve<IComponentContext>(); var config = context.Resolve<MapperConfiguration>(); return config.CreateMapper(context.Resolve); }) .As<IMapper>() .InstancePerLifetimeScope(); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); } } |
Globalasax.cs:
1 2 3 4 5 6 |
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); ContainerConfig.RegisterObjects(); } |
Bu işlemleri bitirdikten sonra sadece uygulamak kalıyor.
1 2 3 4 5 |
public IMapper _mapper; public BookController(IMapper mapper) { _mapper = mapper; } |
1 2 3 4 5 6 7 8 9 10 11 |
[HttpPost] public ActionResult Create(HomeIndexViewModel vm) { var book = _mapper.Map<Book>(vm); using (ApplicationDbContext db = new ApplicationDbContext()) { db.Books.Add(book); db.SaveChanges(); } return RedirectToAction("Index"); } |
Şu an daha temiz bir kod ve iyi bir performans elde ettik.