.NET Developers Begging for Ecosystem Destruction

An ASP.NET GitHub thread entitled “Epic: Eventing Framework in .NET 9” ignited an inferno of criticism for the usual reasons: Microsoft big-footing its own .NET OSS ecosystem, etc, etc…

A few years ago I would have cared about that, but this is simply in Microsoft’s nature - as I’ve written about here before. No amount of public venting of nerd rage or OSS community spirit is going to reach the top of the ivory tower over there. Only changes to Azure spend can make that happen.

If you want to play in the .NET ecosystem as an OSS project, a tool maker, etc - this is the price of admission. If Microsoft entering your space is enough to make you quit or enough to kill your business then you were never creative, determined, or passionate enough to succeed in the first place.

Microsoft claims they’re working on this framework mostly just to improve Azure WebJobs and therefore this isn’t really a threat to MassTransit, Wolverine, MediatR, et al but I don’t believe that. Why make it an epic within ASP.NET, by far the most popular framework in the ecosystem, if you don’t intend to have third parties actually use it?

That aside, it’s not the reaction of the OSS producers or Microsoft on that thread I found interesting - it was the reaction of .NET OSS consumers that caught me by surprise.

Many .NET developers were vocally cheering on the destruction of these popular third party frameworks, as though having multiple, well-maintained tools was an inconvenience that needed solving.

Who are the .NET developers demanding that .NET destroy its own ecosystem and return to .NET to the uncompetitive, intellectual ghetto of yesteryear?

Two Cohorts of .NET Developers

There are two cohorts of .NET developers on that thread:

  1. Supplier diversification is good; having multiple viable options for delivering software lets me choose my trade-offs and keeps the ecosystem healthy + competitive;
  2. Suppler diversification is bad; we should have a single unified standard for how we do things, even complex things like building event-driven architectures. And as long as Microsoft supports that single standard we have nothing to worry about it - it’ll be better documented, maintained, and more approachable than anything else. We should consolidate the rest of the ecosystem around this standard.

Just to be unequivocal - these are not two equally valid, “agree to disagree” points of view. The developers in cohort 2 are buying into a belief system that renders them less capable and skilled than the developers in cohort 1. It’s a self-limiting belief that leads to expert beginner destinations.

Someone who believes that evaluating or even having tooling options is a waste of time isn’t capable of building a high-traffic customer-facing SaaS applications, industrial IOT, automated trading systems, or anything else more complicated than putting forms over data. The entire reason I work in .NET OSS is because I want to increase the population of developers who can build those important systems with .NET.

.NET Developers: what do we want?! Fewer options!

Advocating for the destruction of options isn’t a healthy discourse we should be having in the first place - “let’s make the ecosystem worse and less competitive for my business so I don’t have to think about options” is a short-sighted thought process. Only junior developers who never lived through how utterly terrible the .NET ecosystem was prior to .NET core or “senior” developers working on utterly inconsequential applications through that period could believe this is a good idea.

Cohort 1: The Options-Seeker

Competition is good - having multiple viable options is good. Microsoft getting into the eventing space won’t kill off any of the existing solutions for building message or event-driven architectures; in fact, it will likely increase the number of .NET developers attempting to build them in the first place - a good thing!

Microsoft getting into the eventing space is “bad” only insofar as it’s going to cause a number of developers to not really consider options when it comes time to make a decision on how to build their software. An allegory for this is the increasingly frequent case of newer .NET developers knowing how Entity Framework works, but not how to work directly with SQL - Code First EF “works” so why bother searching any further?

What the options-seekers in Cohort 1 care about is choice and freedom - knowing that there are technical and stylistic trade-offs at work for each possible option and being able to have access to those. Reduction of options necessarily means less creative freedom and possibly not having the tooling you actually need to do the job (which happened quite frequently in the early days of .NET.)

I get asked all the time how I feel about Microsoft Orleans vs. Akka.NET - I usually respond that I’m glad it exists too because neither existed when I needed a viable .NET actor model implementation in 2013-2014. Orleans has a different approach to building software with actors than Akka.NET does and I think it’s healthy to have competition in the space. Orleans existing hasn’t hurt Akka.NET’s adoption rate at all because those differences between Orleans and Akka.NET matter to both technologies’ users.

