You can achieve mapping by manual mapping ( mapping each property by writing code ) or you can use a third party library. Actually , manual mapping ( mapping each property by writing code ) is the safest way. As in performance terms, it is the fastest way to achieve mapping moreover code is easy to understand and easy to maintain. As disadvantage your code gets bloated as following;
customerDto.Balance = customer.Balance;
customerDto.BirthDate = customer.BirthDate;
customerDto.City = customer.Address.City;
customerDto.District = customer.Address.District;
customerDto.DoorNo = customer.Address.DoorNo;
...
...
If your project requires massive property mapping , a third party might ease up your development stage and you can do mapping by writing a few lines of code. This is basically the advantage you get. You achieve mapping by writing a few lines of code ( suppose both destination and source class has same properties).
There are a few disadvantages such as performance and maintenance. First of all, adding a third party library makes maintenance more difficult since you will probably add some custom mapping rules and the library you use might have bugs that are hard to maintain. Secondly, as expected, it will work slower than manual mapping.
So far in my projects I've used Automapper I can tell, I am not really pleased with it. Firstly, its usage has changed a lot as they published new versions. Secondly , its performance is really poor.
Recently , I've seen another mapping library Fastmapper. Which is quite easy to use with its fluent api design and its performance is very close to manual mapping. In terms of feature , it is not as rich as Automapper , but it works fine for simple property mapping. And in most of the applications, that is all you need.
I've created a performance benchmark project to see the result myself;
Here is the result ;
Actually, you will probably never map 100.000 objects from one to another in an enterprise application. It is a very rare case. Yet still, you should be aware of performance of the tool/API/framework/library you are using.
Here's the source code of the performance test project ;
//Customer Class
public class Customer
{
public int Id { get; set; }
public decimal Balance { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public DateTime BirthDate { get; set; }
public AddressInfo Address { get; set; }
public List Accounts { get; set; }
public Customer()
{
this.Address = new AddressInfo();
}
}
public struct Account
{
public int BankCode { get; set; }
public int BranchCode { get; set; }
public int Number { get; set; }
public int AccountPostFix { get; set; }
public override string ToString()
{
return string.Format("{0}-{1}-{2}-{3}", BankCode, BranchCode,
Number, AccountPostFix);
}
}
public class AddressInfo
{
public string City { get; set; }
public string District { get; set; }
public string Street { get; set; }
public int DoorNo { get; set; }
public int ZipCode { get; set; }
}
//CustomerDTO Class
public class CustomerDto
{
public int Id { get; set; }
public decimal Balance { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public DateTime BirthDate { get; set; }
public string City { get; set; }
public string District { get; set; }
public string Street { get; set; }
public int DoorNo { get; set; }
public int ZipCode { get; set; }
public List Accounts { get; set; }
public static implicit operator CustomerDto(Customer customer)
{
CustomerDto customerDto = new CustomerDto();
customerDto.Accounts = new List();
foreach (Account account in customer.Accounts)
customerDto.Accounts.Add(account.ToString());
customerDto.Balance = customer.Balance;
customerDto.BirthDate = customer.BirthDate;
customerDto.City = customer.Address.City;
customerDto.District = customer.Address.District;
customerDto.DoorNo = customer.Address.DoorNo;
customerDto.Id = customer.Id;
customerDto.Name = customer.Name;
customerDto.Street = customer.Address.Street;
customerDto.Surname = customer.Surname;
customerDto.ZipCode = customer.Address.ZipCode;
return customerDto;
}
}
...
...
//Manual Mapping
CustomerDto customerDto = new CustomerDto();
customerDto.Accounts = new List();
foreach (Account account in customer.Accounts)
customerDto.Accounts.Add(account.ToString());
customerDto.Balance = customer.Balance;
customerDto.BirthDate = customer.BirthDate;
customerDto.City = customer.Address.City;
customerDto.District = customer.Address.District;
customerDto.DoorNo = customer.Address.DoorNo;
customerDto.Id = customer.Id;
customerDto.Name = customer.Name;
customerDto.Street = customer.Address.Street;
customerDto.Surname = customer.Surname;
customerDto.ZipCode = customer.Address.ZipCode;
//Using Automapper
var config = new MapperConfiguration(cfg => cfg.CreateMap()
.ForMember(dest => dest.City, opt => opt.MapFrom(src => src.Address.City))
.ForMember(dest => dest.District, opt => opt.MapFrom(src => src.Address.District))
.ForMember(dest => dest.DoorNo, opt => opt.MapFrom(src => src.Address.DoorNo))
.ForMember(dest => dest.ZipCode, opt => opt.MapFrom(src => src.Address.ZipCode))
.ForMember(dest => dest.Street, opt => opt.MapFrom(src => src.Address.Street)));
var mapper = config.CreateMapper();
...
...
CustomerDto customerDto = mapper.Map(customer);
...
//Using FastMapper
TypeAdapterConfig
.NewConfig()
.MapFrom(dest => dest.City, src => src.Address.City)
.MapFrom(dest => dest.District, src => src.Address.District)
.MapFrom(dest => dest.DoorNo, src => src.Address.DoorNo)
.MapFrom(dest => dest.ZipCode, src => src.Address.ZipCode)
.MapFrom(dest => dest.Street, src => src.Address.Street);
...
...
CustomerDto customerDto = TypeAdapter.Adapt(customer);
...
..
Regards,
No comments:
Post a Comment