Mapster icon indicating copy to clipboard operation
Mapster copied to clipboard

Inheritance and scanning assembly for IRegister.

Open vchc opened this issue 1 year ago • 5 comments

If you use IRegister to define the inheritance mapping like this:

DerivedPocoProfile.cs

public class DerivedPocoProfile : IRegister
{
    public void Register(TypeAdapterConfig config)
    {
        .NewConfig<DerivedPoco, DerivedDto>()
        .Inherits<SimplePoco, SimpleDto>();
    }
}

SimplePocoProfile.cs

public class SimplePocoProfile : IRegister
{
    public void Register(TypeAdapterConfig config)
    {
        .NewConfig<SimplePoco, SimpleDto>();
    }
}

and then use scan assembly for types:

TypeAdapterConfig.GlobalSettings.Scan(typeof(DerivedPocoProfile).Assembly);

there is no guarantee that the base type will be registered first and

.Inherits<SimplePoco, SimpleDto>();

will fail silently, leaving your mapping inconsistent.

The current implementation of Inherits does nothing and simply returns when the type tuple has not yet been registered.

vchc avatar Sep 04 '24 13:09 vchc

Same problem here. Our current fix is to do all that manually, so we can guarantee a specific order of registration, but that is still error prone, and would be so much better if Inherits<,> would evaluate lazily.

Edit: we do not use TypeAdapterConfig.GlobalSettings.Scan - but have our own interface & scanner, so it's not a problem with TypeAdapterConfig.GlobalSettings.Scan

praschl avatar Nov 18 '24 08:11 praschl

Edit: we do not use TypeAdapterConfig.GlobalSettings.Scan - but have our own interface & scanner, so it's not a problem with TypeAdapterConfig.GlobalSettings.Scan

I came with the same solution for the problem - to reorder registrations manually.

And I think any assumptions on the library's part about the order or location of IRegister implementations may turn out to be wrong. So there is no simple way to handle this problem lazily.

There can be three ways to the universal solution:

  1. To chain registrations. Like .Inherits<DTOEntity, Entity>().WithRegistration(IRegister) which is somehow cumbersome.
  2. To use a new typed IRegister interface and to rewrite the scanner and handle the order of registrations with taking into account the inheritance hierarchy of the registering types.
  3. To handle registration in two steps. Collect all Configs for types. Execute them in reordered sequence based on the inheritance hierarchy. Something like this: DefaultConfig.Collect(First Assembly) DefaultConfig.Collect(Second Assembly) ... DefaultConfig.Register()

vchc avatar Nov 18 '24 13:11 vchc

Would love to see a solution to this as well.

MuTsunTsai avatar Jul 14 '25 07:07 MuTsunTsai

I have an idea how to do it in a lazy way, but then it will cause a performance drop of the first .Adapt() call: I see it like this:

  1. Inherits does not load settings, but adds to the config, indications of what needs to be loaded and the status of loaded - (not loaded).
  2. All IRegister are loaded in any order.
  3. The first Adapt call for types <DerivedPoco, DerivedDto> will load all configs of parent types - (loaded).

DocSvartz avatar Jul 14 '25 10:07 DocSvartz

It seems to work :) It remains to check that it works with all types of adapters.

Additional samples for testing are welcome :)

DocSvartz avatar Jul 14 '25 12:07 DocSvartz