- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Support generic user implemented mappings #451
Comments
Would a situation like this fall within what you are describing in this issue: [Fact]
public void WithGenericSourceTypeConstraintsAndUserImplemented()
{
var source = TestSourceBuilder.MapperWithBodyAndTypes(
"""
partial To Map(From source);
public OtherValue PickMeForAAndB<TSource>(TSource source)
where TSource : IValue => new OtherValue { Value = source.Value };
public OtherValue PickMeForIValue(IValue source) => new OtherValue { Value = source.Value };
""",
"public interface IValue { public string Value { get; } }",
"public class OtherValue { public string Value { get; set; } }",
"public class A: IValue{ public string Value {get; set;} }",
"public class B: IValue{ public string Value {get; set;} }",
"public class From { public A AV { get; set;} public B BV { get; set;} public IValue IV { get; set;} }",
"public class To { public OtherValue AV { get; set; } public OtherValue BV { get; set; } public OtherValue IV { get; set; } }"
);
TestHelper
.GenerateMapper(source)
.Should()
.HaveMapMethodBody(
"""
var target = new global::To();
target.AV = PickMeForAAndB(source.AV);
target.BV = PickMeForAAndB(source.BV);
target.IV = PickMeForIValue(source.IV);
return target;
"""
);
} |
@Fube that's the idea! |
Would it not be possible to implement this by modifying the I'm able to get that specific test case to pass with this (extremely hacky and specific) solution: public ITypeMapping? Find(ITypeSymbol sourceType, ITypeSymbol targetType)
{
_mappings.TryGetValue(new TypeMappingKey(sourceType, targetType), out var mapping);
if (mapping != null)
{
return mapping;
}
var sourceIndirectlyRegistered = _mappings
.Where(x => x.Key._target.Equals(targetType)) // _target and _source of TypeMappingKey were made public
.Select(x => (method: x.Key._source.ContainingSymbol as IMethodSymbol, kvp: x))
.Where(x => x.method is not null)
.Where(x =>
{
if (x.method?.TypeParameters[0].ConstraintTypes[0] is INamedTypeSymbol ns)
{
return sourceType.AllInterfaces.Any(y => SymbolEqualityComparer.Default.Equals(y, ns));
}
return false;
})
.SingleOrDefault();
return sourceIndirectlyRegistered.kvp.Value;
} I know there's a lot more to take into consideration, I'm just wondering if those things can be accounted for within |
@Fube I think this works for methods where the source is the only generic type argument (would definitely need some cleanup 😄). If the target is (also) generic, not only the lookup side, but also the syntax generation side needs to be adjusted as explicit specification of the generic type arguments is required. |
Yes, very much so 😅
Could you please go into more detail as to why that would be needed? My understanding of the codebase is too shallow to grasp that How would addressing this enhancement affect the bug described in issue #421? |
#421 occurred when Mapperly didn't have any support for generic methods, but still tried to call them. If a generic method was implemented by a user, Mapperly handled the generic type as any other type. Therefore it did type checks with // user implemented mapping method
TTarget Map<TSource, TTarget>(TSource source)
where TSource : IMyInterface
where TTarget : new(), IMyOtherInterface
=> new TTarget { MyValue = source.MyValue };
// would currently be called by Mapperly
var target = Map(source);
// instead of
var target = Map<MySource, MyTarget>(soruce); To support this, as you figured out, Mapperly needs to implement generic mapping support during the mapping resolution in |
Add support for user implemented generic mapping methods:
Mapperly should use the user implemented
MapOptional
method to mapDocument.ModifiedBy
toDocumentDto.ModifiedBy
.Depends on #357.
Discussed in #444.
The text was updated successfully, but these errors were encountered: