Mapster là một thư viện ánh xạ đối tượng (object-to-object mapping) mã nguồn mở, hiệu suất cao dành cho .NET, được tạo ra bởi Albert Huang. Nó giúp sao chép dữ liệu từ kiểu đối tượng này sang kiểu đối tượng khác (ví dụ: DTO sang Entity) một cách gọn nhẹ, nhanh chóng, thường được dùng thay thế cho AutoMapper.
Cài đặt Mapster
Bước đầu tiên là cài đặt package Mapster thông qua NuGet Package Manager Console:
Install-Package Mapster
Chuẩn bị môi trường (Model & DTO)
Giả sử chúng ta có các class thực thể (Entities) và một class DTO (Data Transfer Object) để hứng dữ liệu:public class Person
{
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string PostCode { get; set; }
public string Country { get; set; }
}
public class PersonDto
{
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
}
Lưu ý: Vì các thuộc tính trong PersonDto trùng tên với Person, Mapster sẽ tự động khớp chúng mà không cần cấu hình thêm.
Person Controller
public class PersonController : Controller
{
public ActionResult Index()
{
// Create sample Person data
var person = new Person
{
Title = "Mr.",
FirstName = "John",
LastName = "Doe",
DateOfBirth = new DateTime(1990, 5, 15),
Address = new Address
{
Street = "123 Main Street",
City = "New York",
PostCode = "10001",
Country = "USA"
}
};
// Manual mapping from Person to PersonDto
var personDto = new PersonDto
{
Title = person.Title,
FirstName = person.FirstName,
LastName = person.LastName,
DateOfBirth = person.DateOfBirth
};
return View(personDto);
}
}
Person Index View
@model MapsterSample.Models.PersonDto
@{
ViewBag.Title = "Person Details";
}
<h2>Person Information</h2>
<div class="form-group">
<label>Title:</label>
<p>@Model.Title</p>
</div>
<div class="form-group">
<label>First Name:</label>
<p>@Model.FirstName</p>
</div>
<div class="form-group">
<label>Last Name:</label>
<p>@Model.LastName</p>
</div>
<div class="form-group">
<label>Date of Birth:</label>
<p>@(Model.DateOfBirth?.ToString("yyyy-MM-dd") ?? "N/A")</p>
</div>
<div>
@Html.ActionLink("Back to Home", "Index", "Home", new { @class = "btn btn-primary" })
</div>
Chuyển đổi sang Mapster
Chúng ta dựa vào flow[Entity] ───► [Mapster] ───► [DTO/ViewModel]
| |
Database UI / APIMapster đứng giữa, làm nhiệm vụ:
- Copy dữ liệu
- Biến đổi dữ liệu nếu cần
Mapping cùng tên, cùng kiểu
Before mapping:
var personDto = new PersonDto
{
Title = person.Title,
FirstName = person.FirstName,
LastName = person.LastName,
DateOfBirth = person.DateOfBirth
};
After (Mapster):
var personDto = person.Adapt<PersonDto>();👉 Rule:
Trùng tên → auto map
Trùng kiểu → auto map
📌 Ghi nhớ:
“Cùng tên – cùng kiểu → Mapster tự lo”
Mapping khác tên
Định nghĩa Product Modelpublic class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public decimal ProductPrice { get; set; }
public string Description { get; set; }
public DateTime CreatedDate { get; set; }
}
public class ProductViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
public DateTime CreatedDate { get; set; }
}
Controller
public class ProductController : Controller
{
public ActionResult Index()
{
var product = new Product
{
ProductId = 1,
ProductName = "Laptop Dell XPS 13",
ProductPrice = 999.99m,
Description = "High-performance ultrabook",
CreatedDate = DateTime.Now
};
// Mapping: ProductId => Id, ProductName => Name, ProductPrice => Price
var productViewModel = product.Adapt<ProductViewModel>();
return View(productViewModel);
}
public ActionResult Edit(int id)
{
var product = new Product
{
ProductId = id,
ProductName = "Product " + id,
ProductPrice = 100m,
Description = "Sample product",
CreatedDate = DateTime.Now
};
var viewModel = product.Adapt<ProductViewModel>();
return View(viewModel);
}
[HttpPost]
public ActionResult Edit(int id, ProductViewModel viewModel)
{
var product = viewModel.Adapt<Product>();
product.ProductId = id;
// _repository.Save(product);
return RedirectToAction("Index");
}
}
Config Mapping
public static class MappingConfiguration
{
public static void Configure()
{
TypeAdapterConfig<Product, ProductViewModel>
.NewConfig()
.Map(dest => dest.Id, src => src.ProductId) // ProductId => Id
.Map(dest => dest.Name, src => src.ProductName) // ProductName => Name
.Map(dest => dest.Price, src => src.ProductPrice) // ProductPrice => Price
.Compile();
// Config reverse mapping ProductViewModel => Product
TypeAdapterConfig<ProductViewModel, Product>
.NewConfig()
.Map(dest => dest.ProductId, src => src.Id)
.Map(dest => dest.ProductName, src => src.Name)
.Map(dest => dest.ProductPrice, src => src.Price)
.Compile();
}
}Giải thích:
- .Map() - định nghĩa quy tắc ánh xạ
- dest => dest.Id - property đích (ProductViewModel)
- src => src.ProductId - property nguồn (Product)
- .Compile() - tối ưu hóa performance (quan trọng!)
Global.cs
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// Config Mapster mappings
MappingConfiguration.Configure();
}
}
Nhận xét
Đăng nhận xét