Been using .NET for years now for backend web development after having taken a break from C#. It is such an improvement over the old .NET framework. When I started building my first backend with it, I was surprised how much was included and "just worked". Need to add authentication? Few lines. OAuth? Also built in. Response caching? Yes. ORM? EF Core is pretty good. Need to use env variables to override your JSON config? You are going to have to build a... just kidding that works with one more line too.
Coming from NodeJS, the amount of stuff that could be added with a single line from an official package was great. No more worrying about hundreds of unvetted dependencies.
It really is like finding enlightenment after having to figure out which third party package is best for every little thing in Node. Visual Studio is a pretty powerful IDE as well.
Can you install it [edit: the .Net 7/8 platform that sounds interesting, not the IDE] for free on a Linux server and get the same benefits? (This isn't advocacy, it's a literal question about something I don't know.)
We're moving to .Net, and I was surprised by how poor the built-in DB stuff is. It's like either assembly or Python, but nothing in the middle.
That said I've also been impressed about how nice it is to get stuff going. I used C# back in the .Net 1.1 days and yeah massive difference in ergonomics.
EF Core when it first came out was pretty rough but they have been adding a ton, especially in .NET 7 and coming up with 8: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-cor... Most of the pain points for me are solved now. Like someone else mentioned, Dapper can fill the gaps.
The new asp.net took a lot of good concepts from the node ecosystem and feels really modern. It has a lot of batteries included. I think .net is an awesome platform to build backends. I wouldn’t use it for frontend though. Razor and Blazor never really convinced me.
Blazer Server is perfect for internal applications and dashboards though. It's just so easy to use, especially if you plug in any of the community made component libraries like MudBlazor. I had pure backend devs actually happily make frontend for once. It's essentially Phoenix's LiveView but in C# and that uses already proven SignalR.
I have been having a ridiculous time trying to find out just how to override an appsettings json variable (DBConnection string) with an environment variable. Could not find any good answer. What is the right way?
Configuration is applied in layers. If you’re using the default setup you get the following layers applied in this order:
1. appsettings.json
2. appsettings.{env}.json
3. user secrets (only in Development environment)
4. environment variables
5. command line args
You can full customize the setup if you desire, there are packages to support things like external secret stores. If you Google ‘Asp.Net core configuration” there’s a MS page that goes into great detail on all of this.
Anyway, your env vars must match the name as you’d structure it in a json object, but with the periods replace with double underscores. So ConnectionStrings.MyConnection becomes CONNECTIONSTRINGS__MYCONNECTION, FeatureFlags.Product.EnableNewIdFormat becomes FEATUREFLAGS__PRODUCT__ENABLENEWIDFORMAT, etc.
You can have multiple appsettings files and are additive. Eg, you can have appsettings.production.json which only contains an override for the connection string in the base appsettings.json.
> I was surprised how much was included and "just worked".
A simple HTTP server? Maybe I'm missing something, but when I needed it I hadn't found one.
I believe, the closest it has is System.Net.HttpListener which is a very different thing from your typical Golang's net/http.Server or python's http.server.HTTPServer.
I believe at some point they had switched from HTTP.sys to Kestrel, so at least it doesn't need the admin privileges anymore. But this whole thing is so much related to ASP.NET it's pretty hard to figure out how to create a simplest HTTP server without anything else forced upon you (no services, no "web applications", no router, just plain and simple bare HTTP protocol handler). So my impression is that maybe .NET can make certain complex things easy, but it has some issues with keeping simple things simple.
If for some reason you don’t want the framework to handle things like routing or request/response deserialization/serialization then you can go bare bones and implement everything via custom middleware: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/m...
… how often are you hand-parsing HTTP requests and hand-crafting HTTP responses one character at a time?
Productive devs want the request/response wrapper objects and routing constructs to handler methods to get work done and can still drop down into fine-grained request/response crafting as and when required.
I'm definitely a fan of the "batteries included" approach, but I am ambivalent on EF because I feel like it is still a bit too magic and gets abused. Though it's not like it's a big deal to use whatever else you prefer instead (I am a big fan of the inline SQL with Dapper approach).
I stuck to DB-First model + LINQ + SaveChanges() and largely managed to keep out the magic quite successfully for a .NET6 web project last year. Records are fantastic when composing queries. I didn't touch inheritance or any fancy mapping strategies -- one table, one class.
The only bit of framework-specific / hidden magic debugging I really had to do was the realization of AsSplitQuery() when creating objects composed of independent datasets, AsNoTracking() for a decent perf bump, and single group-by's are fine but when you start nesting them it gets really hairy really quickly -- they usually ended up becoming views.
Otherwise change-tracking worked wonderfully for batch-updating (but everything I did was short-lived) and outside of group-bys, the LINQ -> SQL mapping (and vice-versa) was extremely predictable, in both EF Core generating the SQL I expected, and creating the correct LINQ from the SQL I knew I wanted.
Coming from 10 years of spring and NodeJS development, last year of .NET has been incredible. I share that "batteries included" experience. So much useful functionality is just packed right in. And there's a lot of backward compatibility and support.
When you update .NET libs years later, we still don’t have to change any code in our own software. With anything nodejs, even months and sometimes weeks, updates of any kind means everything breaks. Not sure how anyone builds things with it that don’t need updates outside security fixes. Smaller companies might have software running years or decades that only need security updates and not new features. A lot of our stuff is over 10 years old and needs only security updates; none of that is node (or in the npm ecosystem for that matter) as we simply have shot ourselves in the foot with that too many times already.
It's been a few years (2018?) since I used NestJS but back then our experience with it was far from stellar. It lacked documentation beyond the basic "getting started" examples (just checked, it doesn't seem like they've improved much on that front), it had quite a few footguns and as soon as we strayed off the beaten path, things tended to become painful, especially on the GraphQL side of things and general 'plumbing' like interceptors, schemas, and data validation.
Internal error handling was sometimes abysmal too, a misconfiguration of certain dependencies in `AppModule` could leave the application in a broken state on startup where it wouldn't bind to its port and no error messages were printed to console. On a few occasions I had to spend an hour or more reading and understanding NestJS source code to resolve those issues, which could have been avoided if they had better internal validation and error logging in place.
That's not to say it was all terrible, some aspects of it were genuinely good, but the overall experience and many hours of needless pain it caused left a really bad taste in my mouth. Back then, at least, it felt like a Lego set where the pieces didn't all quite fit together.
Depressingly enough, it seemed like NestJS was the best that Node.js world had to offer which made me quit the ecosystem altogether.
.NET has been doing a lot of things right. My startup's codebase is nearly all .NET 7: landing page, web app, Windows service, API. The main non-.NET code is vanilla JS in the web app.
I've been keeping a close eye on Next.js, which is very well done, but I love how versatile .NET is. With one language, I can write all of the above, and my dependencies are minimal thanks to .NET's rich standard library - a refreshing change from the NodeJS apps I've written and maintained.
With native AOT, .NET can even be compiled to native binaries. Recently, I wrote a Windows password filter DLL in C#, which would have been unthinkable some years ago.
It's a really enjoyable stack to work with. Kudos to Microsoft for what they've been doing with it.
Nextjs (and its contemporaries) work really well with .NET. Toss in your API calls into Next, write a beautiful front end, and now you've got separate front end and back end that works phenomenally together and can be tested separately using their strengths.
I'm more shocked by you sticking with Javascript. Surely with your adoration of C# you would have moved to its closely related sibling Typescript. Although I guess there is that slight initial hump to move to TS from a purely vanilla project.
> Nextjs (and its contemporaries) work really well with .NET. Toss in your API calls into Next, write a beautiful front end, and now you've got separate front end and back end that works phenomenally together and can be tested separately using their strengths.
Is it somehow different than using any other language for your backend? Seems to me you're describing any frontend/backend split, nothing specific to either Nextjs or .NET here.
> I'm more shocked by you sticking with Javascript. Surely with your adoration of C# you would have moved to its closely related sibling Typescript. Although I guess there is that slight initial hump to move to TS from a purely vanilla project.
Some people prefer to stick with vanilla JS because that's what the browser ends up running anyways. Personally, TypeScript tends to get more in the way than be helpful for certain type of projects, while for others, TypeScript helps a lot but tends to be when the codebase involves a lot of contributors of varying skill-levels rather than a small circle of contributors with relatively high knowledge of programming and JavaScript in particular.
Frontends often have a much shorter lifetime than backends. A good example are banks, they change the online banking frontend approximately every 10 years, but a lot of backend systems are running since the 80s/90s without complete rewrites.
It makes a lot of sense to decouple them, and just re-write the frontend to whatever technology is the best for its time. It’s also not uncommon to have multiple frontends, for example a web application and also a native android/iOS app.
How do the costs of running the .NET 7 codebase compare with running something open? I like .NET a lot, have worked with it a lot in the past. But when I tried my own startup, I picked node instead and don't really regret it. I'm getting back into .NET these days though at a new job again, and .NET 7 will be interesting to dive into. Still not sure I'd want to be that tightly-coupled to Microsoft subscriptions though. I'd tried getting a couple .NET projects off the ground back in the .NET 5 days or whenever .NET Core first became a thing. It was surprisingly expensive to run things in Azure, and to use tools too. So that played a role in me just picking node for my startup even though I'd have preferred to stick with C# and .NET if I could, so I could become an expert in those tools.
But yeah, it's definitely a huge plus to have access to .NET's massive standard library. The documentation is amazing, too. If the costs to run in Azure and to be tightly-coupled with Microsoft rthat way are reasonable for a lean/small startup or self-funded startup, then I may give it a shot again.
.NET IS open and not really tied to any Microsoft Subscription. I really hate when people keep parroting that without understanding. Rider is nowadays a better IDE for C# and it's not owned by Microsoft. You can host it wherever because it runs wherever.
Building my startup on .Net as well. Been a huge fan for over a decade but haven't written professional C# in over 8 years. It's been a dream to write OSS b2b .Net based IT tooling for years now(C# or my language crush F#); and here I am :)
Using Asp.Net 7 for the server component with React and Vite as the FE tooling. Been a HUGE learning curve the first couple months particularly around the DI, options pattern, Asp.Net auth and Identity and etc but everything is falling into place now. Also SignalR is much more low-level than it pretends to be lol.
It would have been easier to go straight NodeJS as I'm quite proficient in writing even framework level code in it(down to the sockets), but I believe .Net is the better option for this long term.
Fortunately NextJS and .Net isn’t strictly an either/or proposition. I’ve moved most of my new front-end development to NextJS at this point and use C# for most everything behind it.
My big problem with .NET is that a lot of line-of-business apps were written using ASP.NET Web Forms, but there is no upgrade path other than “rewrite most of it”.
It feels like the pain everyone went through upgrading from Python 2 to Python 3.
It also doesn’t help that .NET Framework has its support cycle tied to the OS, and hence is 10+ years. This means that businesses can be lazy and just leave these old apps to fester and still be technically “supported”.
As web standards evolve, I’m seeing these web apps slowly break.
It’s actually a big problem and Microsoft doesn’t seem to care much. It’s only in .NET 7 that they’ve finally introduced some incremental migration features, but they’re buggy and incomplete.
As a random example of the issues: .NET Core 1.0 broke DataContract deserialisation because of a missing thing in the BCL. A decade later this is present now but they still haven’t fixed the service client generator tool!
Every time I’ve tried to migrate an app, it’s one breaking issue after another with 3-year old GitHub issues that have no responses from Microsoft.
Talking about the awesome future of .NET is great and all, but you've got to give people a path to get there...
The writing was on the wall a long, long time ago!
These companies had 15 years to do it. And it was fairly easy to get webforms + MVC running side-by-side on the same site so you could gradually migrate.
Too late for that now though, you can't run webforms + MVC Core side-by-side.
You could put a load balancer in front of the old app and start moving end points to a new code base.
It's akin to moaning that MS haven't got an upgrade path from IE7. Or your Adobe Air app has stopped working.
On the plus side, doesn't 4.7 still have a huge support window because it's tied to one of the windows server versions?
> The writing was on the wall a long, long time ago! [...] These companies had 15 years to do it.
I pointed this out in 2013 only to be literally shouted down by my manager. I did so again in 2017 under a different manager on the same team with the suggestion that we investigate using SPAs and RESTful frameworks only to be told that Razor Pages was the way forward which, while an improvement, didn't do any wonders for our ability to attract/build technical talent or create rich user experiences.
As a sibling comment points out (in a sentiment that I've echoed on HN before):
> ASP.NET Web Forms are a complete trainwreck and an abuse of HTTP and other basic web development standards (e.g. by using javascript: URLs and POSTing forms for every single interaction with the page). It is broken by design.
You can probably see why developers that chose this framework in the first place aren't interested in upgrading... learning actual web standards and state management isn't something they wanted to do in the first place.
> The writing was on the wall a long, long time ago!
The vast majority of ASP.NET Web Apps could not have migrated to .NET Core 1.0, it was missing too many features. It was missing types like 'securestring', and had zero support for Workflow Foundation, Windows Communication Foundation, etc...
At the time, .NET Core was also advertised as "an alternative platform for Linux apps", not as a direct replacement for .NET Framework.
It was only in .NET 5 that Microsoft changes their tune and started calling Core the "replacement". At the time, something like half of complex enterprise apps might be able to migrate across, but they would have encountered a long list of breaking issues with a note saying "we might fix that in an upcoming major release". That's after a partial rewrite.
You can't go to a business that has a web app that's "not broken" and suggest migrating it to a definitely broken platform that's very much still playing "catch up".
Support is improving in .NET 7, and the upcoming .NET 8, but it's definitely not 100% and pretending that it's the "end users' fault" for not jumping onto an incomplete and buggy platform is not helpful.
I'll list some random GitHub issues for you to perouse. For large enterprise apps, many of these are showstoppers for incremental or seamless migrations. The workaround is always "rewrite everything from scratch using wildly different technologies that aren't direct replacements."
IIS app pool recycle throws 503 errors
https://github.com/dotnet/aspnetcore/issues/41340
OData core libraries now support OData v4
https://devblogs.microsoft.com/odata/announcement-odata-core-libraries-now-support-odata-v4/
(.NET Framework is v1-v3, and Core is 4.0+, a breaking change!)
Workflow Foundation didn't start getting migrated until .NET 6, and not by Microsoft!
https://github.com/UiPath/corewf
dotnet-svcutil ignores most of the settings
https://github.com/dotnet/wcf/issues/4887
dotnet-svcutil silently failing to deserialize responses
https://github.com/dotnet/wcf/issues/4163
Reuse of Types not working with WCF dotnet-svcutil tool for .NET Core
https://github.com/dotnet/wcf/issues/4277
Visual Studio 16.8 breaks SvcUtil build targets
https://github.com/dotnet/wcf/issues/4431
Besides the obvious IFRAME approach, one could have a single solution with both a ASP.NET Web Application project and another MVC (or Blazor) project. Both of them would reference shared models/services via some .NET Standard 2.0 project. IIS can host ASP.NET Core.
Then start refactoring and rewrite the old HTML4/CSS2 into HTML5/CSS4, while the Server Controls and Master Pages become Razor Components.
The end result is that .NET Framework is the Python 2 of the .NET world, and a major slice of anything .NET that I happen to touch on for enterprise consulting.
ASP.NET Web Forms are a complete trainwreck and an abuse of HTTP and other basic web development standards (e.g. by using javascript: URLs and POSTing forms for every single interaction with the page). It is broken by design. ASP.NET MVC 1.0 came out in 2009, there was plenty of time to modernize those apps.
I'm not sure you're addressing anything the comment above said.
Their complaint was that people invested a lot of resources into a technology that Microsoft promoted, and then that technology hit a dead-end with no good upgrade path aside from "rewrite it all!" What year that occurred is irrelevant.
Ironically you brought up MVC 1.0, which Microsoft did EXACTLY THE SAME THING TO, when they released Asp.Net Core MVC which also has no direct upgrade path. In fact, it wasn't until the last twelve months that Microsoft even tried offering anything when they realized it has been ten years and a lot of companies remain stuck to this day on .Net Framework.
Yes, Web Forms was poorly designed. But this is about Microsoft's poor upgrade offerings more than any specific technology, and an import lesson for people investing time/resources into Blazor today (given that it uses a proprietary WebAssembly compilation system and a proprietary back-end not dissimilar from WebForms in terms of lock-in).
Technologies don’t live forever. At some point you need to upgrade, and at some points there will be some major breaking changes.
.NET 4.8 is still fully supported, and there is no end-of-life communicated yet. It is a part of windows server 2022, which will be supported until 2031, that’s probably the earliest possible end-of-life date for .NET 4.8.
If people are looking at what technologies and companies to invest in, knowing that they may be left high and dry with a "full rewrite"-level of breaking changes is a valid and relevant critique. You want to know you'll be supported through difficult transitions, and that isn't unreasonable.
I don't understand why people are coming out of the woodwork to tell everyone that full rewrites are a perfectly normal and expected regular occurrence that you should expect from your tech choice. Python 3 is famous for how much they hurt themselves by ignoring the problem. Many companies never did migrate from 2 to 3, and instead picked tech with better guarantees. I expect the same to occur with .Net Framework.
.NET Framework will be supported for much longer than that. It is used in many internal Windows components including MMC snap-ins, ADFS, and other Microsoft technologies like Exchange and Sharepoint.
Or maybe it will not be supported as in "we won't provide support for any applications needing .NET Framework, but they may or may not still work"?
Old .NET Framework was a main, Windows only, branch of .NET.
At tag "v4.x", a new branch named 'Core' was created. Core was a multiplatform version of .NET.
There were three tags in the Core branch: v1, v2 & v3.
Then Core jumped from v3 to v5 and was merged back into the main branch. ".NET Core" has replaced ".NET Framework". Also, v5 dropped 'Core' from the name and was named just ".NET 5".
Development now happens on the main branch and has already reached tag v7. A new tag is created each year.
I'm traditionally about as far from a "microsoft ecosystem" dude as it gets. The first MS anything I've touched in my career has been the last year or so in csharp, and I love it. Great performance, excellent language, sane architectures. ASP.net is awesome for APIs.
I use Rider from Jetbrains, develop on a mac, deploy to Linux on AWS, it would blow the mind of 2003 me to know this was the case.
I spent a lot of time as a Java developer and have recently moved into a spot where I'm being asked to work with C#. A few things rub me the wrong way, and I'm wondering if it's just ignorance and / or me being stuck in my old ways.
- Unit testing with mocking is kludgy compared to Java and Kotlin (Moq vs Mockito). There's no mocking of concrete implementations for technical reasons, perhaps unless you shell out money for a paid product. This leads to folks putting interfaces everywhere so that code is testable.
- Along the lines of the above, everything feels a lot more corporatized or tied to Microsoft. The open source ecosystem and tooling around C# isn't to the same level of the JVM langs.
- The project structure feels odd. Solutions hide a lot of files from you, whereas JVM langs generally show what's actually there.
When it comes to actually writing implementations, I don't mind it, and it's far ahead of, say, Java 8. ASP.net might even be ahead of Spring in a few ways. But with Java 20 and Kotlin around, I don't feel compelled to move to it as a new default.
There are other libraries than Moq. Nsubstitute, FakeItEasy, etc.
With Moq and most mocking libraries, you generally just need to make a method virtual for mocking concrete classes.
Most mocking libraries use Castle Project's Dynamic Proxy, so they should be able to inject things without the need of interfaces. Interfaces for everything comes from the .net community's obsession with patterns, abstraction, clean architecture, and DDD.
You can use vscode with file based projects. With Rider/Visual Studio you can show hidden folder so long as they are in a folder or subfolder of a project.
Otherwise, you'll need to add a solution folder and items to the solution folder.
Right, marking methods as virtual is the other route I saw. Are most C# codebases opting to do that rather than add interfaces? It feels weird to edit signatures like that for testability, but maybe it's just what I'm used to - I'm putting all of my objects in constructors already for testability's sake, and I'm no stranger to making a factory or two.
VSCode has been my way forward for file-based editing so far. It's not so bad - just feels like I'm doing things that I ought not to be when I'm searching for DLLs or a random "scripts" folder in the root folder of our repo in Rider. In IntelliJ IDEA, all of the folders are just sitting there, ready for quick edits.
I think C# overcommitted on interface-driven design. It's good in some instances, but the more I work in code the more I think that the majority of it is needless and oftentimes harmful to maintaining a healthy code base.
Thanks for the pointers! Nsubstitute looks cleaner than Moq at first glance.
Is hot loading the default in JVM-ville circa 2023 ? God I hope so, I remember downloading these third-party builds and 180 characters of args or something to get that going + whatever voodoo was needed to make your janky framework respect that, make your IDE use it etc.
That's an obvious anti-pattern in the first place, especially when you know the optimizer could inline hot code and optimize the function out.
> Everything feels a lot more corporartized or tied to Microsoft
Remember J2EE and the confusing javax stuff? They're the same and fortunately both are waning out.
> The open source ecosystem and tooling around C# isn't to the same level of the JVM
Isn't that because of the open source community's refusal, rejection and resistance against Microsoft? Not only open sourcing is a first mover takes all, but specific to Microsoft they have been known to be hostile to open source in the past, most prominently one of the former CEOs of Microsoft blatantly called Linux cancer and what do we have today (https://www.theregister.com/2001/06/02/ballmer_linux_is_a_ca...)
Also, it is very well known Microsoft tried to spread FUD in the past in order to kill Netscape Navigator and tried to kill Java until it is almost being antitrusted to the extent of Baby Bells (https://en.wikipedia.org/wiki/Breakup_of_the_Bell_System?wpr...). Still Microsoft is not friendly nor hostile towards open source given that they let Mono lived, despite using Microsoft's trademarks and patents (you heard me right, dotnet has several patents and ECMA standards before!)
It's not like we dotnet people don't know the past shady shit of Microsoft, but I do believe in a convicted criminal could learn from the past, correct itself, move on from the past and be a better person off the record in the long run.
It's like a big bully tried to beat off a skinny nerd but now the nerd is as big as the bully now, and all of a sudden the bully found its conscience and begged for apology. It is natural for the nerd to not accept it in the first place. Except when both are nerds and the analogy may sound kinda odd.
But I also do understand not all people thinks like that especially for the open source community who is wary of Microsoft may attempt to commit a FUD to the open source community and they do have their memory and thus reactions, I don't have any means to control it. In fact most ordinary people would still choose to reject a convicted criminal in their community instead of accepting even if they have stopped the behavior, because it is a social stigma that indicates this person is of high risk
And contrary to Java world, the Oracle situation is getting more and more heated due to its predatory licensing agreement and people are flocking to other Java distributions. This could tear the Java ecosystem apart because it is the .NET Standard situation again and I'm pretty sure histories repeat. By the way, fragmentation is what ultimately killed MIPS and I think RISCV is on the watch.
Alas, time as always will tell, just like it's either hit or miss. We should look for a longer vision and see how it shaped out in the futures.
> The project structure feels odd
No it isn't. It's the multiprojects structure of Gradle, although I'm not sure if you ever heard of it in the first place given your reaction. In JS ecosystem this is aka monorepo but this means .NET Ecosystem actually have monorepos for almost the last two decades!
What's wrong with mocking concrete implementations? I've worked on pretty large-scale services with AWS and we did it all day everyday. I think it worked fine and don't know if adding an interface on top of them would help.
I don't really remember J2EE, but I do run into weird Javax imports from time to time. +1 on them going away being a good thing.
For the open source stuff, I don't really care that much about the politics or history of it. Maybe I should, but at the end of the day Java just seems to have the libraries I need.
And for the project structure, maybe I should have worded that differently. The structure of nested projects makes sense, but the dependency management through Nuget and the hidden project files in IDEs just seems needlessly indirect - just show me files and let me add text for a dependency like in Maven or Gradle. To be fair, I think this one is partially just me being new to the .NET world.
The Oracle situation doesn’t get heated at all, and that’s just not how Java vendors work — basically everything is 100% open-source OpenJDK, some companies just take it, add some marketing bullshit, possibly backport some bugfixes for older versions, and sell a support license for their “vendor”.
It is pretty much what Red Hat Linux does to linux.
I love the new dotnet ecosystem and use it professionally but am I the only one who thinks two years isn’t long enough for a “long term support” release?
Obviously you’ll be able to run older versions of the framework so long as the underlying OS supports it but depending what type of environment you’re in this means you’re likely going to have to update perfectly working applications every two years.
Do I think that it will take a massive amount of work to update from dotnet 6 to 8, or 8 to 10 in a few years? Probably not, but that could change at any time depending on the whims of Microsoft on that particular day.
I get that the current technical zeitgeist is that if you’re not releasing a new version every other day you’re falling behind but five years seems a bit more reasonable to me.
The upgrade process from 5 to 6 to 7 has been a total breeze, and I’expect things to continue in that matter.
There was a massive amount of churn between the introduction of .NET Core and Core 3, then 3 to 5 was quite a bit less so, and since then it’s been a non-issue. Pretty much just flip a version flag and get new features.
> Pretty much just flip a version flag and get new features.
Sure, but in many cases for an application that is "done" we're not looking for new features, per se - we're looking for security patches. Moving from one major version to the next incurs a whole bunch of testing and validation that otherwise might not be needed (depending on your environment and industry).
I view frequent upgrades in the same way as LetsEncrypt's short certificate expiry. It encourages you to create a system that you trust to be upgradeable, rather than a beast that sits, untouched for fear it rears it's head in some ugly manner.
Frankly, places that put off updates have always been a bit of a mess from personal experience and I'd rather have smaller more frequent updates that take a day or two every few years than massive irregular ones that aren't feasible to apply.
> but am I the only one who thinks two years isn’t long enough for a “long term support” release?
No, I feel the same. It really is a completely different mindset compared to .net framework. And I believe it is recommended to keep upgrading, even in maintenance mode. I noticed that Microsoft removes target frameworks from their nuget packages as soon as they are no longer supported. That could be problematic if you need a security update and are on a no longer supported target framework.
An “enterprise” environment that is used to Microsoft products is not used to that.
Odd question maybe, my company uses C# and I've been picking up more backend responsibilities. However, I'm a Linux and Neovim user. I do have Windows and Visual Studio available but I just find it awkward.
Is anyone here having success with Linux and Neovim for C#? Even trying to learn more about the language is awkward as so many resources go straight into VS.
https://github.com/OmniSharp/Omnisharp-vim is a thing, but I don’t know how good it is. I would probably go with VSCode or Rider (and their respective Vim plugins), as they are quite productive for .NET.
I’ve been using Rider in Ubuntu for a year or so, and not really missed VS. Only once when looking into the identity UI templates which required some scaffolding stuff in VS.
Rider is pretty much the only decent option for me, if Linux is a requirement. However not even Rider supports .NET Hot Reloading (Edit and Continue), because Microsoft hasn't implemented runtime support for it in Linux. Doing so would probably work against their vested interest in rolling in Visual Studio subscriptions. Yet EnC is a significant timesaver for my projects, to the point where I find it hard to work without it.
Sadly, OmniSharp (the LSP for vscode and nvim) isn't all that great. The performance is incredibly bad, easily orders of magnitude worse than VS and Rider.
At the moment I'm stuck with Rider, which is terrible (there is an official vim mode plugin), but I still have to port my bindings over to their vim config. Telescope etc. isn't available, which is a sad day.
I mostly work with Powershell, but dabble in C#. Both omnisharp and the Powershell CoC plugins for Neovim seemed to break often. I've switched to VS Code for Powershell and Visual Studio for C#, as sad as that makes me.
This is one mark I have against C#, it is not very stock vim friendly (plug-ins likely exist however). IDE support is almost a requirement for C#. I find Python better in this regard.
I use vim plugins for whichever IDE (VS, vscode, Rider) I'm using - not as good as full-featured as pure vim, but what I needs it's more than good enough.
Coming from NodeJS, the amount of stuff that could be added with a single line from an official package was great. No more worrying about hundreds of unvetted dependencies.
We're moving to .Net, and I was surprised by how poor the built-in DB stuff is. It's like either assembly or Python, but nothing in the middle.
That said I've also been impressed about how nice it is to get stuff going. I used C# back in the .Net 1.1 days and yeah massive difference in ergonomics.
Dapper seems to be in the middle and it is pretty popular
Right now EF Core is probably the best ORM that has ever existed. What exactly is missing?
Although for performance you would probably reach for something like Dapper but that is not an ORM.
1. appsettings.json
2. appsettings.{env}.json
3. user secrets (only in Development environment)
4. environment variables
5. command line args
You can full customize the setup if you desire, there are packages to support things like external secret stores. If you Google ‘Asp.Net core configuration” there’s a MS page that goes into great detail on all of this.
Anyway, your env vars must match the name as you’d structure it in a json object, but with the periods replace with double underscores. So ConnectionStrings.MyConnection becomes CONNECTIONSTRINGS__MYCONNECTION, FeatureFlags.Product.EnableNewIdFormat becomes FEATUREFLAGS__PRODUCT__ENABLENEWIDFORMAT, etc.
builder.Configuration.AddEnvironmentVariables();
Then you can use an env variable like "Foo__Bar=X" to override Foo.Bar from your appsettings json.
A simple HTTP server? Maybe I'm missing something, but when I needed it I hadn't found one.
I believe, the closest it has is System.Net.HttpListener which is a very different thing from your typical Golang's net/http.Server or python's http.server.HTTPServer.
I believe at some point they had switched from HTTP.sys to Kestrel, so at least it doesn't need the admin privileges anymore. But this whole thing is so much related to ASP.NET it's pretty hard to figure out how to create a simplest HTTP server without anything else forced upon you (no services, no "web applications", no router, just plain and simple bare HTTP protocol handler). So my impression is that maybe .NET can make certain complex things easy, but it has some issues with keeping simple things simple.
If for some reason you don’t want the framework to handle things like routing or request/response deserialization/serialization then you can go bare bones and implement everything via custom middleware: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/m...
Productive devs want the request/response wrapper objects and routing constructs to handler methods to get work done and can still drop down into fine-grained request/response crafting as and when required.
The only bit of framework-specific / hidden magic debugging I really had to do was the realization of AsSplitQuery() when creating objects composed of independent datasets, AsNoTracking() for a decent perf bump, and single group-by's are fine but when you start nesting them it gets really hairy really quickly -- they usually ended up becoming views.
Otherwise change-tracking worked wonderfully for batch-updating (but everything I did was short-lived) and outside of group-bys, the LINQ -> SQL mapping (and vice-versa) was extremely predictable, in both EF Core generating the SQL I expected, and creating the correct LINQ from the SQL I knew I wanted.
9/10 would use again; inline sql is for nerds
So much better than spring and NodeJS.
Internal error handling was sometimes abysmal too, a misconfiguration of certain dependencies in `AppModule` could leave the application in a broken state on startup where it wouldn't bind to its port and no error messages were printed to console. On a few occasions I had to spend an hour or more reading and understanding NestJS source code to resolve those issues, which could have been avoided if they had better internal validation and error logging in place.
That's not to say it was all terrible, some aspects of it were genuinely good, but the overall experience and many hours of needless pain it caused left a really bad taste in my mouth. Back then, at least, it felt like a Lego set where the pieces didn't all quite fit together.
Depressingly enough, it seemed like NestJS was the best that Node.js world had to offer which made me quit the ecosystem altogether.
I've been keeping a close eye on Next.js, which is very well done, but I love how versatile .NET is. With one language, I can write all of the above, and my dependencies are minimal thanks to .NET's rich standard library - a refreshing change from the NodeJS apps I've written and maintained.
With native AOT, .NET can even be compiled to native binaries. Recently, I wrote a Windows password filter DLL in C#, which would have been unthinkable some years ago.
It's a really enjoyable stack to work with. Kudos to Microsoft for what they've been doing with it.
I'm more shocked by you sticking with Javascript. Surely with your adoration of C# you would have moved to its closely related sibling Typescript. Although I guess there is that slight initial hump to move to TS from a purely vanilla project.
Is it somehow different than using any other language for your backend? Seems to me you're describing any frontend/backend split, nothing specific to either Nextjs or .NET here.
> I'm more shocked by you sticking with Javascript. Surely with your adoration of C# you would have moved to its closely related sibling Typescript. Although I guess there is that slight initial hump to move to TS from a purely vanilla project.
Some people prefer to stick with vanilla JS because that's what the browser ends up running anyways. Personally, TypeScript tends to get more in the way than be helpful for certain type of projects, while for others, TypeScript helps a lot but tends to be when the codebase involves a lot of contributors of varying skill-levels rather than a small circle of contributors with relatively high knowledge of programming and JavaScript in particular.
It makes a lot of sense to decouple them, and just re-write the frontend to whatever technology is the best for its time. It’s also not uncommon to have multiple frontends, for example a web application and also a native android/iOS app.
But yeah, it's definitely a huge plus to have access to .NET's massive standard library. The documentation is amazing, too. If the costs to run in Azure and to be tightly-coupled with Microsoft rthat way are reasonable for a lean/small startup or self-funded startup, then I may give it a shot again.
No need for MSDN subscriptions these days, although they do come with some perks.
.NET has been open source since .NET Core 1 in 2017. The source code is on GitHub: https://github.com/dotnet/
Using Asp.Net 7 for the server component with React and Vite as the FE tooling. Been a HUGE learning curve the first couple months particularly around the DI, options pattern, Asp.Net auth and Identity and etc but everything is falling into place now. Also SignalR is much more low-level than it pretends to be lol.
It would have been easier to go straight NodeJS as I'm quite proficient in writing even framework level code in it(down to the sockets), but I believe .Net is the better option for this long term.
It feels like the pain everyone went through upgrading from Python 2 to Python 3.
It also doesn’t help that .NET Framework has its support cycle tied to the OS, and hence is 10+ years. This means that businesses can be lazy and just leave these old apps to fester and still be technically “supported”.
As web standards evolve, I’m seeing these web apps slowly break.
It’s actually a big problem and Microsoft doesn’t seem to care much. It’s only in .NET 7 that they’ve finally introduced some incremental migration features, but they’re buggy and incomplete.
As a random example of the issues: .NET Core 1.0 broke DataContract deserialisation because of a missing thing in the BCL. A decade later this is present now but they still haven’t fixed the service client generator tool!
Every time I’ve tried to migrate an app, it’s one breaking issue after another with 3-year old GitHub issues that have no responses from Microsoft.
Talking about the awesome future of .NET is great and all, but you've got to give people a path to get there...
These companies had 15 years to do it. And it was fairly easy to get webforms + MVC running side-by-side on the same site so you could gradually migrate.
Too late for that now though, you can't run webforms + MVC Core side-by-side.
You could put a load balancer in front of the old app and start moving end points to a new code base.
It's akin to moaning that MS haven't got an upgrade path from IE7. Or your Adobe Air app has stopped working.
On the plus side, doesn't 4.7 still have a huge support window because it's tied to one of the windows server versions?
I pointed this out in 2013 only to be literally shouted down by my manager. I did so again in 2017 under a different manager on the same team with the suggestion that we investigate using SPAs and RESTful frameworks only to be told that Razor Pages was the way forward which, while an improvement, didn't do any wonders for our ability to attract/build technical talent or create rich user experiences.
As a sibling comment points out (in a sentiment that I've echoed on HN before):
> ASP.NET Web Forms are a complete trainwreck and an abuse of HTTP and other basic web development standards (e.g. by using javascript: URLs and POSTing forms for every single interaction with the page). It is broken by design.
You can probably see why developers that chose this framework in the first place aren't interested in upgrading... learning actual web standards and state management isn't something they wanted to do in the first place.
The vast majority of ASP.NET Web Apps could not have migrated to .NET Core 1.0, it was missing too many features. It was missing types like 'securestring', and had zero support for Workflow Foundation, Windows Communication Foundation, etc...
At the time, .NET Core was also advertised as "an alternative platform for Linux apps", not as a direct replacement for .NET Framework.
It was only in .NET 5 that Microsoft changes their tune and started calling Core the "replacement". At the time, something like half of complex enterprise apps might be able to migrate across, but they would have encountered a long list of breaking issues with a note saying "we might fix that in an upcoming major release". That's after a partial rewrite.
You can't go to a business that has a web app that's "not broken" and suggest migrating it to a definitely broken platform that's very much still playing "catch up".
Support is improving in .NET 7, and the upcoming .NET 8, but it's definitely not 100% and pretending that it's the "end users' fault" for not jumping onto an incomplete and buggy platform is not helpful.
I'll list some random GitHub issues for you to perouse. For large enterprise apps, many of these are showstoppers for incremental or seamless migrations. The workaround is always "rewrite everything from scratch using wildly different technologies that aren't direct replacements."
Besides the obvious IFRAME approach, one could have a single solution with both a ASP.NET Web Application project and another MVC (or Blazor) project. Both of them would reference shared models/services via some .NET Standard 2.0 project. IIS can host ASP.NET Core.
Then start refactoring and rewrite the old HTML4/CSS2 into HTML5/CSS4, while the Server Controls and Master Pages become Razor Components.
There is definitely an upgrade path.
Their complaint was that people invested a lot of resources into a technology that Microsoft promoted, and then that technology hit a dead-end with no good upgrade path aside from "rewrite it all!" What year that occurred is irrelevant.
Ironically you brought up MVC 1.0, which Microsoft did EXACTLY THE SAME THING TO, when they released Asp.Net Core MVC which also has no direct upgrade path. In fact, it wasn't until the last twelve months that Microsoft even tried offering anything when they realized it has been ten years and a lot of companies remain stuck to this day on .Net Framework.
Yes, Web Forms was poorly designed. But this is about Microsoft's poor upgrade offerings more than any specific technology, and an import lesson for people investing time/resources into Blazor today (given that it uses a proprietary WebAssembly compilation system and a proprietary back-end not dissimilar from WebForms in terms of lock-in).
.NET 4.8 is still fully supported, and there is no end-of-life communicated yet. It is a part of windows server 2022, which will be supported until 2031, that’s probably the earliest possible end-of-life date for .NET 4.8.
I don't understand why people are coming out of the woodwork to tell everyone that full rewrites are a perfectly normal and expected regular occurrence that you should expect from your tech choice. Python 3 is famous for how much they hurt themselves by ignoring the problem. Many companies never did migrate from 2 to 3, and instead picked tech with better guarantees. I expect the same to occur with .Net Framework.
Or maybe it will not be supported as in "we won't provide support for any applications needing .NET Framework, but they may or may not still work"?
Old .NET Framework was a main, Windows only, branch of .NET.
At tag "v4.x", a new branch named 'Core' was created. Core was a multiplatform version of .NET.
There were three tags in the Core branch: v1, v2 & v3.
Then Core jumped from v3 to v5 and was merged back into the main branch. ".NET Core" has replaced ".NET Framework". Also, v5 dropped 'Core' from the name and was named just ".NET 5".
Development now happens on the main branch and has already reached tag v7. A new tag is created each year.
Deleted Comment
I use Rider from Jetbrains, develop on a mac, deploy to Linux on AWS, it would blow the mind of 2003 me to know this was the case.
- Unit testing with mocking is kludgy compared to Java and Kotlin (Moq vs Mockito). There's no mocking of concrete implementations for technical reasons, perhaps unless you shell out money for a paid product. This leads to folks putting interfaces everywhere so that code is testable.
- Along the lines of the above, everything feels a lot more corporatized or tied to Microsoft. The open source ecosystem and tooling around C# isn't to the same level of the JVM langs.
- The project structure feels odd. Solutions hide a lot of files from you, whereas JVM langs generally show what's actually there.
When it comes to actually writing implementations, I don't mind it, and it's far ahead of, say, Java 8. ASP.net might even be ahead of Spring in a few ways. But with Java 20 and Kotlin around, I don't feel compelled to move to it as a new default.
With Moq and most mocking libraries, you generally just need to make a method virtual for mocking concrete classes.
Most mocking libraries use Castle Project's Dynamic Proxy, so they should be able to inject things without the need of interfaces. Interfaces for everything comes from the .net community's obsession with patterns, abstraction, clean architecture, and DDD.
You can use vscode with file based projects. With Rider/Visual Studio you can show hidden folder so long as they are in a folder or subfolder of a project.
Otherwise, you'll need to add a solution folder and items to the solution folder.
VSCode has been my way forward for file-based editing so far. It's not so bad - just feels like I'm doing things that I ought not to be when I'm searching for DLLs or a random "scripts" folder in the root folder of our repo in Rider. In IntelliJ IDEA, all of the folders are just sitting there, ready for quick edits.
I think C# overcommitted on interface-driven design. It's good in some instances, but the more I work in code the more I think that the majority of it is needless and oftentimes harmful to maintaining a healthy code base.
Thanks for the pointers! Nsubstitute looks cleaner than Moq at first glance.
That was always halfway between oxymoron and forbidden magic.
That's an obvious anti-pattern in the first place, especially when you know the optimizer could inline hot code and optimize the function out.
> Everything feels a lot more corporartized or tied to Microsoft
Remember J2EE and the confusing javax stuff? They're the same and fortunately both are waning out.
> The open source ecosystem and tooling around C# isn't to the same level of the JVM
Isn't that because of the open source community's refusal, rejection and resistance against Microsoft? Not only open sourcing is a first mover takes all, but specific to Microsoft they have been known to be hostile to open source in the past, most prominently one of the former CEOs of Microsoft blatantly called Linux cancer and what do we have today (https://www.theregister.com/2001/06/02/ballmer_linux_is_a_ca...)
Also, it is very well known Microsoft tried to spread FUD in the past in order to kill Netscape Navigator and tried to kill Java until it is almost being antitrusted to the extent of Baby Bells (https://en.wikipedia.org/wiki/Breakup_of_the_Bell_System?wpr...). Still Microsoft is not friendly nor hostile towards open source given that they let Mono lived, despite using Microsoft's trademarks and patents (you heard me right, dotnet has several patents and ECMA standards before!)
It's not like we dotnet people don't know the past shady shit of Microsoft, but I do believe in a convicted criminal could learn from the past, correct itself, move on from the past and be a better person off the record in the long run.
It's like a big bully tried to beat off a skinny nerd but now the nerd is as big as the bully now, and all of a sudden the bully found its conscience and begged for apology. It is natural for the nerd to not accept it in the first place. Except when both are nerds and the analogy may sound kinda odd.
But I also do understand not all people thinks like that especially for the open source community who is wary of Microsoft may attempt to commit a FUD to the open source community and they do have their memory and thus reactions, I don't have any means to control it. In fact most ordinary people would still choose to reject a convicted criminal in their community instead of accepting even if they have stopped the behavior, because it is a social stigma that indicates this person is of high risk
And contrary to Java world, the Oracle situation is getting more and more heated due to its predatory licensing agreement and people are flocking to other Java distributions. This could tear the Java ecosystem apart because it is the .NET Standard situation again and I'm pretty sure histories repeat. By the way, fragmentation is what ultimately killed MIPS and I think RISCV is on the watch.
Alas, time as always will tell, just like it's either hit or miss. We should look for a longer vision and see how it shaped out in the futures.
> The project structure feels odd
No it isn't. It's the multiprojects structure of Gradle, although I'm not sure if you ever heard of it in the first place given your reaction. In JS ecosystem this is aka monorepo but this means .NET Ecosystem actually have monorepos for almost the last two decades!
I don't really remember J2EE, but I do run into weird Javax imports from time to time. +1 on them going away being a good thing.
For the open source stuff, I don't really care that much about the politics or history of it. Maybe I should, but at the end of the day Java just seems to have the libraries I need.
And for the project structure, maybe I should have worded that differently. The structure of nested projects makes sense, but the dependency management through Nuget and the hidden project files in IDEs just seems needlessly indirect - just show me files and let me add text for a dependency like in Maven or Gradle. To be fair, I think this one is partially just me being new to the .NET world.
It is pretty much what Red Hat Linux does to linux.
Here I expanded a bit more on the topic: https://news.ycombinator.com/item?id=35249701
Obviously you’ll be able to run older versions of the framework so long as the underlying OS supports it but depending what type of environment you’re in this means you’re likely going to have to update perfectly working applications every two years.
Do I think that it will take a massive amount of work to update from dotnet 6 to 8, or 8 to 10 in a few years? Probably not, but that could change at any time depending on the whims of Microsoft on that particular day.
I get that the current technical zeitgeist is that if you’re not releasing a new version every other day you’re falling behind but five years seems a bit more reasonable to me.
There was a massive amount of churn between the introduction of .NET Core and Core 3, then 3 to 5 was quite a bit less so, and since then it’s been a non-issue. Pretty much just flip a version flag and get new features.
Sure, but in many cases for an application that is "done" we're not looking for new features, per se - we're looking for security patches. Moving from one major version to the next incurs a whole bunch of testing and validation that otherwise might not be needed (depending on your environment and industry).
Frankly, places that put off updates have always been a bit of a mess from personal experience and I'd rather have smaller more frequent updates that take a day or two every few years than massive irregular ones that aren't feasible to apply.
No, I feel the same. It really is a completely different mindset compared to .net framework. And I believe it is recommended to keep upgrading, even in maintenance mode. I noticed that Microsoft removes target frameworks from their nuget packages as soon as they are no longer supported. That could be problematic if you need a security update and are on a no longer supported target framework.
An “enterprise” environment that is used to Microsoft products is not used to that.
If you are using BinaryFormatter you certainly will have some work ahead of you.
Is anyone here having success with Linux and Neovim for C#? Even trying to learn more about the language is awkward as so many resources go straight into VS.
Deleted Comment
https://github.com/dotnet/runtime/issues/12409
So the most efficient C# development solution for me is going back to Windows and Visual Studio. As they want it to be.
Hot reload works mostly fine in Rider on Windows.
There is this alternative LSP, which I plan to try out still: https://github.com/razzmatazz/csharp-language-server
At the moment I'm stuck with Rider, which is terrible (there is an official vim mode plugin), but I still have to port my bindings over to their vim config. Telescope etc. isn't available, which is a sad day.
You can always use vs code however.