Live data from Hacker News

Show HN: Mapperly – A .NET source generator for object to object mappings

github.com

41–50 of 71 posts

Re: Show HN: Mapperly – A .NET source generator for object to object mappings

#41
post #31

The ability to use source generators in .NET did seem like a really powerful capability when it was first announced. That said, I have failed to find a practical use case for source generators in my day-to-day work. Reflection is very accessible and we have managed to avoid severe penalties of this on most paths so far. Has anyone found other good use cases for source generators in their projects?

Regular Expressions and System.Json support using source generation for performance gains.

Re: Show HN: Mapperly – A .NET source generator for object to object mappings

#42
post #31

The ability to use source generators in .NET did seem like a really powerful capability when it was first announced. That said, I have failed to find a practical use case for source generators in my day-to-day work. Reflection is very accessible and we have managed to avoid severe penalties of this on most paths so far. Has anyone found other good use cases for source generators in their projects?

Reflection is inherently unsafe. Even something as relatively simple as a JSON de/serializer can blow up in your face.

Source generators are compile-time safe. Well, unless they generate unsafe code, of course, but most of them shouldn't and don't.

They're also safer in a broader sense in that any "implicit" changes will show up in the version control history, if you commit the generated code (which you should!).

Re: Show HN: Mapperly – A .NET source generator for object to object mappings

#43
post #18

Earlier quoted context omitted.

In many cases DbModel is not exactly the same as AppModel and ViewModel. In typed programming languages automappers are rather useful. > without reflection Source generators are not reflection.

Yes, the above comment was addressed at most popular use case - that of back-end services where entity to class map 1:1. In fact, there is already mapping in defining DB field types (if non-default) in model registrations consumed by ORM. Worst case it is always an option to project within DB query itself, sometimes even "cheaper" too. In such cases, having an extra abstraction is both redundant and an anti-pattern t…

>> teams can easily maintain up to 10 or even 15 (micro)services

Your arguments reject complexity, then, in the next breath, endorse it. Micro-services are the enterprise bloat of our time (and likely the worst example of all the bad ideas that have circulated in that space). Small departmental apps used by 15 people require 34 micro-services (all hitting the same db tables of course).

Re: Show HN: Mapperly – A .NET source generator for object to object mappings

#44

