MapsterMapper / MapsterMapper/Mapster
Feat: more powerful Attribute-based configuration
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 5.2k
- Forks
- 410
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 6
Description
It would be nice if we could use attributes to define any (or most...) aspects of mapping -- and if we could derive our own attributes to do that.
### Use case
I want to be able to easily say, with an attribute, that a property is mapped only if another property has a specific value.
If I was doing this in code, it would be:
```cs
config.Map(target => target.Prop, src => src.Prop, src => src.Other == SentinelValue);
```
Instead, I wrote an attribute to configure this aspect:
```cs
class SourceDto
{
public string Other { get; set; }
[AdaptNullUnless(nameof(Other), SentinelValue)]
public string Prop { get; set; }
}
```
Of course, because this attribute is unknown to Mapster, I also had to create an `IRegister` implementation that configures those mappings automatically using reflection.
It would be nice if that last part was not required.
### Suggestion
Similar to other frameworks that use Attributes as an alternative configuration (I'm thinking Grace IoC here), maybe Mapster could provide a base attribute class:
```cs
// Provided my Mapster
abstract class MapsterPropertyAttribute : Attribute
{
public void abstract Map(PropertyInfo property, TypeAdapterSetter config);
}
```
Maspter would then find any attribute derived from `MapsterPropertyAttribute` when building a mapping and invoke `Map` on them.
With this, users could build their own attributes and apply them without any other discovery step.
My example use case would be entierly contained in this attribute:
```cs
public class AdaptNullUnlessAttribute : MapsterPropertyAttribute
{
private string other;
private object value;
public AdaptNullUnlessAttribute(string other, object value)
{
this.other = other;
this.value = value;
}
public override void Map(PropertyInfo prop, TypeAdapterSetter config)
{
config.Settings.Resolvers.Add(new InvokerModel
{
// This assumes same name, maybe Mapster should pass the config so far to this method,
// esp. the target name if AdaptMember was also used.
DestinationMemberName = p.Name,
SourceMemberName = p.Name,
Condition = Expression.Lambda(...), // Removed for conciseness
});
}
}
```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue names no repository files or tests. Start by tracing existing attribute handling and IRegister configuration around TypeAdapterSetter, PropertyInfo, and InvokerModel; done would mean a derived attribute can be discovered and affect a mapping without a separate registration step.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- developer-experience
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100