Map constant value to properties and constructor parameters
See original GitHub issueIs your feature request related to a problem? Please describe. If I have a target type that has a required property (or constructor parameter) and the source type does not have a matching property then I’m currently not able to use Mapperly to create the target object.
The only way to map such types right now is to use an object factory. But that results in ugly code because you need to initialize all required properties (or constructor parameters) in the object factory - even those that could be mapped from the source object. So this object factory might have many Xyz = default
or (even worse) Xyz = default!
assignments (or default
/default!
constructor parameter values).
Describe the solution you’d like
A new attribute like [MapperSetDefaultValue(nameof(SomeEntity.Id))]
that would instruct the source generator to assign default
to the property (or constructor parameter) given in that attribute.
Describe alternatives you’ve considered
A simpler solution that doesn’t need a new attribute might be possible: The existing MapperIgnoreTargetAttribute
could cause the source generator to assign default
if it is a required property (or constructor parameter).
A more complex but also more customizable way to do this would be a property like [MapperSetValue(nameof(SomeEntity.Id), 0)]
, so one where even non-default values could be supplied.
Additional context
I’m not sure how nullable warnings are handled in generated code, but if the target property is not nullable then the source generator might have to assign default!
. I’m not sure if this is a good idea. Maybe only allow this with an additional opt-in?
If one of the suggested new attributes is implemented: There could be a situation where a user applies the new attribute although a matching source property is available. Maybe it would be a good idea to show an analyzer warning (or even an error) in that case, unless the MapperIgnoreSourceAttribute
is used.
Related discussion: https://github.com/riok/mapperly/discussions/335
Issue Analytics
- State:
- Created a month ago
- Comments:7 (4 by maintainers)
Top GitHub Comments
I don’t think we need to make the attribute generic. We can just assume,
null
isdefault
for value types and it should work.Mapperly usually works on the semantic model and not on the syntax, that’s why it is not easily possible to tell whether
null
ordefault
was used (it shouldn’t matter here anyway). And we recently implemented syntax access when reading configuration attirbutes here.I don’t know how source generators work, but can’t you just take the
default
language token and place it in the generated code? Or to be more generic, take anything the user writes as attribute constructor parameter and copy the code as-is?If this is not possible, then I assume
default
alone wouldn’t work for anobject?
attribute constructor parameter because it is target typed? Butdefault(int)
should work, right?Maybe also consider making the new attribute generic? (Generic attributes are possible since c# 11)