Options make our experience working in the .NET ecosystem more economically valuable to employers and to ourselves - options are good.

Cohort 2: The Fearful

What surprised me about some of the comments from .NET developers on https://github.com/dotnet/aspnetcore/issues/53219 was how fearful they were of .NET OSS projects and thus, their demands that Microsoft make a first party solution to solve their problems. Some examples:

There’s also the “our lawyers made us choose our technology stack” excuse, the enterprise version of “the dog ate my homework:”

The issue described here is one of the problems that the .NET Foundation is supposed to explicitly solve for third party .NET open source projects: ensuring that all projects allowed into the foundation have both clean (non-infringing) intellectual property AND commercial-friendly permissive open source licenses - the two things non-engineering stakeholders care about. Our project, Akka.NET, is a .NET Foundation project.

Akka.NET’s currently used in production by companies like Bank of America, United Airlines, Siemens, U.S. Office of Personnel Management, Northrop Grumman, Dell, Qualcomm, etc - we’ve had to go through IP and licensing checks at some of those firms but that’s the extent of it. I’ve never seen a legal department mandate which specific library authors you can use, even in sensitive spaces like defense contracting, justice systems, government, and Fortune 100. The entire premise of permissive OSS is that you can see exactly what you’re getting - and if you want to practice hyper-hyper-vigilance on your technology supply chain, you can build artifacts yourself from source you can clone onto your own machines.

The only people who’d impose a strict library-vendor mandate like this are software developers themselves - hence why this is largely BS:

I’ve discussed the .NET OSS ecosystem frequently on my blog. Many of the issues we have, such as OSS sustainability, are common problems shared by all software ecosystems. These comments illustrate a problem that is entirely unique to the .NET ecosystem though: single vendor monoculture, Microsoft in this case.

What these complaints come down to is a high degree of fearfulness from this cohort of .NET users:

These users are substituting their own critical thinking with blind faith in Microsoft - the primary driver for this being the “no one got fired for choosing Microsoft” adage.

This is something that doesn’t really happen in other software ecosystems. If a Java developer begged for Oracle to come along and create a first party replacement for Kafka because they were too scared to use Confluent’s tooling for any of the reasons I listed above they would be laughed out of the room. Here in .NET-land, we entertain this for some reason - we should stop doing that.

This is emotional reasoning leading technology adoption - herding under Microsoft’s umbrella not because their tooling is the best for the job, but because it has the strongest blame-resistant accountability firewall. “No one ever got fired for choosing Microsoft” taken literally.

The best part is: most of these reasons offered for why Microsoft is “safe” aren’t even true.

For users worried about the longevity of OSS tools, ask any Silverlight users how their bosses reacted in 2011 when it was abruptly cancelled. Or ask WPF / UWP / MAUI users how confident they feel about Microsoft’s offerings in the desktop UI space in 2024.

Let’s consider Microsoft’s impressive and expansive boneyard of popular OSS projects they’ve once touted - here’s a portion from a talk I gave in 2020 detailing Microsoft’s rate of abandonment of popular projects:

Since the comment I quoted earlier was concerned about the longevity of MassTransit specifically: MassTransit has been in development since 2007 and Windows Communication Foundation, WCF, since 2006. Which of these two frameworks is still actively maintained today, in 2024?

There’s also this sentiment, which I have to admire for its sheer Kafkatrapping ability:

Microsoft, for all its flaws and its bad decisions, is a net positive for the millions of developers that feel ignored or belittled by the others. The .NET SDK is developed by some of the world’s best engineers. Their documentation is vast and detailed. They are consistent and disciplined in the delivery of new versions. They innovate continuously. And they’re incredibly diplomatic.

While I think Microsoft’s commitment to product quality is undeniable, only a tremendously inexperienced developer in this ecosystem could believe that it’s easier to interface with a $2T market cap company with 100k employees versus a 3-person OSS project. Any project made by Microsoft is 1-2 corporate re-orgs away from no longer existing. Consider the fate of poor AppCenter users this past week:

One particular user in the eventing thread was crowing about how amazing ASP.NET’s Rate Limiting features are as an example of Microsoft’s unparalleled genius and providing accessible offerings that were otherwise impossible for dark matter .NET developers to access.

Consider the following argument made by Options-Seekers: “the existence of a default-by-Microsoft option prematurely terminates most .NET user’s search for the best option.”

The ASP.NET Rate Limiting APIs this user is praising fall far short of “useful” for most real-world applications:

  1. They’re in-process only, so the biggest class of economically useful rate-limiting applications (charging tenants $ on a metered basis) can’t even use them - there are plans to fix this in .NET 9 https://github.com/dotnet/aspnetcore/issues/53426;
  2. The configuration is extremely difficult to reason about - doing some stream-based programming (Rx, TPL Dataflow, Akka.Streams) would actually be easier. Don’t ask me, I just do this all day long for a living;
  3. It’s not backpressure sensitive - arbitrarily rate-limiting a web app is idiotic. It should only be done in response to a business reason (see point 1) or because a shared resource (like a database) is starting to become unavailable and you’re choosing to prioritize some traffic over others (also a business rule.) This would require some backpressure-awareness. The closest the current APIs come to supporting this is the token bucket rate limiting policy.
  4. The API makes it difficult, out of the box, to reason about important side effects and flow control when you actually do need to start invoking rate limits - again, if this were a stream-based programming model and not a configuration-driven one, this would be easier to do. I could simply start buffering / batching / debouncing or whatever was appropriate given my app’s requirements. In this instance, you get to reject a request and maybe do stuff afterwards in an event handler.

This rate limiting feature shipped because ASP.NET “needed” it, or whatever, and its lack of consideration for what real high traffic applications would actually need to productionize it is demonstrated. Developers who’ve been working on third party solutions for managing high throughput traffic in ASP.NET / other .NET systems, such as https://github.com/ThrottlingTroll/ThrottlingTroll - which supports distributed per-tenant rate limiting, builds this stuff properly because their businesses depend on it, not because their Microsoft PM added this to this year’s Objectives and Key Results document. The .NET team does great work, but they have different incentives for why they ship and do things and that’s reflected in their priorities.

When it comes to “alignment” between a library / framework author and your own needs, third party OSS options are often closer to you than Microsoft is - many of these projects were born as a result of a legitimate business need felt by the authors themselves. Akka.NET was certainly born that way.

If Microsoft has to deliver “cloud native” stuff this year and “compete with Python on minimalism” next year, that’s not necessarily because it’s what current users of the framework actually want. Moreover, the .NET team has to ship lowest common denominator experiences due to the volume and variety of users, use cases, versions, and cohorts they support. That’s precisely why abstractions like ASP.NET Rate Limiting and even older ones like IDistributedCache don’t have a tremendous amount of real-world usage - they’re very, very clunky for serious customer-facing production uses.

So here we are, with this user crowing about how great this feature is, simultaneously exposing how little meaningful experience he has with rate limiting and proving the Options-Seeker’s point about developers stopping their search for the best tools whenever Microsoft has slop to serve in the space. This is the entire reason why anyone is raising concerns about Microsoft building an eventing solution at all.

Thinking and Acting Strategically

You are not compelled to care about .NET OSS - and it is totally fine to choose Microsoft’s first party offerings. But there’s a stark difference between choosing Microsoft’s solution because you’ve determined that it meets your needs from choosing it because Microsoft made it. These two decision-making processes arrive at the same conclusion - the former being rational reasoning, the other being specious.

Cheering on the destruction of options is cutting off your nose despite your own face - in the long run, it drives both talented people and talented organizations out of .NET. The next time you want to post a “Why don’t major Internet platforms use .NET?” thread on /r/dotnet - consider that it’s because in .NET’s past the tooling simply wasn’t available for these platforms to be built in the first place.

.NET’s been on a great trajectory since it went cross-platform. If you want that to continue, cheer the expansion of options within the .NET ecosystem - not their destruction.

Discussion, links, and tweets

I'm the CTO and founder of Petabridge, where I'm making distributed programming for .NET developers easy by working on Akka.NET, Phobos, and more..