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

Add support for mapping private and protected members #531

Closed
myth384 opened this issue Jun 30, 2023 · 7 comments
Closed

Add support for mapping private and protected members #531

myth384 opened this issue Jun 30, 2023 · 7 comments

Comments

@myth384
Copy link

myth384 commented Jun 30, 2023

Is your feature request related to a problem? Please describe.
Currently it is not possible to map private and protected class members. When applying DDD principles, child entities of aggregates need to be as much encapsulated to the domain as possible, while the repository for the aggregate should be able to map those members to DTO's.

Describe the solution you'd like
The abbility to map private and protected members. For example by using a [MapPrivateMembers] attribute fot that member.

Describe alternatives you've considered
For the moment I'm planning to use Automapper or writing manual mappers.

Additional context
N.A.

@CommonGuy
Copy link
Contributor

Could you show an example of a simple manual mapping that maps private/protected fields? I presume you are doing it via reflection? I don't think Mapperly will ever support mappings via reflection, as this is out of scope of the project.

@myth384
Copy link
Author

myth384 commented Jun 30, 2023

I don't have a concrete example right now, but if I were to implement a manual mapping, I would likely utilize reflection. I believe AutoMapper, also employs reflection for its functionality.

Another approach that could be considered is using inheritance to access protected members, similar to how NHibernate operates. However, this approach does impose specific accessibility requirements on the input classes. Nevertheless, I find it preferable to making every member that needs to be mapped publicly accessible.

@latonz
Copy link
Contributor

latonz commented Jul 5, 2023

Mapperly will not use Reflection as this would conflict with Mapperly's goals of generating AoT safe, fast and easy to read code.
If you have a concrete example where this could be helpful, please feel free to comment on this issue as there may be another solution for such a use-case than reflection.

@latonz latonz closed this as completed Jul 5, 2023
@myth384
Copy link
Author

myth384 commented Jul 5, 2023

Thank you for your reply, Latonz.

I appreciate your response. In my initial request, I provided a specific example that involved the Domain-Driven Design (DDD) architecture. Generally, it is recommended that child entities within an aggregate should not be exposed outside of the aggregate. If you're referring to a code example, please let me know.

I understand that you aim to avoid using Reflection and rely solely on Code Generation, which aligns with the concept behind Mapperly. One approach to achieve this could be through the use of proxy classes that inherit the class-to-map. However, it's important to note that private members cannot be supported by this technique. Nonetheless, using protected accessibility instead of public is already a significant improvement in terms of encapsulating child entities.

Please let me know if there's anything else you would like to discuss or if you have any further questions.

@latonz
Copy link
Contributor

latonz commented Jul 5, 2023

Thank you for your explanations. We currently don't have plans to support that in the near future due to the reasons mentioned above.

@isarhoo
Copy link

isarhoo commented Jul 26, 2023

Can you support this usage?

record CarDto(string? Id);
partial class Car
{
    public string? Id { get; private set; }

    public void Update(CarDto dto)
    {
        Mapper1 mapper = new Mapper1();
        mapper.MergeCarDto(dto, this);
    }

    [Mapper(UseDeepCloning = true)]
    internal partial class Mapper1
    {
        public partial void MergeCarDto(CarDto source, Car target);
    }
}

@TimothyMakkison
Copy link
Collaborator

TimothyMakkison commented Jul 26, 2023

I don't think Mapperly will ever support mappings via reflection, as this is out of scope of the project.

Mapperly will not use Reflection as this would conflict with Mapperly's goals of generating AoT safe, fast and easy to read code.

It looks like zero overhead member access will be added to .NET 8.0. I don't know if this changes anything.

The neccessary code isn't exactly "easy to read" but it will work 💪

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

5 participants