I must say props for the insane compatibility that was kept over the years/decades!
Even migrating some apps from vb6 was relatively easy, that effort shouldn't be underestimated.
A minor nit would be with Silverlight, but I wasn't affected by it. I didn't use much of wpf because of that though. Since around that time, everything migrated to the web.
On the bright side, a lot of Silverlight code still works since it wasn't a completely separate class library etc. Back when I was still working on JSIL, I had one enterprise customer who was slowly porting over a huge pile of Silverlight code to run on top of my stack. It was more feasible than you'd think since so much of the code could be used without modification. You basically only had to replace the frontend.
But for the people that migrated around that time to it, I suspect a deprecated framework ( although functional), probably wasn't what was anticipated.
Although being open source and free doesn't necessarily make it open and accessible. The core CLR team do not listen to customers, particularly ones who complain about not wanting telemetry by default in there, ones who open bugs in the HTTP stack which spam logs for months and months and months and complete deadlocks and crashes.
Open Source has only completely absolved Microsoft of any responsibility to support their products to actual paying customers, who are told to open github issues now which are auto-closed after being ignored. I'd rather invest my time in any other platform without the other issues that it brings at this point.
That bit about SSCLI is only about half true, at best. The original version of .NET was developed on Windows, but they contracted Corel to implement the cross-platform bits they wanted for SSCLI. Those bits only existed in SSCLI; it was never integrated into the actual commercial .NET implementation. SSCLI is not a snapshot of the actual .NET Framework code; not like the later Reference Source is.
I think in 50 years if Microsoft is still around, it’ll probably be because of .NET. For a company I have very little time for, .NET is an exceptionally awesome tool and ecosystem.
It's really not. It's a hellscape of insanely rapid platform churn, abandonware, payware and half-assed bug-ridden copy implementations of libraries from other ecosystems all stuck together with marketing crowed from a bunch of people with Stockholm syndrome.
I have literally used it along side several other ecosystems for the full lifespan of it from beta, and it has in large been a very very expensive mistake in the long run compared to the other platforms.
I always used it without the desktop gui frameworks and didn't have this experience, aside from a couple of abandoned 3rd party tools. One web thing I did has been chugging, unchanged for 15 years. Overall it has been great for me.
But getting sucked into silverlight would likely have soured me on it.
Agree on the desktop. The peak of development was when Windows, Visual Studio and .Net framework releases were synchronised and we were targeting Windows Forms. That was almost bliss. I got so much work done.
That started in 2002 and ended in about 2010.
I built some stuff in C# on Windows CE as well which was interesting too.
CE development must have been interesting. Not sure I ever saw a CE device that had enough room left over for another program.
Back when I switched to .NET the future looked like web apps. Can't say I am particularly prescient but of all the tech in .NET, the web stuff thankfully had the longest legs so I'm kinda glad I avoided the slow death spiral of MS's ever changing desktop moods.
Your response is not only hyperbole, but also not very consistent with, like, reality.
If you've really used .NET "from beta", you'll know that the platform became a snoozefest around 4.5, only to be revived around Core 3.0. "Insanely rapid platform churn" it is not.
And abandonware? Silverlight, sure, not much future in that (although it still runs fine on its own) but how is Adobe Flash doing these days, talking about "other platforms".
Java Servlets - these are backend services. Those run fine even today and are 100% supported by at least 2 (there must be more, but I have not checked) app servers that I regularly use.
I don’t think you know what you’re talking about nor have dealt with significantly sized enterprise platforms.
In fact there was a hell of a lot of churn while Microsoft pissed around with the MVC middleware stack implementation and throwing async in which has been buggy as hell on classic. And of course there was the entire “we decided to gut WCF and WWF and AppFabric” thing.
I lost count of the hours I spent digging through deadlocks and spinwaits.
On .net core there have been many many breaking API changes over just the last three years which have broken everything from libraries to the stack. There has also been absolutely zero to no guidance on what best practices are in the current hour. All the documentation and articles out there are obsolete within a gnat’s fart of time after they are written.
There was a lot of change and not a lot of thinking that went into the platform over the years. This costs big money for clients.
Well, I don't know what you consider "significantly sized enterprise platforms", so I can't really refute you on that. Maybe, possibly, include a small example here?
Your complaints about the "MVC middleware stack implementation" only underscore the fact that you're making unsourced allegations here. DotNET middleware has been remarkably stable, only requiring some minor adjustments to source code.
So, really, can you give me one, just one concrete example of how .NET has "costs big money for clients"?
Software maintenance costs money, yeah. In Java, in Golang, in (dare I say it?) Rust, in C#. But is the latter platform really that much worse than any of the former?
Particularly I am talking about Django and ASP.NET. I find Django to be a lot more productive and pleasant. Supporting open source libraries/projects are thinner for .NET.
That is hard to quantify, besides the raw package count, but is a general (subjective) observation I have. There are some replacements for Celery for example, but rather recent and not as capable.
Django REST Framework beats the .NET equivalents hands down. The Django ORM is better than EF, IMHO. Django comes with a command line framework (which can somehow be integrated into .NET projects probably). Reloading times are faster. IMHO the template engine is better.
I like F#, which is more pleasant to work with than C#. But it's hard to get a team going with F#, because it is also harder to learn.
Well it has kept me employee for quite some time now so that's something to celebrate.
The opposite side to that it I think every commercial .Net system I've ever worked with / on has been an absolute mess. Not sure if it's .Net or the companies but something there seems to attract devs to make ill performing, over abstracted, confusing, massive architecture systems that in reality could be simplified down to a bunch of data forms.
As I say I shouldn't complain keeping these things running pays my bills.
I never came across code older than 2-3 years that’s not a complete clusterfuck. So looking at it from this side, the fact that it still runs is more of a sign of quality, what do you think?
We don’t communicate via GitHub any more. See my other comments.
Also the assistant doesn’t help with the numerous third party components which were never ported to core, the entire MVC stack internal changes or the changes that took place in NHibernate. So even if it did work it’d break everything in the process.
But I should mention that nhibernate is not even in the dotnet foundation and not supported for .net core ( I visited their site and it mentions dotnet framework).
I have my own theory on this.
Green-field projects are usually whipped up and rolled out by the experienced devs in the shop.
Once the boat is in the water and floating,
the senior devs are posted off to next new-dev initiative,
and the following maintenance/deployment work is assigned to less and less senior devs, and/or student programmers.
Within 2-3 years, those inexperienced devs have mangled the original design into unrecognisability, and the application accumulates instabilities from their bolted-on "fixes".
A different perspective is that the original creators are never allowed back to fix their design mistakes.
I don't know if it's universal, but I have sure seen it in a lot of places, and I have myself been in most of those roles hinted at.
Disclaimer - my job is literally to take on the long term maintenance of those green field projects.
I wouldn't necessarily blame it on a lack of seniority or inexperience, it's a matter of not knowing the initial style, decisions, and limitations, as well as the vagaries of time. I find myself creating duplicate functions not because I wouldn't reuse the ones that exist, but because the original one was hidden away in a different place than I'd ever think to look for them. My approach is different and drifts even further over the years, I can't help it, so that the project starts to look stranger and stranger comparing the old code to the new. The original designers would find their style drifting too if they had to take care of a system for that long. They are just lucky enough that their style drift has project cut-offs, so each slice seems more cohesive.
I also don't know if this is a current maxim or not, but there should be a software principle that matches Peter's - every successful system will grow until it reaches a point where it's no longer successful. More and more requirements get added on, and unlike initial requirements where you could justify keeping scope tight due to staying lean, a system needs to grow beyond it's current limitations or it dies.
An additional side effect is that management fails to understand what/why is going on and overvalues the skills of the "experienced devs" and undervalues the skills of the maintenance devs because they don't understand the order-of-magnitude speed advantage enjoyed by devs when writing greenfield code.
"Experienced Developer A wrote the whole damn system in three months! Now Maintenance Developer B wants three months just to add a few buttons?!?"
I've been both the experienced person and the junior maintenance person.
Exactly! As a maintenance dev, you tend not to get much praise, you need to continuously explain why things take so long. I'm currently adapting some code that is, in the eyes of management, adding an extra little wire, which should not be more than a day of work. In effect it will be more than 4 days plus some overtime...
Yeah. I've been in the industry for 20+ years and I have not figured out a way to "shine" when tasked with maintenance work, other than finding ways to avoid such roles entirely.
The root issue is that management never seems to be able to grasp things on a technical level. I've tried to communicate this over the years, and have been praised for my communication skills in general, but I've never managed to bridge this particular gap.
It's also that requirements often change in ways the original design hadn't foreseen. And usually there's no time for a decent redesign, so things get hacked together and slowly degrade hack by hack
I had to debug some of my own 15 year old C# the other day, quite a reminder of how far .NET has come. Back then I rolled my own ORM and it was fun but not a patch on EFCore.
One dark place some .NET devs got caught in the early days was some of the 3rd party ORMs. Nightmare of weird code, proprietary mapping tools and headaches.
I am still not sold on linq2sql either. Debugging that is never fun.
Yeah those ORMs were horrible. We used NHibernate what with being sold down the river by Udi Dahan on domain modelling etc. That was a huge mistake too. Dapper is the only ORM that hasn't screwed us in some way.
Early on I liked Linq2SQL, and I think I still do, but it might be just looking back with rose colored glasses.
When I thought I needed better control and performance I wrote my first ORM. Which wasn't really all that ORM-y. It would use reflection to map to an object, but queries definitely weren't linq-able or using IQueryable and walking the predicates to dynamically generate queries. It was more like dataBase.TableName.First("id=@id", new {id = 1}); Which would generate "select * from TableName where id=@id" nothing earth shattering. Joins were done through dataBase.Join(new [] {"table1", "table2" }, new [] {"on table1.id=table2.table1_id"}, "table1.id=@id", new {id=1});
It was ugly and I eventually just replaced it with straight ADO.net.
I tried various other ORMs over the years, I eventually just settled on EF since it was not bad, and generates almost sane SQL most of the time.
It always made more sense to me to have a sanely-designed database first and then generate the mapping code from it, rather than the code-first style that seems to be popular with EF. You can do the database-first mode with entity framework, but it is less the happy path that the tooling and documentation tries to nudge you into.
I've always been frustrated that active record ORMs have completely overtaken tools like Linq2Sql.
I don't deny the value of the active record pattern where it works, but in almost every case I've used SQL over the past 5 years, I don't want a complex abstraction layer. I just want something to make it easy and safe to talk to the database for the 90% of straight forward queries we write.
With something like that, I feel as though I'd rather write my own active record system than use the configuration based systems we see with EF
I'm kind of sentimental for EF, as I think it can be a handy tool, but in my experience, ORMs of any kind are not suited to serious work, they usually assume that they own the database creation, which is fine when you are building a webshop, but obviously not, when you are interacting with a large existing database.
ORM-lites, such as Dapper, which only bind query results to objects, are an obvious exception thoug.
It’s my experience that ORM “frameworks” are a net negative for anything that needs scale or performance. They’re optimized for demos and quick setup but fall apart as soon as the system needs to scale. Straight deserialization is generally a win but the “magic” never is and fighting with it when it doesn’t work is way more pain that writing some SQL.
Every time I’ve seen a project use an ORM past the proof of concept phase, it ends up with some garbage layer to bypass or “trick” the ORM into doing something acceptable. (e.g. Complex materialized views presented as tables to the ORM so the ORM can just do straight selects without joins).
Speaking of databases: In my experience, denormalizing usually doesn't help either with performance. Hell, often normalizing it more leads to it actually being faster. (Assuming appropriate indices)
>One dark place some .NET devs got caught in the early days was some of the 3rd party ORMs. Nightmare of weird code, proprietary mapping tools and headaches.
Also EntitySpaces. Not sure what they were thinking. Anything that used EntitySpaces needed a complete re-write as it spawned a living hell of class definitions and mappings that locked you into a particular style of programming that was hideous.
I've stopped caring but if I had to I could be paid a lot more to do something more productive. But sometimes it's nice to sit there and watch visual studio crash 30 times a day or lagging out when I hit a key because it makes me angry enough to go for a walk which I really enjoy :)
Yep. Almost all old code bases are like this. Complexity inevitably grows over time, and old code lingers. People leave, and knowledge often fails to transfer. This is why developers prefer to work on new things: it's more fun to make the mess than to clean it up. Plus nobody wants to pay only for "maintenance"... you have to work it into other projects, which is often easier said than done.
What these all have in common though, is encouraging shared mutable references, they don't do a lot to make effects in a system explicit, don't encourage a clear organization of code, and many fundamental concepts (functions as values) were missing early on or still are (discriminated unions)
I agree that pretty much any 15 year old code base is going to get rough, but I think these languages have some clear footguns that aren't doing them favors either. I work on a codebase that isn't more than a few years old, and there's complexity issues from simple things like the language lacking good semantics for transforming data immutably, and that complexity spirals
I can attest that writing messy processes in languages that do address these concerns is absolutely possible, I've done so myself, but the mess is contained to a particular area and it's not as hard to follow which pieces of a system feed into another. Things as simple as making immutability the default and mutation explicit like Rust, and requiring modules be organized into a hierarchy like F# are huge wins. As much as I've gotten annoyed with F#'s project files hierarchy requirement because it requires some extra work/considerations for codependent types and codegen, it's amazing how much easier it is to jump into a new codebase where you can clearly see to understand behavior you start with the bottom of the file list, and to understand core logic/patterns you go to the top of the file list
You can possibly work with and update a C# program because of the incredible longevity/backward compatibility of the core libraries, and reasonable commitment to this in the culture of the ecosystem.
But in Javascript land this can easily or even typically hit a point where the errors from package churn are so much that economically the juice is not worth the squeeze, in a literal order of magnitude less than the typical C# system.
My company has multiple applications written in jQuery and Bootstrap that are now 10+ years old and going strong. We've been using Node.js on the backend for a little over 3 years now and those apps aren't going anywhere for quite some time. I think the notion of the continually shifting Javascript landscape has been overplayed. To wit, C++ has been changing more frequently than Javascript has!
I liked seeing the expressions of frustration when developers that were sloppy with their coding style were no longer able to get away with code that didn't meet the coding standards.
When it was adopted it literally made some people scream in frustration, and I loved it for that.
The default ruleset of StyleCop is absolutely brutal and unforgiving with messy code.
I tend to be of the camp that if a tool can automatically detect issues, they usually aren't that important of an issue. The real messes that lose money can't be cleaned with a formatter or detected with a tool.
I was tasked with running an autocorrector on all our code once in 6 months. On average, out of thousands problems it detected, 1-2 came out as real hard bugs, that would never been caught by programmers or the testing team. 1-2 bugs for a day of work is not that bad.
Exactly, survivorship bias.
I find C# to be a beautiful and elegant language. And if you wanna see what .net is capable of, you have to look at core projects, asp.net, entity framework, ml.net, ...
Not what random businesses and their poor specs built in a haste project look like.
I really think this is because of the way companies act and not the fault of any technology. We work in a field where companies really believe they should try for the cheapest labor possible without thinking about the consequences. When written with thought programs with .NET or any other platform work well. When you start replacing the person who had real knowledge and experience with the recent boot camp grad, "because that was the more affordable option" that's when problems start to arise.
I wonder if this is because the languages we use today like C#, Java etc evolves mostly horizontally, like standard library improvements, syntactic sugar, performance etc, instead of vertically like higher abstraction and modularity.
What I’m trying to say is that we lack abstractions to model our intent on a higher level.
I think that is why we invent things like micro services because we can’t express modularity on higher level good enough , when that type of abstraction should be built into the language itself (and irrelevant if it is on a separate network node or not).
I guess Java modules is a go at this, don’t know if successful or not.
That is how I at least feel when I’m maneuvering huge projects, a building block is missing.
It makes me really sad to read things like this. .NET/C# gives you the tools to write elegant, performant code in any domain, and really rewards high level of expertise, with stuff like advanced parallelism support, and optimizing things like memory layout with structs, really great native interop story, or the ability to write Source Generators/Analyzers, so you can develop AST-parsing compiler plugins to do stuff like automated code generation/analysis.
Imo it has a way higher skill ceiling, than something like, say NodeJS, which is supposedly part of the cool kids club.
I have literally had conversations with hardcore devs that had the 'enterprise offshore-bait' perception of the language and were surprised when I showed them all the awesome stuff you can do with it.
It's very much a problem with the orgs and the typical culture at these types of orgs. It's not a problem with the tech.
Someone mentioned Unity. I'm really curious as to what typical C# Unity codebase looks like since I imagine a Unity game dev shop would culturally be very, very, different from a big enterprise .NET shop.
I would argue the 'standard' Unity game dev shop are made of experienced burned out developpers from 'standard tech' big shops managing enthousiastics but 'incompetents' (I quote the word i'm not sure it's the good one, it's not they are bad as persons but they lack experience and game development school have an abyssal level of formation in programming) interns, wich is not different than a lot a place I worked before going to game development (and sometime as the enthousiastic but unproductive intern myself of course) ^^
My impression from hanging out on Unity forums / reading tutorials/ code snippets, is that the usual Unity developer is not a very experienced coder, often getting into programming to make games, or lacks a traditional SW development background and wants to just make cool stuff, without a regard for typical SWE concerns. Not that any of this is a bad thing, mind you.
Not sure about how representative is this of the typical professional Unity dev.
This is microsoft not .net's fault. .Net was just jam to spread over the turds.
Microsoft tried to jump on every fad that came along and proceeded to burn all the old ones yet still keep the customers limping on them.
Lets not forget stuff like Velocity, DNA, AppFabric, Workflow Foundation etc all of which we had to spend millions rewriting out of products. Before that it was the C++ frameworks: MFC, ATL etc etc etc.
Absolutely still a thing! Formulas forever. I don't like the macro deployment story fully so dialed that way back -> if you can worth avoiding I think.
If I could have rolled back time I'd have used Java and Spring.
If I pick now it'd be a composite application based on microservices built in pretty much out of the box Go. I have a proven 8 year low maintenance cycle project on that already because Pike Et al actually think about the past and future before they release stuff.
I used WinForms actually, with drag and drop in the designer you could very very quickly get basic line of business apps going. You could write apps using this type of "old" outdated tech for a long time (I know most moved on, I didn't).
One thing I've been enjoying recently is slack / zoom bots. It's basically a CLI that is accessible to an entire team. I've found the efficiency fantastic. So for simple line of business needs where a quick winforms app might have worked, something to consider.
I started with some very simple items, and then just kept building. It's immediately usable by staff from an office manager to someone very technical. The deployment story is fantastic -> no one has to do anything. Matches web apps that way. This beats winform apps for me.
You get a front-end without much hassle. If someone doesn't give a command in expected format I do exactly what I'd do with a CLI, give them a help response. It's the command line for non-command line people, and the efficiency is great.
Deployment side moved to AWS RDS (postgresql) for the data store. AWS ECS for the containers. ECS Anywhere for stuff that is heavy compute where AWS can get expensive. Scheduled jobs (ECS again) for data load work, added a freshness indicator to responses to users as additional monitoring. Went from self hosting assets to signed s3 links that expire following asset generation. This is a bit slower then doing a straight http server but again, the maintenance reduction is great.
This is for small in size databases with a perhaps 100M records x 4 tables maybe. Also doing some live lookups / crawl type work based on commands to supplement database, again ECS.
I ended up moving off SimpleDB (old AWS product not offered but they kept it running) to dynamoDB and then to just postgresql for everything. For large data loads despite the flexibility/scalability of dynamo, I just couldn't get it to really deliver and the performance / feature set on postgresql for the price and just being on one datastore worked out far better for me. I don't pretend to be a dynamoDB expert so the big loads are probably something I wasn't doing right
RDS is fantastic in my book, upgrades / backups etc in particular -> I'm a huge fan. I wish AWS would break out revenue by product, that has to be raking in the money along with EC2 / S3 and data transfer.
If you have compute needs, ECS anywhere feels like cheating. Basically, you can take a almost home level AMD Ryzen box with a bunch of ram, get the disto/agent on it, and try your jobs there first. Makes you realize how much we give up in the cloud in terms of cost/unit compute. If box is offline, you can fall back to ECS. Not sure exactly why they offered this product -> it saves a ton.
Anyways, that one solution that has been rock solid stable, easy to deploy, and covers a surprising amount of ground and user picked it up quickly.
You also get authentication pretty much built in as well.
The hackers here obviously call this "laughable", but I'd encourage folks tired of all the layers of crap to give it a try, just start scratching small user itches - the usage I've seen has been fantastic with no push.
BTW, the interface feels fast to users because they are just typing, don't have to login or go anywhere etc.
Not sure what you’re implying here. Those technologies, especially WPF with XAML, allowed me to be insanely productive developing desktop apps back in the day. In a way XAML is the precursor to stuff like React native and the like.
Granted, I feel like MS dropped the ball in failing to have an overarching vision of how their .NET technologies would work together and evolve for the future.
As a user (not developer) I liked Silverlight at the time, compared to Flash. Flash applications made my computer run very hot and the fans go loud. With equivalent Silverlight apps on the other hand my computer didn't break a sweat.
Developing for Silverlight was also great, full power of abstractions like LINQ and the BCL, with the holy grail of two way design to code and back with Blend and Visual Studio.
Technically a big pity that the market wouldn't accept a Microsoft platform for competitive reasons, but I can also well understand that. Just a shame the wonderful technical platform was lost and we ended up with the lost decade of Javascript front ends.
I was on the user side of silverlight mostly, and also really enjoyed it. I'm not sure why, but it ran nicely as well (speed etc). Flash crushed my machine. Javascript had jank at the time. Java apps for some reason were always slow (dev style and frameworks, I know language was fast)
You are basically selling your soul to Microsoft. Microsoft is controlling virtually all development even on the open source side.
Also, expect to write 5-10 times more code than with other popular languages. You may not notice this when you come from Java or C++ because then it is an improvement.
It’s bullshit. There is not even a 2x factor between high level languages when it comes to productivity (and lines of code is a shitty metric to begin with. Typing speed is most definitely not the bottleneck for programmers)
To be pedantic, It is entirely possible in .net to have either multiple classes per file or multiple files per class.this has been in since least .net 2
No it's not "idiomatic". Stop this nonsense. Look at the biggest C# code base, ASP.NET Core, and there are many instances where this is not the case.
You don't need to preface a method with `private` to be so but people still do it, why? My theory is the influx of Java dev influences, same with the "One class per file nonsense".
Where I work it is a hard convention. It is also a sensible convention because anything else makes the codebase even harder to navigate/refactor and whatever.
When working in teams, you really shouldn't put more than one class in one file, except for rare exceptions of very small and inconsequential classes. Otherwise the files get pretty big and the chance of merge conflicts get bigger.
The underlying problem - in my opinion - is that C# encourages you to overcomplicate things and that it is relatively verbose. Of course you can put a class with multiple members and methods in one line. But then it's also unreadable. Readability matters.
All languages with a syntax derived from C have a fundamental readability/verbosity problem, C# is no exception. F# for example doesn't have that baggage and is a lot more concise.
It is a convention, but not entirely without reason. Breaking the convention leads to other problems.
You still need a metric shit ton of classes, so finding any one class gets harder. The chance of merge conflicts increases because of more lines per file.
I don't hate Microsoft. You just need to be clear that if you build something with the .NET ecosystem, you are fully dependent on that company, even if some people want to suggest otherwise. And this seems to bite people occasionally.
.NET is open source. You're not dependent on Microsoft at all if you don't want to be. If Microsoft closes shop tomorrow, .NET will live on.
You've got a minimal amount of .NET experience (based on your own assertion 3 months ago) and you're spouting incorrect/false information. You were forced to use .NET, maybe that's why you're so unhappy with it. I've used C#/Java/Go/Python/Typescript/JS in my professional life and I've never felt more productive than when I'm building software with C#/.NET. Is it perfect? Not by a longshot. If I had my way I'd be using F#, but alas it's not popular/well-promoted (that I blame squarely on MS.)
If you think .NET will continue without Microsoft, you are delusional. It won't "die" as in the codebase disappearing, and there would even be the occasional patch, but the project and platform as such would essentially be dead in the water.
You are also beholden to the direction Microsoft wants to take the project/platform. There is nothing the other open source contributors, such as there are, can do about it. Fork? Maybe, but there's not THAT much activity around it anyway.
Again, all of this is a risk or "situation" one may be happy to take. Just be aware of it. At the end, .NET is more code, harder to learn, harder to recruit for, easier to over-complicate, and the ecosystem of libraries is thinner than with Django, Python and Javascript.
Others are downvoting you, but this is a perspective I appreciate as it is something I have been thinking about. Although I don't think selling out to MS is a large concern for me at the current time. I do think in the future it is important to become more independent and versatile.
Depends on what you are doing. I'd also question the need for "compiled language" in most cases.
.NET is sometimes/often chosen for "performance reasons". In my opinion, for websites or web applications this is completely bogus. ASP.NET will slow your development down so much (compared to Django/Node/PhP/RoR) that you won't see any of those benefits any time soon.
Microsoft will frequently hype up things only to drop them 1-2-3 years later. Beware of the hype, especially when coming from MS.
Also, keep stuff up-to-date, MS will at the same time maintain things forever and drop them mercilessly (look at .NET framework itself; it still runs - so counts as "maintained"; but if you didn't migrate to .NET core/ .NET5 / .NET6, you're in a very bad position for the future. With the announcement of .NET core they made a lot of code obsolete).
The previous two things combined create a somewhat bizarre situation: you want to keep up to date with the latest things MS is up to.... but not TOO up-to-date, because you can get into the "hype that will be killed" train. E.g. .NET core 1 was too early to jump onboard - wasn't clear that it's not going to be an UWP. But by .NET core 3, you'd better pay close attention and be ready to invest whatever it takes to move on to the new tech. Probably around .NET core 2.1 was the moment when one should've confidently said that "MS is serious about this .NET core stuff"? (though the exact timing is of course debateable)
.NET Framework was actively developed for two decades. It's not a jab at them to finally move on to a new runtime while simultaneously providing a very excellent migration path.
And all the things Microsoft "hypes up them drops after a few years" have low adoption compared to their main offerings anyways. It would be silly of them to continue actively developing things like Silverlight when everyone saw that better options were available.
It makes perfect sense to do what they do! And in all honesty sometimes they grind for a very long time before achieving true success (see: Xbox).
That said, people don't always realize how many things Microsoft tries (and subsequently abandons, because of course not all of them are going to be a success). That .net core was a success is clear now; but you could've easily believed that UWP will be a success and invested in it (in fact, I know teams who did, with really bad consequences for them). What I say is... just wait a bit. In the early days, not even Microsoft knows what will succeed, and they will "sell" their new initiatives very hard (of course!).
The main important historical fact is the jump from .NET Framework to .NET Core.
Core is cross-platform, whereas Framework is Windows-only.
Also, some APIs were put in before generics were introduced and thus don't have type safety. The main ramification of this is to basically always use things in the System.Collections.Generic namespace over other collections.
.NET Core is where it is now, and the UI story is (as always) evolving FAST. Make sure to build a good separation between back- and frontend, and be ready to switch
If you are lucky and you are making not-very-complex UIs, you can make a thin wrapper using some of the "newer" frameworks. If you make heavy/classic UI's you will probably have to go for WPF or a Third party framework instead.
As someone coming from Node who has only recently (with .NET 6) taken a good look at the ecosystem, it appears to me that there have been a lot of breaking changes to get where they are now.
On one hand, I love that they’re trying to reduce boilerplate and align closer to something like Node with Minimal APIs. On the other hand, nearly every reference guide or tutorial I look up is outdated and I’m left trying to figure out what changed between .NET 5 (or earlier) and .NET 6. I was following the Little ASP.NET Core book one day and things like there being no Startup.cs anymore (being merged into Program.cs) took me a minute to figure out, as there’s also no definitive resource for a newcomer on what has changed that would make older documentation inaccurate.
Both should cover the majority of scenarios. The main takeaway is that everything you usually configure in `ConfigureServices` now hangs off `builder.Services`, and everything you'd configure in the middleware pipeline `Configure(IApplicationBuilder app)` is available after you call `var app = builder.Build();`.
I'll note that the change to the Minimal API was only in the project templates, so the old model does continue to work without any breaking changes.
Is there an up-to-date guide for migrating from .NET Framework 4.8 to .NET Core 6.0 (or whatever the latest LTS is)? I guess many projects have not yet migrated, especially libraries that wanted to stay compatible.
From my understanding, that's not really a migratable stack. Depending on what you're doing in 4.8 (aspx, wpf, aka windows only type stuff) there's not a direct migration. It's more of a re-write.
I think you are only kind of right. aspx is over 10 years old, you should have switched to .NET MVC already and then the difference to .NET Core is small. We rewrote some things at an earlier company and there mostly general things like auth and where to get querystring variables and similar that had changed.
If we look at WCF to REST (or gRPC) it is also mainly easy since it is some general configurations and infrastructure things that have changed but most of the business logic will work. So you have to rewrite but it might be quite easy. And doing this once every decade is not that strange. Also remember that most of the old things still work. You can stay on those tech stacks for another couple of years if you feel that is better for your organization.
WPF wasn't left behind. It's still supported in .NET 6, you don't have to rewrite anything. Windows Forms, too. Can you be more specific what you mean by aspx? ASP.NET is, of course, still supported.
.NET 3.5 SP1 support ends Jan 9, 2029. For .NET 4.8 there currently there is no support end date. Don't think it's gonna be sooner than 3.5.
> .NET Framework 4.8 is the latest version of .NET Framework and will continue to be distributed with future releases of Windows. As long as it is installed on a supported version of Windows, .NET Framework 4.8 will continue to also be supported. https://dotnet.microsoft.com/en-us/platform/support/policy/d...
In our case, a fairly big monolith .NET 4.8 web app is being migrated to .NET Core by splitting that monolith into microservices that run on .NET Core. Can't say if it is for better or worse, more moving parts in infrastructure for sure.
It really depends on your project & how your code is split up. A lot of business type logic code should be identical.
I've migrated a couple decade plus old web form projects. A lot of the business logic can be moved to .NET Core 6 verbatim. I'll often set up a new version & slowly proxy web requests from the old site to a new version of the site as we update it.
Upgrading usually requires an enormous amount of remediation work before it's even possible. Generally you can do it like this - convert to PackageReference style NuGet packages (this one alone may even be a blocker if you have certain unfortunate dependencies which aren't compatible with PackageReference), upgrade all your dependencies to a netstandard2.x compatible version (this is often brutally difficult in a big system and you may have to replace certain dependencies outright), start swapping out DI / Logging etc with the netstandard equivalents found in .NET Core, create a new .NET Core solution file and try to compile your project to see what breaks and fix any remaining issues.
Having done this it does work, but it's fairly time consuming and for larger apps virtually impossible without massive buy-in from the business.
Thank you for this. That first one in particular is probably exactly what I needed.
I guess the one downside of having lots of documentation (and third party guides/tutorials) is that it may take some time to update when there are significant changes
I really don't understand the obsession the ASPNET team has with minimal APIs. I'm firmly in the camp of wanting things to be explicit rather than implicit, because it gets difficult to keep implicit conventions in your head as things shift and melt chasing the latest fashions.
Most of the changes are not _breaking_. There are new ways to do things but the old still works. You can have both an api controller and a minimal api in the same application. I agree that it is hard to know which version a specific blog post or tutorials works for.
The problem is that Microsoft can never avoid the temptation to fix things that weren't that broken and leave it up to you to find the bugs later. Even a theoretical "non-breaking" change like adding some more constructors broke some of our code, previously, you could add ILoggerFactory really easily and it found a single default constructor in LoggerFactory and just worked. The new overloads cause most DI systems to look for the constructor with the most parameters, some of which are not available, and then fall over.
MS need a better system for updates, every version has brought us a lot of headache although I can't really see us using anything else, which would be an enormous amount of work.
A lot of the changes are aimed at making it easier for people to get started with Asp.Net, and most of those aren't breaking changes. Traditionally Asp.Net has had a lot of boilerplate around project setup and configuration, and things like minimal APIs aim to change that. The unfortunate side effect is that it adds more complexity (more ways to do the same thing) to the ecosystem, and the newer minimal approaches probably aren't what you're see used in the typical production project.
For sure. There has been a lot of pushback in the community from both sides of that issue. They wanted to reduce the boilerplate and make it cleaner to make simpler projects (with the goal of enabling microservice scenarios). But that moved some people's cheese from the standpoint of what the recommended path is. The problem is that there's a huge amount of very good documentation on the microsoft documentation site, but it's not organized in a way that makes it easy to find.
At my company, most of us write on windows in VS. A couple of us use MacOS. We use WSL pretty often, largely for Docker and dev ops work. Our build pipelines are mostly run on Windows, unless we're making containers. We deploy to Linux (AWS Lambda mostly, but with some Debian on EC2/Fargate/Batch here and there).
I'd say that the .NET teams that I work with (probably 60-70 FTEs) are 80% Windows, 15% Mac, 5% Linux. A handful of the Windows folks are using WSL1/2. But we target Linux for everything but our oldest ( we've got a couple of 10-20+ years old codebases that are perpetually being phased out) legacy systems at this point.
I started my career as a .NET dev, and until recently was the stack I've worked the longest with. I have fond memories of working with C#.
However I am no longer interested in any job that uses .NET and have removed all mention of C# and .NET on my LinkedIn and resume. This is because even despite great recent advances, .NET still seems to be almost exclusively used by tech-as-a-cost-center enterprise companies that I have no interest in working for anymore.
I'm sure there are some great companies in some corners of the world working with C# and .NET, but as far as I can tell, they are still by far, the exception, not the rule.
I’m in the same boat. C# and F# are excellent languages. But C# jobs are as you describe. F# jobs are practically nonexistent. So, I’ve moved on to other stacks. I do miss LINQ. Other than that, I’m quite happy with Go and Node+TypeScript.
That's a good point I don't see mentioned much about choice of tech stack and impact on career.
It's not so much about the technical merits of the stack itself as about what kinds of companies and projects use that stack, and sometimes it might be worth learning some technologies you might not be particularly invested in if you want to work at those companies.
It's not easy to switch stacks either - yes you can learn a new stack but you need those golden "years of experience" in your resume, making a switch an expensive and risky proposition, so you need to choose wisely.
The landscape has been changing rapidly since .Net Core (now just .Net) matured 3-4 years ago. As you say there are a LOT of big enterprise shops out there using .Net, but more and it's catching the attention of small companies and startups. I work at a small-ish (~300 employees) B2B SaaS that has a wide variety of legacy code bases: .Net Framework, Node, Ruby, Php, and a few others. We made the decision last year to make .Net our default choice for new projects.
I'll agree upfront that it's been adopted very corporately, but it's worth noting that the Unity game engine uses C# extensively. If you enjoy video-games and one of them is on this list[1] it was likely written in C#.
Unity's dialect of C# is not really the same as .NET's C#. Even though they've made strides to keep their version of C# up to date, the way of doing most things is not the .NET way.
Unity has it's own dependency management, project system, runtime, idea of threading/parallelism, concurrency, networking etc.
Usually when one gets involved in some language ecosystem, the language is the small part, getting to know the libraries, and the idiomatic way of getting things done tends to be the emphasis. Here the ecosystems (Unity's and .NET's ) tend to be quite different.
Generally, API support is not that bad, afaik Unity supports .NET standard 2.0, which is a bit old but not ancient - the chief problem is there's stuff like async/await in .NET which is their standard way of asynchrony, but not really supported in Unity without workarounds.
Also the serialization system in Unity tends to interact weirdly with more complex .NET object hierarchies, so expect strange things to happen.
Oh by all means, don't get me started on what they did to IEnumerator or awaits. Plus they _really_ fell into a hole by trying to compete with Unreal from a graphics perspective, forcing them down the route of having to write a compiler xD
Unity made tons of strange decisions over its lifetime. Like first, they picked .NET and it's Mono implementation, which wasn't as fast as the original one, but was decent - then they kicked up some stink with the Mono devs, leading to them shipping a Mono version that was at a point a decade out of date, and performed way worse than either Mono and .NET.
Their first idea was, instead of updating Mono, what if they compiled .NET IL to C++, resulting in the monstrosity that was IL2CPP. If you are interested in what sort of C++ code it generated, here's a link:
It's full of goto-s, helper method calls, and passing around these weird helper objects to every method.
They triumphantly announced their perf gains - compared to their own old impl, which I remember being slower than Python at times.
Then came Burst/ECS, like you mentioned, the former of which is working pretty well, but requires you to rewrite your C# code, with Unity-licenced dependencies, so even if you wrote a kickass dynamic tessellation library, it could be only used in Unity, because of said deps.
The latter is still in forever Unity innovation limbo.
Meanwhile in Unreal-land, they used pretty much standard C++, for a decade, no arcane space-magic ECS found here - and the code has been pretty much stable for that time.
Now I'm curious what a typical Unity C# codebase looks like versus your typical .NET enterprise application. Plus I'm sure a typical Unity game dev shop is culturally extremely different from a typical .NET enterprise dev shop.
Curious - other than Stack Overflow and obviously Microsoft, what other well known tech companies use .NET as their primary stack?
In any case, before I removed mention of C#/.NET on my profile and resume, I would be bombarded with recruiter e-mails and phone calls advertising jobs at old school cost center companies, most of them paying very poorly too.
After removing C#/.NET, these have gradually declined, and nowadays any recruiter that contacts me is for a job/company that I would generally be more interested in.
Exactly - but they are not the primary stack by far. To be fair, you can certainly get into a FAANG as a .NET developer (I've seen ex-coworkers do this) so long as you can pass the leetcode gauntlet like anyone else.
As I said above, my decision is more about filtering out many of those companies that use .NET as their primary stack because I've found far more often than not, they aren't the best companies to work for as a SWE.
I don't think any company (above certain size) would stick to just one stack. Technologies change considerably from one team to another. I agree Google and Amazon are exceptions.
Technology is still central to "tech-as-a-cost-center" enterprises. I'm absolutely a cost center and contribute to the firm's market differentiation by using technology effectively.
I've worked at cost center companies for my entire career but recently jumped to a profit center company. The difference in how tech and tech employees are treated is night and day.
Pretty much every big company these days is driven by technology and would collapse without technology. But cost center companies tend to treat tech and tech employees as a necessary evil instead of a respected peer.
I feel seen with this comment and I'm glad I'm not the only one that has been feeling this way.
I'm about to start a new position that uses C#/.NET and seems like a technically mature/sophisticated organization. Finding this position was hard though.
If that fell through, I was thinking of ways I could try to switch tech stacks. As you stated, the types of companies that gravitate towards .NET are not the types of companies I want to work for anymore.
Not to mention, after talking to several recruiters, it seems like salary for .NET devs are much lower than counterparts in other languages. I'm probably at the top of what I can expect to make as a senior engineer in .NET. I spoke to a few recruiters who recruit for other stacks and my salary is what senior devs typically start at for those organizations.
Regarding compensation - I think that is more of a function of the orgs that tend to use .NET and not .NET itself.
Most senior+ SWEs at cost center non-tech companies (frankly, the overwhelming majority of SWEs) would probably be lucky to retire as a sixtysomething seventysomething seeing $200-250k total compensation after decades upon decades of work.
Meanwhile that amount is probably around what most run of the mill twenty/thirty/fortysomething senior SWEs at profit center tech companies (not FAANG!). Needless to say even some juniors are making that much at FAANG and other upper tier tech companies.
If you can find some corner of a profit center tech company doing .NET, you'd probably be paid the same as any other engineer at that company. But these types of companies rarely seem to employ .NET.
Oh, I agree with you. It absolutely comes down to the organization.
And like you said the organizations that pay very well...don't tend to use .NET. Which is what I've been seeing "in the wild".
At this point, it's just becoming increasingly hard to justify sticking with it. Especially considering I could make more money and not have to deal with so much legacy or poor development practices all the time.
In defense of those organizations though, in my experience, the interview processes have been very reasonable, i.e. no LeetCode. As long as you haven't been sleep walking through your career, it should be pretty easy to get a new position.
Has anyone seen some numbers on the .net core vs .net full usage? A lot of my projects are stuck on full, either because of incompatible dependencies, CLR APIs not implemented or winform. I can’t be alone. As a result I kind of stopped following what’s new on .net. It feels like a python 2/3 split of the user base, though a lot quieter.
.NET 6 currently supports WinForms/WPF if you target Windows specifically [1]. Most API gaps are filled. And .NET Framework compatibility mode [2] might Just Work (tm) for your dependencies.
Sigh (fond memories) - I had just signed a deal to make my 1-person consulting company a Sun Certified Partner, as Java was clearly the future. VB6/COM was an obvious dead-end, and my other preferred alternative - Borland Delphi - was just not being considered by my enterprise clients.
A friend who had recently been hired into Microsoft got me into the alpha pre-release program for .NET. And boom - I never touched Java again, except to port code to C# (or tell IBM sub-contractors how to integerate with .NET/Windows authentication ecosystems).
Weirdly enough - as a programmer who got my start with VB1, I ended-up immediately preferring C# over VB.NET - mostly because my first paying .NET client was facing a complete dead-end with FoxPro - so, as we were performing architectural and technical evaluations of .NET, it was exciting to see that C# was submitted very early-on for ECMA (and eventually ISO) certification.
Myself - I see the release of .NET as the point where Microsoft started to become more open, more platform-agnostic and more developer-friendly than it had ever been before.
> Myself - I see the release of .NET as the point where Microsoft started to become more open, more platform-agnostic and more developer-friendly than it had ever been before.
.NET certainly was more developer friendly, and I guess more open in a way by engaging with standardizing bodies. But more platform-agnostic? The original .NET (anything before dotnet) was very windows-centric. You couldn't take your .NET code and run it anywhere else. The C# language was ISO-certified, sure, but not the APIs. And C# without the APIs is quite uninteresting.
MS only started being interested in platform agnosticism again in the last 3-4 years, because they aren't the dominant platform anymore in a few important verticals (servers and mobile). But for most of the previous decade, they have not cared at all about it.
Agree - the platform agnostic thing is only a recent reality - but, the "possibility" was there at the begining, and at the time the future seemed very bright. (The fact that they did not sue Mono into oblivion immediately was a good sign - of course, but then their historical trend of influental buy-outs continued with the eventual aquisition of Xamarin...)
1. use .Net that work with open standard like ASP.net (html/css/javascript) never buy into Microsoft's own technology like Silverlight. Blazor look promising since its based on webassembly
2. Microsoft fat client is a mess. winform? wpf? uwp? which one to use? don't forget winRT
Mess is subjective. I've been using the same stable UI framework for 20 years. Today's junior frontend devs were in diapers when I started using Windows Forms and it hasn't ever been broken or required rewrites. I don't think web developers even realize this is possible.
The biggest choice is deciding how much you like technologies from the Windows team. Personally, I stay away from them. With the exception of the very oldest technologies (Win32 and COM), tech from the Windows team has less longevity than technologies from DevDiv. That means yes to Blazor, WinForms, and WPF, and no to UWP and WinRT.
Note that Blazor has a server-side edition. Most production Blazor usage is not WebAssembly-based at this point in time.
That's interesting because the 3 blazor projects that I have done client work for are all WASM not server. Do you have a source for the stats on server vs wasm deployments or just what you've experienced so far?
It's just personal experience and what I've heard from other enterprises. Inside corporate networks the latency from Blazor Server isn't a showstopper, and Blazor Server has been production-ready for much longer than Blazor/WASM.
And sadly Blazor WASM even in .NET 6 has runtime performance slower than React, with 5 Mb hello world download.
The other big advantage of Blazor server is you can remove the separate service layer project and deployment target entirely, reducing total code and total infrastructure significantly.
In my opinion, almost every complaint I could possibly have about .NET would not exist if it weren't for windows. From the weird idiosyncrasies that make cross platform GUI development hard, to the dumb enterprisey software patterns, to the weird build systems and packaging...all of them can be traced back to windows somehow.
Currently working in the world of TypeScript/Node/JavaScript there's so much stuff I miss from .NET.
* Awesome standard library - very little need to install packages from randos on the internet
* LINQ makes performing complicated work with collections simple and readable
* Great async model for work that needs to be done in parallel or scheduled
Was also impressed at how much stuff they managed to add to it over the years:
* Generics
* Now runs just about anywhere: Windows/Linux/macOS/mobile
* Null reference types largely gets rid of the endless 'Object not set to instance of ...' errors
* Now supports some form of immutable data types (records)
Frankly most of the complaints I'm reading about here come from the companies that choose to use the technology rather than the tech itself.
212 comments
[ 5.2 ms ] story [ 258 ms ] threadI must say props for the insane compatibility that was kept over the years/decades!
Even migrating some apps from vb6 was relatively easy, that effort shouldn't be underestimated.
A minor nit would be with Silverlight, but I wasn't affected by it. I didn't use much of wpf because of that though. Since around that time, everything migrated to the web.
A well deserved thanks!
But for the people that migrated around that time to it, I suspect a deprecated framework ( although functional), probably wasn't what was anticipated.
https://docs.microsoft.com/en-US/troubleshoot/developer/visu...
They still have a updated faq for it.
https://opensilver.net/
Some things do change
Although being open source and free doesn't necessarily make it open and accessible. The core CLR team do not listen to customers, particularly ones who complain about not wanting telemetry by default in there, ones who open bugs in the HTTP stack which spam logs for months and months and months and complete deadlocks and crashes.
Open Source has only completely absolved Microsoft of any responsibility to support their products to actual paying customers, who are told to open github issues now which are auto-closed after being ignored. I'd rather invest my time in any other platform without the other issues that it brings at this point.
> Cross-Platform... as long as you don't use the GUI libs.
I have literally used it along side several other ecosystems for the full lifespan of it from beta, and it has in large been a very very expensive mistake in the long run compared to the other platforms.
But getting sucked into silverlight would likely have soured me on it.
That started in 2002 and ended in about 2010.
I built some stuff in C# on Windows CE as well which was interesting too.
Back when I switched to .NET the future looked like web apps. Can't say I am particularly prescient but of all the tech in .NET, the web stuff thankfully had the longest legs so I'm kinda glad I avoided the slow death spiral of MS's ever changing desktop moods.
We did unholy things on CE which were quite impressive.
If you've really used .NET "from beta", you'll know that the platform became a snoozefest around 4.5, only to be revived around Core 3.0. "Insanely rapid platform churn" it is not.
And abandonware? Silverlight, sure, not much future in that (although it still runs fine on its own) but how is Adobe Flash doing these days, talking about "other platforms".
Or Java Servlets? In-browser applets?
I've had to migrate my server-side Java code at least twice in the last decade. But possibly I'm just not understanding the needful?
In fact there was a hell of a lot of churn while Microsoft pissed around with the MVC middleware stack implementation and throwing async in which has been buggy as hell on classic. And of course there was the entire “we decided to gut WCF and WWF and AppFabric” thing.
I lost count of the hours I spent digging through deadlocks and spinwaits.
On .net core there have been many many breaking API changes over just the last three years which have broken everything from libraries to the stack. There has also been absolutely zero to no guidance on what best practices are in the current hour. All the documentation and articles out there are obsolete within a gnat’s fart of time after they are written.
There was a lot of change and not a lot of thinking that went into the platform over the years. This costs big money for clients.
Your complaints about the "MVC middleware stack implementation" only underscore the fact that you're making unsourced allegations here. DotNET middleware has been remarkably stable, only requiring some minor adjustments to source code.
So, really, can you give me one, just one concrete example of how .NET has "costs big money for clients"?
Software maintenance costs money, yeah. In Java, in Golang, in (dare I say it?) Rust, in C#. But is the latter platform really that much worse than any of the former?
That is hard to quantify, besides the raw package count, but is a general (subjective) observation I have. There are some replacements for Celery for example, but rather recent and not as capable.
Django REST Framework beats the .NET equivalents hands down. The Django ORM is better than EF, IMHO. Django comes with a command line framework (which can somehow be integrated into .NET projects probably). Reloading times are faster. IMHO the template engine is better.
I like F#, which is more pleasant to work with than C#. But it's hard to get a team going with F#, because it is also harder to learn.
The opposite side to that it I think every commercial .Net system I've ever worked with / on has been an absolute mess. Not sure if it's .Net or the companies but something there seems to attract devs to make ill performing, over abstracted, confusing, massive architecture systems that in reality could be simplified down to a bunch of data forms.
As I say I shouldn't complain keeping these things running pays my bills.
I got paid. That's all the good stuff I can say about it.
Additionally: https://docs.microsoft.com/en-us/dotnet/architecture/porting...
Also the assistant doesn’t help with the numerous third party components which were never ported to core, the entire MVC stack internal changes or the changes that took place in NHibernate. So even if it did work it’d break everything in the process.
But I should mention that nhibernate is not even in the dotnet foundation and not supported for .net core ( I visited their site and it mentions dotnet framework).
I see this though: https://enterprisecraftsmanship.com/posts/nhibernate-now-sup...
So the issue is mostly nhibernate?
I wouldn't necessarily blame it on a lack of seniority or inexperience, it's a matter of not knowing the initial style, decisions, and limitations, as well as the vagaries of time. I find myself creating duplicate functions not because I wouldn't reuse the ones that exist, but because the original one was hidden away in a different place than I'd ever think to look for them. My approach is different and drifts even further over the years, I can't help it, so that the project starts to look stranger and stranger comparing the old code to the new. The original designers would find their style drifting too if they had to take care of a system for that long. They are just lucky enough that their style drift has project cut-offs, so each slice seems more cohesive.
I also don't know if this is a current maxim or not, but there should be a software principle that matches Peter's - every successful system will grow until it reaches a point where it's no longer successful. More and more requirements get added on, and unlike initial requirements where you could justify keeping scope tight due to staying lean, a system needs to grow beyond it's current limitations or it dies.
An additional side effect is that management fails to understand what/why is going on and overvalues the skills of the "experienced devs" and undervalues the skills of the maintenance devs because they don't understand the order-of-magnitude speed advantage enjoyed by devs when writing greenfield code.
"Experienced Developer A wrote the whole damn system in three months! Now Maintenance Developer B wants three months just to add a few buttons?!?"
I've been both the experienced person and the junior maintenance person.
The root issue is that management never seems to be able to grasp things on a technical level. I've tried to communicate this over the years, and have been praised for my communication skills in general, but I've never managed to bridge this particular gap.
One dark place some .NET devs got caught in the early days was some of the 3rd party ORMs. Nightmare of weird code, proprietary mapping tools and headaches.
I am still not sold on linq2sql either. Debugging that is never fun.
When I thought I needed better control and performance I wrote my first ORM. Which wasn't really all that ORM-y. It would use reflection to map to an object, but queries definitely weren't linq-able or using IQueryable and walking the predicates to dynamically generate queries. It was more like dataBase.TableName.First("id=@id", new {id = 1}); Which would generate "select * from TableName where id=@id" nothing earth shattering. Joins were done through dataBase.Join(new [] {"table1", "table2" }, new [] {"on table1.id=table2.table1_id"}, "table1.id=@id", new {id=1});
It was ugly and I eventually just replaced it with straight ADO.net.
I tried various other ORMs over the years, I eventually just settled on EF since it was not bad, and generates almost sane SQL most of the time.
It always made more sense to me to have a sanely-designed database first and then generate the mapping code from it, rather than the code-first style that seems to be popular with EF. You can do the database-first mode with entity framework, but it is less the happy path that the tooling and documentation tries to nudge you into.
I don't deny the value of the active record pattern where it works, but in almost every case I've used SQL over the past 5 years, I don't want a complex abstraction layer. I just want something to make it easy and safe to talk to the database for the 90% of straight forward queries we write.
With something like that, I feel as though I'd rather write my own active record system than use the configuration based systems we see with EF
ORM-lites, such as Dapper, which only bind query results to objects, are an obvious exception thoug.
Every time I’ve seen a project use an ORM past the proof of concept phase, it ends up with some garbage layer to bypass or “trick” the ORM into doing something acceptable. (e.g. Complex materialized views presented as tables to the ORM so the ORM can just do straight selects without joins).
I'm looking at you LLBLGen
"c#" <--- this is not
Imagine what a 15 year old C++, Java, Javascript or Python project would look like. Not much different, I'm thinking...
I agree that pretty much any 15 year old code base is going to get rough, but I think these languages have some clear footguns that aren't doing them favors either. I work on a codebase that isn't more than a few years old, and there's complexity issues from simple things like the language lacking good semantics for transforming data immutably, and that complexity spirals
I can attest that writing messy processes in languages that do address these concerns is absolutely possible, I've done so myself, but the mess is contained to a particular area and it's not as hard to follow which pieces of a system feed into another. Things as simple as making immutability the default and mutation explicit like Rust, and requiring modules be organized into a hierarchy like F# are huge wins. As much as I've gotten annoyed with F#'s project files hierarchy requirement because it requires some extra work/considerations for codependent types and codegen, it's amazing how much easier it is to jump into a new codebase where you can clearly see to understand behavior you start with the bottom of the file list, and to understand core logic/patterns you go to the top of the file list
You can possibly work with and update a C# program because of the incredible longevity/backward compatibility of the core libraries, and reasonable commitment to this in the culture of the ecosystem.
But in Javascript land this can easily or even typically hit a point where the errors from package churn are so much that economically the juice is not worth the squeeze, in a literal order of magnitude less than the typical C# system.
I liked seeing the expressions of frustration when developers that were sloppy with their coding style were no longer able to get away with code that didn't meet the coding standards.
When it was adopted it literally made some people scream in frustration, and I loved it for that.
The default ruleset of StyleCop is absolutely brutal and unforgiving with messy code.
For example:
- StyleCop validated variable names beyond just casing, and forced you to decide how to comply.
- StyleCop validated the number of arguments in methods, the length of a method and the length of statements.
- StyleCop would identify situations when a variable should be created for a expression.
Every large mess starts as a smaller mess, and that smaller mess is usually low quality code.
I don't think ES is as common as you think though. CQRS is.
Though yes there were definitely some influenced by Udi Dahan that use or aspired to use those.
The others go bankrupt before it happens.
What I’m trying to say is that we lack abstractions to model our intent on a higher level.
I think that is why we invent things like micro services because we can’t express modularity on higher level good enough , when that type of abstraction should be built into the language itself (and irrelevant if it is on a separate network node or not).
I guess Java modules is a go at this, don’t know if successful or not.
That is how I at least feel when I’m maneuvering huge projects, a building block is missing.
Imo it has a way higher skill ceiling, than something like, say NodeJS, which is supposedly part of the cool kids club.
I have literally had conversations with hardcore devs that had the 'enterprise offshore-bait' perception of the language and were surprised when I showed them all the awesome stuff you can do with it.
Someone mentioned Unity. I'm really curious as to what typical C# Unity codebase looks like since I imagine a Unity game dev shop would culturally be very, very, different from a big enterprise .NET shop.
Not sure about how representative is this of the typical professional Unity dev.
Something about .net made Microsoft lose their minds
Microsoft tried to jump on every fad that came along and proceeded to burn all the old ones yet still keep the customers limping on them.
Lets not forget stuff like Velocity, DNA, AppFabric, Workflow Foundation etc all of which we had to spend millions rewriting out of products. Before that it was the C++ frameworks: MFC, ATL etc etc etc.
If I pick now it'd be a composite application based on microservices built in pretty much out of the box Go. I have a proven 8 year low maintenance cycle project on that already because Pike Et al actually think about the past and future before they release stuff.
One thing I've been enjoying recently is slack / zoom bots. It's basically a CLI that is accessible to an entire team. I've found the efficiency fantastic. So for simple line of business needs where a quick winforms app might have worked, something to consider.
I started with some very simple items, and then just kept building. It's immediately usable by staff from an office manager to someone very technical. The deployment story is fantastic -> no one has to do anything. Matches web apps that way. This beats winform apps for me.
You get a front-end without much hassle. If someone doesn't give a command in expected format I do exactly what I'd do with a CLI, give them a help response. It's the command line for non-command line people, and the efficiency is great.
Deployment side moved to AWS RDS (postgresql) for the data store. AWS ECS for the containers. ECS Anywhere for stuff that is heavy compute where AWS can get expensive. Scheduled jobs (ECS again) for data load work, added a freshness indicator to responses to users as additional monitoring. Went from self hosting assets to signed s3 links that expire following asset generation. This is a bit slower then doing a straight http server but again, the maintenance reduction is great.
This is for small in size databases with a perhaps 100M records x 4 tables maybe. Also doing some live lookups / crawl type work based on commands to supplement database, again ECS.
I ended up moving off SimpleDB (old AWS product not offered but they kept it running) to dynamoDB and then to just postgresql for everything. For large data loads despite the flexibility/scalability of dynamo, I just couldn't get it to really deliver and the performance / feature set on postgresql for the price and just being on one datastore worked out far better for me. I don't pretend to be a dynamoDB expert so the big loads are probably something I wasn't doing right
RDS is fantastic in my book, upgrades / backups etc in particular -> I'm a huge fan. I wish AWS would break out revenue by product, that has to be raking in the money along with EC2 / S3 and data transfer.
If you have compute needs, ECS anywhere feels like cheating. Basically, you can take a almost home level AMD Ryzen box with a bunch of ram, get the disto/agent on it, and try your jobs there first. Makes you realize how much we give up in the cloud in terms of cost/unit compute. If box is offline, you can fall back to ECS. Not sure exactly why they offered this product -> it saves a ton.
Anyways, that one solution that has been rock solid stable, easy to deploy, and covers a surprising amount of ground and user picked it up quickly. You also get authentication pretty much built in as well.
The hackers here obviously call this "laughable", but I'd encourage folks tired of all the layers of crap to give it a try, just start scratching small user itches - the usage I've seen has been fantastic with no push.
BTW, the interface feels fast to users because they are just typing, don't have to login or go anywhere etc.
Granted, I feel like MS dropped the ball in failing to have an overarching vision of how their .NET technologies would work together and evolve for the future.
Technically a big pity that the market wouldn't accept a Microsoft platform for competitive reasons, but I can also well understand that. Just a shame the wonderful technical platform was lost and we ended up with the lost decade of Javascript front ends.
Most everything else is awesome. .NET core or .NET 6 is what you want.
https://www.devexpress.com/products/net/controls/winforms/
https://www.syncfusion.com/winforms-ui-controls
https://www.nevron.com/products-open-vision-winforms-ui-cont...
https://www.infragistics.com/products/windows-forms
https://www.grapecity.com/componentone/winforms-ui-controls
Also, expect to write 5-10 times more code than with other popular languages. You may not notice this when you come from Java or C++ because then it is an improvement.
As for the misinformation about writing 5-10 times more code than other popular languages, which languages would that be?
Switching between files when every class is in its own file and you need to touch half a dozen classes for each API endpoint, is more of a factor...
Pardon my formatting I'm on a phone
Namespace foo{ Class class1{} Class class2{} }
And
Partial class foo{ }
You don't need to preface a method with `private` to be so but people still do it, why? My theory is the influx of Java dev influences, same with the "One class per file nonsense".
When working in teams, you really shouldn't put more than one class in one file, except for rare exceptions of very small and inconsequential classes. Otherwise the files get pretty big and the chance of merge conflicts get bigger.
The underlying problem - in my opinion - is that C# encourages you to overcomplicate things and that it is relatively verbose. Of course you can put a class with multiple members and methods in one line. But then it's also unreadable. Readability matters.
All languages with a syntax derived from C have a fundamental readability/verbosity problem, C# is no exception. F# for example doesn't have that baggage and is a lot more concise.
You still need a metric shit ton of classes, so finding any one class gets harder. The chance of merge conflicts increases because of more lines per file.
.NET is open source. You're not dependent on Microsoft at all if you don't want to be. If Microsoft closes shop tomorrow, .NET will live on.
You've got a minimal amount of .NET experience (based on your own assertion 3 months ago) and you're spouting incorrect/false information. You were forced to use .NET, maybe that's why you're so unhappy with it. I've used C#/Java/Go/Python/Typescript/JS in my professional life and I've never felt more productive than when I'm building software with C#/.NET. Is it perfect? Not by a longshot. If I had my way I'd be using F#, but alas it's not popular/well-promoted (that I blame squarely on MS.)
https://news.ycombinator.com/threads?next=29303588&id=bayesi...
You are also beholden to the direction Microsoft wants to take the project/platform. There is nothing the other open source contributors, such as there are, can do about it. Fork? Maybe, but there's not THAT much activity around it anyway.
Again, all of this is a risk or "situation" one may be happy to take. Just be aware of it. At the end, .NET is more code, harder to learn, harder to recruit for, easier to over-complicate, and the ecosystem of libraries is thinner than with Django, Python and Javascript.
.NET is sometimes/often chosen for "performance reasons". In my opinion, for websites or web applications this is completely bogus. ASP.NET will slow your development down so much (compared to Django/Node/PhP/RoR) that you won't see any of those benefits any time soon.
Also, keep stuff up-to-date, MS will at the same time maintain things forever and drop them mercilessly (look at .NET framework itself; it still runs - so counts as "maintained"; but if you didn't migrate to .NET core/ .NET5 / .NET6, you're in a very bad position for the future. With the announcement of .NET core they made a lot of code obsolete).
The previous two things combined create a somewhat bizarre situation: you want to keep up to date with the latest things MS is up to.... but not TOO up-to-date, because you can get into the "hype that will be killed" train. E.g. .NET core 1 was too early to jump onboard - wasn't clear that it's not going to be an UWP. But by .NET core 3, you'd better pay close attention and be ready to invest whatever it takes to move on to the new tech. Probably around .NET core 2.1 was the moment when one should've confidently said that "MS is serious about this .NET core stuff"? (though the exact timing is of course debateable)
And all the things Microsoft "hypes up them drops after a few years" have low adoption compared to their main offerings anyways. It would be silly of them to continue actively developing things like Silverlight when everyone saw that better options were available.
That said, people don't always realize how many things Microsoft tries (and subsequently abandons, because of course not all of them are going to be a success). That .net core was a success is clear now; but you could've easily believed that UWP will be a success and invested in it (in fact, I know teams who did, with really bad consequences for them). What I say is... just wait a bit. In the early days, not even Microsoft knows what will succeed, and they will "sell" their new initiatives very hard (of course!).
Same as Google. Same as YC :)
Core is cross-platform, whereas Framework is Windows-only.
Also, some APIs were put in before generics were introduced and thus don't have type safety. The main ramification of this is to basically always use things in the System.Collections.Generic namespace over other collections.
If you are lucky and you are making not-very-complex UIs, you can make a thin wrapper using some of the "newer" frameworks. If you make heavy/classic UI's you will probably have to go for WPF or a Third party framework instead.
On one hand, I love that they’re trying to reduce boilerplate and align closer to something like Node with Minimal APIs. On the other hand, nearly every reference guide or tutorial I look up is outdated and I’m left trying to figure out what changed between .NET 5 (or earlier) and .NET 6. I was following the Little ASP.NET Core book one day and things like there being no Startup.cs anymore (being merged into Program.cs) took me a minute to figure out, as there’s also no definitive resource for a newcomer on what has changed that would make older documentation inaccurate.
The two pages you want are: https://docs.microsoft.com/en-us/aspnet/core/migration/50-to... and https://docs.microsoft.com/en-us/aspnet/core/migration/50-to...
Both should cover the majority of scenarios. The main takeaway is that everything you usually configure in `ConfigureServices` now hangs off `builder.Services`, and everything you'd configure in the middleware pipeline `Configure(IApplicationBuilder app)` is available after you call `var app = builder.Build();`.
I'll note that the change to the Minimal API was only in the project templates, so the old model does continue to work without any breaking changes.
If we look at WCF to REST (or gRPC) it is also mainly easy since it is some general configurations and infrastructure things that have changed but most of the business logic will work. So you have to rewrite but it might be quite easy. And doing this once every decade is not that strange. Also remember that most of the old things still work. You can stay on those tech stacks for another couple of years if you feel that is better for your organization.
https://docs.microsoft.com/en-us/dotnet/core/porting/net-fra...
> .NET Framework 4.8 is the latest version of .NET Framework and will continue to be distributed with future releases of Windows. As long as it is installed on a supported version of Windows, .NET Framework 4.8 will continue to also be supported. https://dotnet.microsoft.com/en-us/platform/support/policy/d...
I think for new apps, you should choose .NET Core. But for legacy apps, I suppose you can take your time. .NET Core actually has much shorter LTS lifecycle. Only 3 years: https://dotnet.microsoft.com/en-us/platform/support/policy/d...
In our case, a fairly big monolith .NET 4.8 web app is being migrated to .NET Core by splitting that monolith into microservices that run on .NET Core. Can't say if it is for better or worse, more moving parts in infrastructure for sure.
( Doing something similar, but I'm not going to go with Microservices)
I've migrated a couple decade plus old web form projects. A lot of the business logic can be moved to .NET Core 6 verbatim. I'll often set up a new version & slowly proxy web requests from the old site to a new version of the site as we update it.
Having done this it does work, but it's fairly time consuming and for larger apps virtually impossible without massive buy-in from the business.
I guess the one downside of having lots of documentation (and third party guides/tutorials) is that it may take some time to update when there are significant changes
The problem is that Microsoft can never avoid the temptation to fix things that weren't that broken and leave it up to you to find the bugs later. Even a theoretical "non-breaking" change like adding some more constructors broke some of our code, previously, you could add ILoggerFactory really easily and it found a single default constructor in LoggerFactory and just worked. The new overloads cause most DI systems to look for the constructor with the most parameters, some of which are not available, and then fall over.
MS need a better system for updates, every version has brought us a lot of headache although I can't really see us using anything else, which would be an enormous amount of work.
Just wondering as someone who doesn't have a clue about anything .Net.
https://insights.stackoverflow.com/survey/2021#most-popular-...
That doesn't factor in other JVM and .NET languages like Scala and F#, but it does give you some idea.
However I am no longer interested in any job that uses .NET and have removed all mention of C# and .NET on my LinkedIn and resume. This is because even despite great recent advances, .NET still seems to be almost exclusively used by tech-as-a-cost-center enterprise companies that I have no interest in working for anymore.
I'm sure there are some great companies in some corners of the world working with C# and .NET, but as far as I can tell, they are still by far, the exception, not the rule.
It's not so much about the technical merits of the stack itself as about what kinds of companies and projects use that stack, and sometimes it might be worth learning some technologies you might not be particularly invested in if you want to work at those companies.
It's not easy to switch stacks either - yes you can learn a new stack but you need those golden "years of experience" in your resume, making a switch an expensive and risky proposition, so you need to choose wisely.
https://en.wikipedia.org/wiki/List_of_Unity_games#2021
Unity has it's own dependency management, project system, runtime, idea of threading/parallelism, concurrency, networking etc.
Usually when one gets involved in some language ecosystem, the language is the small part, getting to know the libraries, and the idiomatic way of getting things done tends to be the emphasis. Here the ecosystems (Unity's and .NET's ) tend to be quite different.
Also the serialization system in Unity tends to interact weirdly with more complex .NET object hierarchies, so expect strange things to happen.
https://docs.unity3d.com/Packages/com.unity.burst@0.2/manual...
Their first idea was, instead of updating Mono, what if they compiled .NET IL to C++, resulting in the monstrosity that was IL2CPP. If you are interested in what sort of C++ code it generated, here's a link:
https://www.jacksondunstan.com/articles/4654
It's full of goto-s, helper method calls, and passing around these weird helper objects to every method.
They triumphantly announced their perf gains - compared to their own old impl, which I remember being slower than Python at times.
Then came Burst/ECS, like you mentioned, the former of which is working pretty well, but requires you to rewrite your C# code, with Unity-licenced dependencies, so even if you wrote a kickass dynamic tessellation library, it could be only used in Unity, because of said deps. The latter is still in forever Unity innovation limbo.
Meanwhile in Unreal-land, they used pretty much standard C++, for a decade, no arcane space-magic ECS found here - and the code has been pretty much stable for that time.
Heh.
None of those of those decisions seem strange once you view them through the lens of some game devs full of hubris :-)
In any case, before I removed mention of C#/.NET on my profile and resume, I would be bombarded with recruiter e-mails and phone calls advertising jobs at old school cost center companies, most of them paying very poorly too.
After removing C#/.NET, these have gradually declined, and nowadays any recruiter that contacts me is for a job/company that I would generally be more interested in.
Pretty sure SpaceX and Tesla would pay competitively to most cost center companies too. Though I hear Elon works his employees hard.
As I said above, my decision is more about filtering out many of those companies that use .NET as their primary stack because I've found far more often than not, they aren't the best companies to work for as a SWE.
Pretty much every big company these days is driven by technology and would collapse without technology. But cost center companies tend to treat tech and tech employees as a necessary evil instead of a respected peer.
I'm about to start a new position that uses C#/.NET and seems like a technically mature/sophisticated organization. Finding this position was hard though.
If that fell through, I was thinking of ways I could try to switch tech stacks. As you stated, the types of companies that gravitate towards .NET are not the types of companies I want to work for anymore.
Not to mention, after talking to several recruiters, it seems like salary for .NET devs are much lower than counterparts in other languages. I'm probably at the top of what I can expect to make as a senior engineer in .NET. I spoke to a few recruiters who recruit for other stacks and my salary is what senior devs typically start at for those organizations.
Most senior+ SWEs at cost center non-tech companies (frankly, the overwhelming majority of SWEs) would probably be lucky to retire as a sixtysomething seventysomething seeing $200-250k total compensation after decades upon decades of work.
Meanwhile that amount is probably around what most run of the mill twenty/thirty/fortysomething senior SWEs at profit center tech companies (not FAANG!). Needless to say even some juniors are making that much at FAANG and other upper tier tech companies.
If you can find some corner of a profit center tech company doing .NET, you'd probably be paid the same as any other engineer at that company. But these types of companies rarely seem to employ .NET.
And like you said the organizations that pay very well...don't tend to use .NET. Which is what I've been seeing "in the wild".
At this point, it's just becoming increasingly hard to justify sticking with it. Especially considering I could make more money and not have to deal with so much legacy or poor development practices all the time.
In defense of those organizations though, in my experience, the interview processes have been very reasonable, i.e. no LeetCode. As long as you haven't been sleep walking through your career, it should be pretty easy to get a new position.
[1] https://docs.microsoft.com/en-us/dotnet/standard/frameworks#...
[2] https://docs.microsoft.com/en-us/dotnet/core/porting/#net-fr...
A friend who had recently been hired into Microsoft got me into the alpha pre-release program for .NET. And boom - I never touched Java again, except to port code to C# (or tell IBM sub-contractors how to integerate with .NET/Windows authentication ecosystems).
Weirdly enough - as a programmer who got my start with VB1, I ended-up immediately preferring C# over VB.NET - mostly because my first paying .NET client was facing a complete dead-end with FoxPro - so, as we were performing architectural and technical evaluations of .NET, it was exciting to see that C# was submitted very early-on for ECMA (and eventually ISO) certification.
Myself - I see the release of .NET as the point where Microsoft started to become more open, more platform-agnostic and more developer-friendly than it had ever been before.
.NET certainly was more developer friendly, and I guess more open in a way by engaging with standardizing bodies. But more platform-agnostic? The original .NET (anything before dotnet) was very windows-centric. You couldn't take your .NET code and run it anywhere else. The C# language was ISO-certified, sure, but not the APIs. And C# without the APIs is quite uninteresting.
MS only started being interested in platform agnosticism again in the last 3-4 years, because they aren't the dominant platform anymore in a few important verticals (servers and mobile). But for most of the previous decade, they have not cared at all about it.
2. Microsoft fat client is a mess. winform? wpf? uwp? which one to use? don't forget winRT
The biggest choice is deciding how much you like technologies from the Windows team. Personally, I stay away from them. With the exception of the very oldest technologies (Win32 and COM), tech from the Windows team has less longevity than technologies from DevDiv. That means yes to Blazor, WinForms, and WPF, and no to UWP and WinRT.
Note that Blazor has a server-side edition. Most production Blazor usage is not WebAssembly-based at this point in time.
The other big advantage of Blazor server is you can remove the separate service layer project and deployment target entirely, reducing total code and total infrastructure significantly.
Windows ruins everything.
* Awesome standard library - very little need to install packages from randos on the internet * LINQ makes performing complicated work with collections simple and readable * Great async model for work that needs to be done in parallel or scheduled
Was also impressed at how much stuff they managed to add to it over the years:
* Generics * Now runs just about anywhere: Windows/Linux/macOS/mobile * Null reference types largely gets rid of the endless 'Object not set to instance of ...' errors * Now supports some form of immutable data types (records)
Frankly most of the complaints I'm reading about here come from the companies that choose to use the technology rather than the tech itself.