cezarypiatek / MappingGenerator

:arrows_counterclockwise: "AutoMapper" like, Roslyn based, code fix provider that allows to generate mapping code in design time.
https://marketplace.visualstudio.com/items?itemName=54748ff9-45fc-43c2-8ec5-cf7912bc3b84.mappinggenerator
MIT License
1.03k stars 120 forks source link

[Enhancement] Synchronization means through attribute like [SyncedMapping] etc. #71

Closed wachulski closed 4 years ago

wachulski commented 5 years ago

Right now we have perfect means to create mappings. I'd would be useful too to resync the changes as entities/DTOs evolve over time (cliche, I know).

What about marking types/methods with attributes from e.g. MappingGenerator.Annotations (a dedicated NuGet) [SyncedMapping] to indicate the engine to look for changes and update mappings on the fly? It'd be particularly useful in scenarios when some entity-DTO pairs appear in multiple mappings as aggregate children.

I expect that one'd want some exclusion rules then too, e.g. custom mapping method discovery for not to loose custom changes:

dto.Accounts = MapAccountsInCustomWay(entity)
// ...

void MapAccountsInCustomWay(MyEntity entity)

It can be developed incrementally: 1) diagnostics only (i.e warnings) 2) code fixes (auto-sync updates on the fly).

cezarypiatek commented 5 years ago

Hi

There is a discussion about this topic #12 The main idea behind the MappingGenerator was to provide a mechanism that scaffold the mapping code and allows to easily adjust it to custom needs. I've never started to implement it because of two reasons:

I see this feature has aroused a lot of interest, but I'm not sure if this is doable. In order to make any attempt to implement it, I need more specific requirements. Especially, what are the expectations towards the "custom adjustment". How should they be handled?

For complete automated mappings I would be nice to use https://github.com/dotnet/roslyn/blob/master/docs/features/generators.md but they are still WIP

wachulski commented 5 years ago

Thanks for elaborating on this. Custom adjustments can be marked like explicit method extracts as I showed in the example and for omissions one could mark such with an attribute like:

public class MyDto
{
    [NoMap]
    public int MyProp {get; set;}
}

I know, a bit intrusive. When it comes to performance, we can start with sth as simple as resync button (keyboard shortcut) to resync them all.

The source generators look promising, indeed.

cezarypiatek commented 5 years ago

I prefer to keep all the mapping information closed to the context as possible. I mean, your proposal has a few flaws:

1) There is no option for controlling mapping if your are not an owner of the sources (for example it's generated or it's shipped as a library) 2) You cannot reuse class with attributes for different mappings.

wachulski commented 5 years ago
  1. What about placing attributes in classes you have control over (i.e. for which you generate code for)?
  2. Can you provide an example? If you really want your entities/DTOs clean and devoid of special markers, then you can put sth like this at the assembly level:
[assembly:MappingSync(typeof(...), typeof(...))]

or any convention you want.

I understand that syncing all up automatically may be problematic but at least some analyzer utility would be helpful to cover entities evolution over time. This could be especially valuable for having the compiler detect entity modifications by 3rd parties that are not reflected in the mapping code yet. For this, a set of reasonable markers would do.

cezarypiatek commented 5 years ago

I will make an attempt to create such analyzer, but this is not gonna happen in this month (quite busy season)

wachulski commented 5 years ago

I know, I wish I could attend your WG.NET talk on Roslyn this month. If you need any help developing such analyzer, I offer my help (well, I'm in TOP 2 of this repo Contributors list 😄).

cezarypiatek commented 4 years ago

I'm not going to implement a synchronization mechanism. If you need a mapping code that is continuously synchronized with models, please take a look at OnBuild plugin (#79) that generates mapping code during the build.