News for hackers. Stuff that matters.
Re:Show HN: Mapperly – A .NET source generator for object to... by neonsunset on Thursday January 12, 2023 @08:11AM (#34352939)
It is sad we still live in the enterprise world where having both "SomeClass" and "SomeClassEntity" isn't grounds for rejecting a PR that dares to do this.

Therefore, thank you for making this. Automapping is a sign of incorrect abstractions and unarguably bad solution architecture but since we are still forced to deal with such, doing so with speed and without reflection is always welcome.

Re:Show HN: Mapperly – A .NET source generator for object to... by functionstooge on Thursday January 12, 2023 @08:26AM (#34353129)
I'm curious, why would this be bad? I've generally always seen it as best practice to create classes in your domain model and try to write your ideal code and then have separate classes/DTOs that are used for communicating outside your domain model such as reading/writing to a database using an ORM or responding from an API with your ideal model for the consumer (since more often than not consumers don't need or want all of the cruft inside the domain model and your DB will likely have stored the information in a different format in a large system). I always love thinking of ways to simplify architecture though and I absolutely hate having classes/records that looks so similar though so I'm intrigued about a simpler solution if there is one? Domain Driven Design practices really encourage a bloated/complex architecture so I try to avoid it if possible but more often than not business requirements end up becoming so complex that I immediately fall back to those abstractions when the logic starts to get complex.
Re:Show HN: Mapperly – A .NET source generator for object to... by neonsunset on Thursday January 12, 2023 @08:44AM (#34353361)
Abstractions are useful to make a box and put horrors of edge case handling or business requirements variability in it :)

But if there are little of those, no need to make them prematurely. Field mapping is something for EF Core mapper configuration or repository implementation to worry about, no need to do the job twice.

You often don't need separate "Host" and "Core" projects either. And if you ever need to migrate to a new hosting solution, it happens maybe once during application lifecycle, and even then it requires some effort.

Replace-all and IDE tools work just as fine if not better for this, no need to inflict easily avoidable pain simply because it looks consistent with "other" solutions that were written 10 years ago.

Re:Show HN: Mapperly – A .NET source generator for object to... by grandpoobah on Friday January 13, 2023 @07:39AM (#34366907)
The amount of time C#/.NET developers waste on abstracting away all kinds of shit, creating three different layers for "separation of concerns", having 10 projects in some basic web app solution.. my god, they truly are suckers for punishment.
Re:Show HN: Mapperly – A .NET source generator for object to... by 0x445442 on Thursday January 12, 2023 @10:06AM (#34354540)
> customers don’t need or want all of the cruft inside the domain model and your DB…

Why would the customer need to know about the cruft? The view/UI shouldn’t be exposing what’s not needed. Same with the DB, frameworks like MyBatis put the mapping where it belongs.

Re:Show HN: Mapperly – A .NET source generator for object to... by jcmontx on Thursday January 12, 2023 @08:20AM (#34353050)
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.

Re:Show HN: Mapperly – A .NET source generator for object to... by neonsunset on Thursday January 12, 2023 @08:38AM (#34353272)
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 that made sense in the age of large monoliths where the scopes/contexts/features where segregated by modules.

Today, where modularity and protection of abstractions is no longer of concern because many teams can easily maintain up to 10 or even 15 (micro)services, the bias towards a certain solution style/architecture that is full of unnecessary abstraction layers, boilerplate and patterns that violate locality of behavior like there is no tomorrow is something that makes using C# much less attractive than warranted.

Ultimately, it comes down to the fact that unlike Go, C# is more than 20 years old, and while it builds upon ideas that were ahead of its time back then like async/await, LINQ and some other, it also suffers from "tradition" which can be easily seen in community resistance to rely on top-level statements (aka Python-style Program.cs), religiously following the rule "one file = one class" (even if it's just 'record User(string Name);') or simply overall creating 5-project solutions for something expressible in 3 .cs files.

Keeping in mind Chesterson's fence, I do acknowledge that the above is a result of likely reasonable and well-thought-out choices at the time, but it does not mean the circumstances haven't changed either.

Re:Show HN: Mapperly – A .NET source generator for object to... by radicalbyte on Thursday January 12, 2023 @09:02AM (#34353582)
I've been programming forever now and have written a lot of C#, TypeScript (/JS) and Python - and I much prefer the approach used in ServiceStack and in Vue.js of putting the "things which belong together" in one file than the alternatives.

You see in C# and Java that people love splitting classes into files (and are forced to by automated auditing tools - my last big project suffered from that, even as Lead I had my hands tied). Navigating such projects is horrible outside of tooling (such as in github) but fine if you always work within the IDE.

In Python I'm used to wading through classes of >1k LOC which are only slightly related because they have the opposite habit. I've yet to find a way to work around this.

Honestly I'm not sure what I find worst: it really depends on the project or the domain. If I had to chose I think that I'd prefer "too many small files" to "one huge file" as the latter has an extremely high risk of turning into a "big ball of mud" and it's what the clueless beginners do. That and trauma of having to maintain some old Visual Basic system where that was the norm.

Re:Show HN: Mapperly – A .NET source generator for object to... by kaba0 on Thursday January 12, 2023 @11:37AM (#34356221)
While some tooling has trouble with many small files, I find it just as debilitating to navigate a huge C file for example, that mandates heavy jumping between different positions even in IDEs. Sure, I do know about multi-pane editing, but my brain prefers the “tab corresponds to file” abstraction.
Re:Show HN: Mapperly – A .NET source generator for object to... by radicalbyte on Thursday January 12, 2023 @12:08PM (#34356869)
Same here.

Although to be completely honest: I would much rather that the AST was the main interface for code. The fact that our tools are based on text is a relic of the past.

Re:Show HN: Mapperly – A .NET source generator for object to... by radicalbyte on Thursday January 12, 2023 @09:04AM (#34353599)
(and as an aside: Python is very much VisualBasic++, I actually kind of like using it but it's just tiring putting up with the amateur level of other developers and the flakey ecosystem)
Re:Show HN: Mapperly – A .NET source generator for object to... by radicalbyte on Thursday January 12, 2023 @09:07AM (#34353631)
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.

Re:Show HN: Mapperly – A .NET source generator for object to... by HideousKojima on Thursday January 12, 2023 @09:30AM (#34353980)
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... by neonsunset on Thursday January 12, 2023 @09:43AM (#34354163)
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... by radicalbyte on Thursday January 12, 2023 @10:15AM (#34354702)
Yeah this! I write a lot of console apps and I absolutely love this change as it simplifies and removes a lot of cruft. Which means more people will make more console apps.
Re:Show HN: Mapperly – A .NET source generator for object to... by osigurdson on Thursday January 12, 2023 @09:24AM (#34353894)
>> 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... by neonsunset on Thursday January 12, 2023 @09:35AM (#34354054)
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... by osigurdson on Thursday January 12, 2023 @10:51AM (#34355337)
Services should be factored along scaling dimensions, not domain or team size. Ideally scaling and domain dimensions will be coupled to some extent, but that is not always the case. The popular idea that needs to die is that services are somehow tied to team size.
Re:Show HN: Mapperly – A .NET source generator for object to... by kaba0 on Thursday January 12, 2023 @11:34AM (#34356156)
The latter has API equivalency, but that is not the same thing as feature parity. Plus, you have very different concerns when you want a small self-hosted app, vs a more “traditional” deploy model where integration and the like are more important, shaping the way you program.
Re:Show HN: Mapperly – A .NET source generator for object to... by kaba0 on Thursday January 12, 2023 @11:31AM (#34356087)
> unlike Go

What exactly does Go do here, besides being grossly more verbose and less expressive than C# (and even Java)?

Sure, there are edge cases to nominative typing systems, and some of these particular cases may be better expressible with a structural one, but that’s another discussion to have.

Re:Show HN: Mapperly – A .NET source generator for object to... by neonsunset on Friday January 13, 2023 @01:47AM (#34364687)
Sorry, this was meant to refer to simplicity and focus of Go at solving problems it was designed to solve. Not that it doesn’t suffer from its own kind of boilerplate hell (the verbosity you mention), but it does not take away its upsides.
Re:Show HN: Mapperly – A .NET source generator for object to... by radicalbyte on Thursday January 12, 2023 @08:54AM (#34353469)
As always, it depends. Are you working on a CRUD system and are you using models to generate your UI/forms (or to generate a service layer for your SPA / Android / iOS apps)?

Then that pattern can be extremely effective - in fact, that is exactly the reason that some of us were pushing the patterns you see today. It was especially effective back before we had strong typing in frontends as it saved a lot of time otherwise wasted on QA or typo's in the frontend.

Re:Show HN: Mapperly – A .NET source generator for object to... by f8o on Thursday January 12, 2023 @07:51PM (#34362527)
A simple set of dtos in the application layer, defined around their respective application services (use cases if you will) is ok. Required for most bounded contexts/microservices. You properly organize application and domain layers. It does not need to be verbose. The problem is when people define dtos on the http infrastructure, then similar dtos on the app layer, domain models (often with all attributes being public and behavior scattered elsewhere), then dtos for database schemas... AutoMapper looks useful in these scenarios, but it's the wrong solution for poor design.

While manual handling is required when you have proper domain models with controlled creation and change operations, these tools can be useful for other matters.