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

Question: applying new fields to the mapping? #100

Closed Eldar1205 closed 4 years ago

Eldar1205 commented 4 years ago

Hi, I've read your blog post for why use compile-time mappings instead of AutoMapper and I agree with your claims against it mostly, however there's one thing important for me to use AutoMapper for I wonder if this Roslyn mapper solves. Let's say we have types UserDTO and UserEntity, and we generated a mapping. Now someone adds field "Locale" to both UserEntity and UserDTO and forgets the mapping(s) exist to add the field there; I've seen all the time, which AutoMapper solves. Will this generator emit some diagnostic about missed mapping opportunity?

cezarypiatek commented 4 years ago

Hi @Eldar1205 I wrote another blog post about using MappingGenerator to create mappings that are auto-synchronized during the build time https://cezarypiatek.github.io/post/generate-mappings-on-build/ This should solve your problem. Creating an analyzer that reports missing mappings is a quite complicated task and this will cause problems in cases when you adjust generated mapping afterward.

Eldar1205 commented 4 years ago

Nice nice nice! Thank you very much :) I'd like to say that your SmartCodeGenerator I'll definitely look into, wanted simple build-time code generation for a while. Regarding how you support extensibility for the generated mappers, virtual methods is great idea, the only it lacks that I can think of is the ability to customize the constructor call, which is the only way to initialize certain properties - the constructor call of the destination class can only be customized by completely override the generated mapper. Would be nice to have two methods to override - the destination factory and the post initialization mapping. Regardless great work and I'll consider using it in a layer of internal libraries I'm about to provide for our group :)

‫בתאריך יום ו׳, 10 בינו׳ 2020 ב-21:32 מאת ‪Cezary Piątek‬‏ <‪ notifications@github.com‬‏>:‬

Hi @Eldar1205 https://github.com/Eldar1205 I wrote another blog post about using MappingGenerator to create mappings that are auto-synchronized during the build time https://cezarypiatek.github.io/post/generate-mappings-on-build/ This should solve your problem. Creating an analyzer that reports missing mappings is a quite complicated task and this will cause problems in cases when you adjust generated mapping afterward.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/cezarypiatek/MappingGenerator/issues/100?email_source=notifications&email_token=ABIFRN4B4P5Z5FSTZG55TATQ5DENRA5CNFSM4KFC5HIKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEIU7HRA#issuecomment-573174724, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABIFRN4R3SNXKWGXRV56FV3Q5DENRANCNFSM4KFC5HIA .

cezarypiatek commented 4 years ago

What kind of constructor invocation customizations do you have on mind? Could you provide a sample code that depicts your expectations? I've been thinking about extracting methods for sub-types mappings for some time. This could make the code much clearer in case of complex mappings, allows to reuse mapping logic, gives move flexibility in terms of override/customization and supports programming best practices as well.

Eldar1205 commented 4 years ago

It's a general statement that if one of classes has a constructor that the mapping generator can't implement for some reason then the entire mapping method needs to be coded instead of replacing one line. With AutoMapper it's possible to provide a factory method which is nice, but I digress; I still find the build-time auto-mapper an idea worth leveraging where possible, maybe use AutoMapper as supplement if it makes sense. A quick question if I may (no option to test myself anytime soon) - can your mapping generator be used for deep cloning? AutoMapper doesn't allow mapping a type to itself, and it's not worth to create a duplicate type which people will forget to update with new fields.

‫בתאריך שבת, 11 בינו׳ 2020 ב-19:13 מאת ‪Cezary Piątek‬‏ <‪ notifications@github.com‬‏>:‬

What kind of constructor invocation customization we are talking about here? Could you provide a sample code that depicts your expectations?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/cezarypiatek/MappingGenerator/issues/100?email_source=notifications&email_token=ABIFRN4X7OLYVOYD3QYWQWLQ5H423A5CNFSM4KFC5HIKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEIWGN6Q#issuecomment-573335290, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABIFRN25RYSDOU7JPPX5VBDQ5H423ANCNFSM4KFC5HIA .

cezarypiatek commented 4 years ago

Regarding the question about cloning - yes, MappingGenerator is supporting identity mappings. You need to declare a method with the signature as follows (names doesn't matter)

public GivenType Map(GivenType input)
{
}

About the factory methods - I need to think about it, take a look at the code base and I will let you know when I decide something. I think this could be doable.

Eldar1205 commented 4 years ago

Awesome thanks! I'll check it out, make sure it copies arrays and deep clones nested properties even though they share the same type, thanks!

‫בתאריך שבת, 11 בינו׳ 2020 ב-19:49 מאת ‪Cezary Piątek‬‏ <‪ notifications@github.com‬‏>:‬

Regarding the question about cloning - yes, MappingGenerator is supporting identity mappings. You need to declare a method with the signature as follows (names doesn't matter)

public GivenType Map(GivenType input) { }

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/cezarypiatek/MappingGenerator/issues/100?email_source=notifications&email_token=ABIFRN7LELNV2FXVVRO2PWDQ5IBDNA5CNFSM4KFC5HIKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEIWHGPY#issuecomment-573338431, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABIFRN3YPFUX53TP4DVUMXTQ5IBDNANCNFSM4KFC5HIA .

cezarypiatek commented 4 years ago

@Eldar1205 If you want to keep tracking of new properties then you can try to use [InitRequired] attribute or /*FullInitRequired*/ commend marker described here https://cezarypiatek.github.io/post/immutable-types-with-roslyn/