Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression bug - works on 7.3.0 not on 7.4.0 #672

Open
FaustoNascimento opened this issue Jan 29, 2024 · 4 comments
Open

Regression bug - works on 7.3.0 not on 7.4.0 #672

FaustoNascimento opened this issue Jan 29, 2024 · 4 comments

Comments

@FaustoNascimento
Copy link

FaustoNascimento commented Jan 29, 2024

I found some pretty weird behaviour with Mapster 7.4.0...

Imagine you have the following DTOs:

public class Source
{
    public long Id { get; init; }
}

public class ADestination
{
    public int Id { get; init; }
}

public class BDestination : ADestination
{
    public new long Id { get; init; }
}

With no configuration at all, Mapster should be able to map between these two types and it can... but only depending on how it's invoked:

var source = new Source();
source.Adapt<BDestination>(); // this works
source.Adapt(new BDestination()); // this throws a AmbiguousMatchException exception

To make things worse ... if your DTOs are not as simple as this example and you use DI/IoC and you combine this with TypeAdapterConfig<Source, BDestination>.NewConfig().ConstructUsing() then the results are again unexpected depending on the Expression passed:

using Microsoft.Extensions.DependencyInjection;

var serviceProvider = new ServiceCollection().AddTransient<BDestination>().BuildServiceProvider();

// Obviously use *one* of the configurations below only

// Works if configured this way (only when doing Adapt<BDestination>() though!!)
TypeAdapterConfig<Source, BDestination>.NewConfig().ConstructUsing(_ => new BDestination());

// Does not work with this configuration - no matter what I try
TypeAdapterConfig<Source, BDestination>.NewConfig().ConstructUsing(_ => serviceProvider.GetRequiredService<BDestination>());

var source = new Source();
source.Adapt<BDestination>(); // Depending on configuration used, either Mapster will map successfully or throw AmbiguousMatchException  here

Any ideas what's going on and any potential workarounds?

@FaustoNascimento
Copy link
Author

I've also tried it with DryIoC with the following registration:

var container = new Container();

container.Register<BDestination>();
TypeAdapterConfig<Source, BDestination>.NewConfig().ConstructUsing(_ => container.Resolve<BDestination>(IfUnresolved.Throw));

var source = new Source();
source.Adapt<BDestination>();

But this also fails with the same error - although I swear I had it working with DryIoC before...

@FaustoNascimento
Copy link
Author

Ok cause I was really certain that this worked before with DryIoC and the only other thing I could think of was that I updated Mapster... I decided to go back to 7.3.0 and that works so this looks a regression bug?

@FaustoNascimento FaustoNascimento changed the title Mapping issues with DI and AmbiguousMatchException - inconsistent results - bug? Regression bug - works on 7.3.0 not on 7.4.0 Jan 29, 2024
@DocSvartz
Copy link

Hello @andrerav . This remains current given changes to the code from the development branch.

From development branch code it works without error if destination is Record Types .
Looks like there is a bug somewhere in the update mechanism Init Property in the СlassAdapter.
But I haven't done any research on this issue yet.

Hello @FaustoNascimento.
The value from the source is mapped to both parent and child properties is this expected behavior?

Yes, these are slightly different mapping methods.

source.Adapt<BDestination>(); // this сreating a new Instance  BDestination and field value from source
source.Adapt(new BDestination())  // this update current instance  BDestination value from source (from Class);

DocSvartz added a commit to DocSvartz/Mapster that referenced this issue Jan 4, 2025
@DocSvartz
Copy link

DocSvartz commented Jan 4, 2025

fixed it in #753

For DI/IoC no testing was conducted.

upd:
The fix works even if you redefine the field with the same type. I thought it wouldn't work))

class BDestination : ADestination
{
    public new int Id { get; init; }
}

But in this case, only the redefined property is updated, unlike the original case.

This question remains relevant:

The value from the source is mapped to both parent and child properties is this expected behavior?

issue672

If this was not expected, then this is an independent bug.

andrerav added a commit that referenced this issue Jan 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants