I have the need for an object to object mapper in my application. I've tried out a few, but haven't been able to find anything that fits my needs, so I'm writing my own. Currently I have an interface like below:
public interface IMapper<T, R> {
T Map(R obj);
}
I then implement an AccountMapper that maps a Customer to an Account as:
public class AccountMapper : IMapper<Account, Customer> {
Account Map(Customer obj) {
// mapping code
}
}
This works fine so far, however I have several source entities that map to the same destination entity. For instance I have a Payment and an Invoice that both map to BillHistory. For the above to support this, I need to make two separate mappers (ie. BillHistoryPaymentMapper and BillHistoryInvoiceMapper), which is fine. However, I'd love to be able to implement it slightly differently like below. Only problem is I don't know if it's possible and if so, I don't know the correct syntax.
public interface IMapper<T> {
T Map<R>(R obj);
}
public class BillHistoryMapper : IMapper<Account> {
public BillHistory Map<Invoice>(Invoice obj) {
// mapping code
}
public BillHistory Map<Payment>(Payment obj) {
// mapping code
}
}
While the first implementation works fine, the second would be slightly more elegant. Is this possible and if so what would the correct syntax look like?
edit-------
I hate when people do this, but of course I forgot to mention one little detail. We have an abstract class between the mapper and the interface to implement some common logic across all of the mappers. So my mapper signature is actually:
public class BillHistoryMapper : Mapper<BillHistory, Invoice> {
}
where Mapper contains:
public abstract class Mapper<T, R> : IMapper<T, R> {
public IList<T> Map(IList<R> objList) {
return objList.ToList<R>().ConvertAll<T>(new Converter<T, R>(Map));
}
}
You'll have to use your first interface and implement the interface multiple times on your object:
public class BillHistoryMapper : IMapper<Account, Invoice>,
IMapper<Account, Payment> {
...
}
I would serious consider taking a look at AutoMapper instead of writing your own. There are a lot of nuances in mapping that it has already solved, not to mention it has been through plenty of performance testing, bug fixes, etc.