I've never really understood the use case for these mapping generators. Every time I've seen them used (MapStruct in Java, AutoMapper in C#) the mapping configuration eventually ends up being so complex that just manually writing out the mapping would've been just as simple and arguably simpler to understand.

We ran into a problem where AutoMapper changed it's approach between versions for a way we were using it. We then got to spend the next few weeks updating our code because of it. I'm pretty sure that all the time we "saved" by using it was lost.

My project had the same issue. I ended up stripping out AutoMapper and manually mapping my types. In the end, it was much easier to determine exactly what was going on, and now I have one less third-party dependency.

Re: Show HN: Mapperly – A .NET source generator for object to object mappings

#45

Earlier quoted context omitted.

Yes, the above comment was addressed at most popular use case - that of back-end services where entity to class map 1:1. In fact, there is already mapping in defining DB field types (if non-default) in model registrations consumed by ORM. Worst case it is always an option to project within DB query itself, sometimes even "cheaper" too. In such cases, having an extra abstraction is both redundant and an anti-pattern t…

BTW have you seen the new Node / Go style top-level statements in the .net 7? Microsoft have been doing some fantastic work, they've constantly been taking the best bits from other ecosystems. In the right hands - so with strong progressive leadership - it wipes the floor with other ecosystems.

Top-level statements are actually my single biggest beef with .NET 6 and 7, specifically because Microsoft decided to make them the default for any new console apps. And they didn't even add a flag for reverting to the old behavior until .NET 7, their guides for .NET 6 if you actually wanted a proper Program.cs file were literally "Generate is with .NET 5 and then up the target framework to .NET 6." This broke over a decades worth of guides/tutorials for beginners, right around the time I was trying to help a younger relative learn to code.

Re: Show HN: Mapperly – A .NET source generator for object to object mappings

#46

Earlier quoted context omitted.

Yes, the above comment was addressed at most popular use case - that of back-end services where entity to class map 1:1. In fact, there is already mapping in defining DB field types (if non-default) in model registrations consumed by ORM. Worst case it is always an option to project within DB query itself, sometimes even "cheaper" too. In such cases, having an extra abstraction is both redundant and an anti-pattern t…

>> teams can easily maintain up to 10 or even 15 (micro)services Your arguments reject complexity, then, in the next breath, endorse it. Micro-services are the enterprise bloat of our time (and likely the worst example of all the bad ideas that have circulated in that space). Small departmental apps used by 15 people require 34 micro-services (all hitting the same db tables of course).

It all comes down to scale. I'm not endorsing splitting off logic into different applications for the sake of it - it is no better (usually worse) than splitting logic into separate modules for things that could've been "together". 34 microservices per just 15 people sounds like a lot of trouble unless those are really "lean", have little to no boilerplate and managing infra-side of things is automated away or outsourced to dedicated platform team.

To give a better example, recently on HN there was a discussion on self-hosting Bitwarden and its respective implementations. The official one[0] is written in C# and uses 15ish containers. The alternative one[1] is written in Rust and is a one application. I think both have their merits, since the former is used to serve possibly millions of users at this point, while the latter is best utilized in self-hosted home or SMB scenarios.

[0] https://github.com/bitwarden/server

[1] https://github.com/dani-garcia/vaultwarden

Re: Show HN: Mapperly – A .NET source generator for object to object mappings

#47
post #5

What are the advantages over AutoMapper?

Automapper generates all mappings at runtime with reflection. Mapperly in contrast uses roslyn based source generators and generates all mapping code at compile time. This leads to improved runtime performance with less allocations [1]. Since no reflection is used at runtime, the generated code is completely trimming save and AOT friendly. [1] https://github.com/mjebrahimi/Benchmark.netCoreMappers

Even though AutoMapper of course uses reflection to construct mappings, executing mappings does not involve reflection if not necessary. AutoMapper builds expression trees, compiles them on first use, and uses the resulting function to perform the mapping. If your mapping involves things only accessible through reflection, then the compiled mapping function will of course still have to rely on reflection.

Re: Show HN: Mapperly – A .NET source generator for object to object mappings

#48

Earlier quoted context omitted.

BTW have you seen the new Node / Go style top-level statements in the .net 7? Microsoft have been doing some fantastic work, they've constantly been taking the best bits from other ecosystems. In the right hands - so with strong progressive leadership - it wipes the floor with other ecosystems.

Top-level statements are actually my single biggest beef with .NET 6 and 7, specifically because Microsoft decided to make them the default for any new console apps. And they didn't even add a flag for reverting to the old behavior until .NET 7, their guides for .NET 6 if you actually wanted a proper Program.cs file were literally "Generate is with .NET 5 and then up the target framework to .NET 6." This broke over a…

That is the goal. Change is likely to cause documentation and knowledge to become outdated.

Also changing the app back to old format is "Ctrl + ." -> "Change to Program.Main" away.

Developers would find a gripe with one new feature or another, even if it makes achieving a particular goal easier and less painful, simply because change is very uncomfortable to many.

Re: Show HN: Mapperly – A .NET source generator for object to object mappings

#49
post #9

I've never really understood the use case for these mapping generators. Every time I've seen them used (MapStruct in Java, AutoMapper in C#) the mapping configuration eventually ends up being so complex that just manually writing out the mapping would've been just as simple and arguably simpler to understand.

I banned Automapper from my company.

So did I. Do the napping manually and let the type system actually help you instead of being invisible.

Re: Show HN: Mapperly – A .NET source generator for object to object mappings

#50

I've never really understood the use case for these mapping generators. Every time I've seen them used (MapStruct in Java, AutoMapper in C#) the mapping configuration eventually ends up being so complex that just manually writing out the mapping would've been just as simple and arguably simpler to understand.

In webapps it's often very useful to accept a subset of a domain entity as an APIs request body, or to return it as a response body. It's nice having separate classes to describe the request & response bodies because this lets you automatically generate OpenAPI descriptors which can then be used for client generation and so on. When your domain objects are small it's easy to just manually copy the data between your d…

Agreed. If you've come along the journey of first using the json attributes on your Domain objects to try and define your return but then get stuck the first time you have another API call returning a different subset of fields.

It all clicked for me when I read somewhere: "The best way to define a data structure is a class, that's what they are".

So now you can create Response and Request versions of your classes and use AutoMapper to convert them.

When someone green comes into my Domain Driven project they always have the same question - why are there so many versions of your classes? In my project I have the aforementioned versions of those classes, but also the auto-generated Entity Framework classes in the Repository - which mimic the database structure - but it's not 1:1 (e.g. a many to many relationship will most likely not have a Domain model for the joining table - unless it has its own non-Foreign Key fields defining that relationship). But I don't use AutoMapper for that part - just a lot of code - maybe one day.

Oh, and then I have at least one more version in Typescript!

Post reply on HN