Mapping subobjects whose types and names differ?

May 22, 2014 at 4:01 PM
Edited May 22, 2014 at 4:01 PM
Hello, I want to substitute FastMapper for Automapper and most of my scenarios are simple, but I'm running into an issue with the following case and need to know if FastMapper can handle this.

The issue I have is that it doesn’t look like it will map by convention for subobjects whose names and types don’t match. I could be wrong because I just started playing with it yesterday but I don’t see a way to do it at least. For example, it balks at the mapping below because it wants dest.AppliedDiscount to be the same type as src.Discount.Discount. They are in fact different types but they should be mappable by convention (or via configuration).
TypeAdapterConfig<Entities.Discounts.ShippingDiscount, ShippingDiscount>.NewConfig()
                  .MapFrom(dest => dest.Code, src => src.MethodCode)
                  .MapFrom(dest => dest.AppliedDiscount, src => src.Discount.Discount); //FastMapper doesn’t like this, it wants these types to match.  They have the same members but are different types
Coordinator
May 22, 2014 at 9:03 PM
Edited May 22, 2014 at 9:06 PM
Hi ericswann,

Please try to convert the same type,
   TypeAdapterConfig<Entities.Discounts.ShippingDiscount, ShippingDiscount>
   .NewConfig()
   .MapFrom(dest => dest.Code, src => src.MethodCode)
   .MapFrom(dest => dest.AppliedDiscount, src => (double)src.Discount.Discount);
or
   TypeAdapterConfig<Entities.Discounts.ShippingDiscount, ShippingDiscount>
   .NewConfig()
   .MapFrom(dest => dest.Code, src => src.MethodCode)
   .MapFrom(dest => dest.AppliedDiscount, src => Convert.ToDouble(src.Discount.Discount));
"double" is sample. convert to AppliedDiscount property type.

Thank you for your interest :)
May 22, 2014 at 9:21 PM
Edited May 22, 2014 at 9:49 PM
Ah, if only it were that easy in my case :) The problem I have is that AppliedDiscount and Discount are not primitives. They are themselves mapped types. Is it permissible or advisable to nest calls to the TypeAdapter inside of the TypeAdapterConfig? That's essentially what I'm trying to accomplish, something that would do an explicit nested conversion like the following (since it can't be inferred from the property name):
TypeAdapterConfig<Entities.Discounts.ShippingDiscount, ShippingDiscount>.NewConfig()
                  .MapFrom(dest => dest.Code, src => src.MethodCode)
                  .MapFrom(dest => dest.AppliedDiscount, src => TypeAdapter.Adapt<Entities.Discounts.Discount, AppliedDiscount>(src.Discount.Discount));
Is there some way to accomplish this? I haven't gotten to the point where I can test if this would work. Is it advisable for the TypeAdapterConfig to reference the TypeAdapter?

Here is another specific example. In this case I have two child objects that should be mappable, but due to their different names, they won't match up. Object A has Parent, Object B has ParentCategory (this is just a nested object structure).
So FastMapper doesn't like:
TypeAdapterConfig<ProductRuntime.Contracts.Category, Category>.NewConfig()
                .MapFrom(dest => dest.Id, src => src.CategoryId)
                **.MapFrom(dest => dest.Parent, src =>src.ParentCategory);**
The only thing I can think to do is the following, but again not sure if this is advisable.
TypeAdapterConfig<ProductRuntime.Contracts.Category, Category>.NewConfig()
                .MapFrom(dest => dest.Id, src => src.CategoryId)
                .MapFrom(dest => dest.Parent, src => TypeAdapter.Adapt<ProductRuntime.Contracts.Category, Category>(src.ParentCategory));
Coordinator
May 22, 2014 at 10:04 PM
Edited May 22, 2014 at 10:15 PM
Ah, I thought AppliedDiscount and Discount are primitives.
              TypeAdapterConfig<Entities.Discounts.ShippingDiscount, ShippingDiscount>.NewConfig()
              .MapFrom(dest => dest.Code, src => src.MethodCode)
              .MapFrom(dest => dest.AppliedDiscount, src => TypeAdapter.Adapt<Entities.Discounts.Discount, AppliedDiscount>(src.Discount.Discount));
this is true approach. It will work correctly.

If property names are same and property types are different, you don't need a configuration. FastMapper map properties automatically.
Coordinator
May 22, 2014 at 10:14 PM
Edited May 22, 2014 at 10:14 PM
It is true.
.MapFrom(dest => dest.Parent, src => TypeAdapter.Adapt<ProductRuntime.Contracts.Category, Category>(src.ParentCategory));
If I would not force to same type in MapFrom, FastMapper would use the same approach in the background.
May 22, 2014 at 10:22 PM
Sweet! Thanks for responding...I'll give it a shot and see what happens. I'm converting a ton of mappings from Automapper, mainly because we do a lot of conversions between services our performance testing shows Automapper to be eating up a lot of CPU and causing overall response latency under load. Hope this project will help.
Coordinator
May 22, 2014 at 10:36 PM
You are right.Automapper use slightly more resource because of reflection methods ( GetValue, SetValue ...etc. ).But FastMapper use "System.Reflection.Emit" library in the background.

Thanks again for your interest.