Open mdarefull opened 8 years ago
Also, and I don't know if it's possible, an even better signature from the readability point of view (at least IMO) for the extension method is:
public static TN Map<TN>(this object source);
After all, if it works having the destination type as argument, we can get the actual type of source:
var soureType = source.GetType();
I don't know the exact implementation details of your approach, sorry if I'm proposing non-senses. I just think that this approach would be a killer feature from the readability perspective, a very clean way to map objects, something I haven't seen before.
@mdarefull in the case of your example, instead of writing:
var viewModels = products.Map<IEnumerable<Product>, IEnumerable<ProductViewModel>>();
You can simply use the underlying types:
var viewModels = products.Map<Product, ProductViewModel>();
So I don't think anything needs to change.
I also disagree that the signature of:
public static TN Map<TN>(this object source);
Is more readable than the existing signature of:
public static TN Map<T, TN>(this T source)
{
return Mapper.Map<T, TN>(source);
}
There are plenty of other reasons as to why the second approach is preferred, but that's for another day :)
I still think that:
var viewModels = products.Map<Product, ProductViewModel>();
is too redundant. But you have a point, it won't be a ground-breaker neither, it just feel weird having to specify the source type and keeps me awake at nights :)
For the second suggestion, yes, the method signature may be odd, but is its usage I'm referring to, after all, once you get used to it you'll never think about its signature again, but you'll be seeing all around your project something like:
var viewModels = Mapper.Map<ProductViewModel>(products);
Or even better:
var viewModels = products.Map().To<ProductViewModel>();
Just try to read it aloud. Well, I think I get too passionate and academic with this last one :)
My apologies @mdarefull I misunderstood what you were referring to. Yes the redundancy is confusing, especially coming from AutoMapper, but I'm not sure if that's just because I'm used to AutoMapper!
Thanks a lot @mdarefull! - Let me see what we can do with that as I agree with you.
@nickcoad I was checking your proposal of just using the underlying types:
var viewModels = products.Map<Product, ProductViewModel>();
And I think it is invalid, that's an extension method, so, the first type parameter should be the type of products which is IEnumerable
Some common characteristic I've seen on several mappers is that they are too verbose and very redundant. And actually, it has been the main reason behind how I found ExpressMapper, I was trying to look for some mapper easier to write, to read, less redundant.
For example, let's take this registration code:
Mapper.Register<Product, ProductViewModel>();
To perform a mapping from IEnumerable to IEnumerable, one nice way is:
var viewModels = products.Map<IEnumerable<Product>, IEnumerable<ProductViewModel>>();
As you can see, it is somewhat redundant, because we need to specify the source type and the destination type. Furthermore, if the source type is a collection, there's no point on specifying the destination type as a non-collection object.What about this approach for the above example?
var viewModels = products.Map(typeof(ProductViewModel))
In this case, I'm proposing several things: