MapsterMapper / Mapster

A fast, fun and stimulating object to object Mapper
MIT License
4.32k stars 329 forks source link

Fix issue #524. Adding support for working with Types packed into an object to the standard adapter #645

Open DocSvartz opened 11 months ago

DocSvartz commented 11 months ago

Fix issue #524

Before:

if Type was packaged into an object:

object _source = new TSource()

Instead of updating with data from TSource, it was converted to the TDestination type

_source.Adapt(_destination) == _source.Adapt<TDistination>

DocSvartz commented 11 months ago

Seems like, It was simply necessary to apply an already developed solution. By adding it to a standard adapter. :)

DocSvartz commented 11 months ago

Hello @andrerav
It looks like the simplest and most correct solution would actually be to use the mechanism from the special overload of the Adapt Method. 1) In general, the Expression for an adapt is created based on the types of generic arguments. With this call, generation will always occur for the objecttype as a TSourceor TDestination. Since the generic method was called for them: Adapt<object,TDestination>(), Adapt<object,object>(), Adapt<TSource ,object> ( but not Adapt<TSource,TDestination>(). 2) The received conversion Adapt function is called with Runtime arguments (variables) passed for updating. But since the Adapt function has already been generated for the Objecttype, processing for it will occur as an Object.

Therefore, this is not exactly an ObjectAdapter problem, as I initially decided. You just need to initially generate the Adapt function for the Type Packed into an object ( TSource or TDestination )

3) Even to call a function dynamically, need to know the real type of the TSourcebefore calling them. Without this cannot create this:

var method = (from m in typeof(TypeAdapterConfig).GetMethods(BindingFlags.Instance | BindingFlags.Public)
    where m.Name == nameof(GetMapToTargetFunction)
    select m).First().MakeGenericMethod(sourceType, destinationType);

The main problem is the following: For this to work, need to capture the Runtime type of variables _source.GetType() _destination.GetType() somewhere and save them for subsequent construction of the Adapt function (Theory, maybe this won't work either).

DocSvartz commented 11 months ago

@andrerav It looks like now the work on the fix is really complete.

Update: I left the endless loop breaker in both places, for greater reliability - in ObjectAdapter this not required