We have a pretty great ecosystem for C# and .NET. We have amazing IDEs like Visual Studio, a fast runtime, good troubleshooting tools, etc. But I think we can do much better. I think the .NET ecosystem can be somewhat inspired by the development process in JavaScript and TypeScript projects. I’m talking about Visual Studio, MSBuild, and the .NET SDK being a closed ecosystem, whereas in JavaScript there’s an open ecosystem that enables amazing extensibility by the community.
We do have great libraries in .NET created by the community like Newtonsoft.Json, Automapper, Serilog, etc. But I’m talking specifically about opening up the build pipeline. The process of code development that’s written in an IDE, built by the compiler, and then executed by the runtime. That’s entirely controlled by Microsoft, with the single exception of custom Roslyn Analyzers. If you want to customize something, you’ll have to create proprietary solutions and dig into the complexities of Visual Studio extensibility and MSBuild. As a VSIX developer in the past, I assure you it’s not a piece of cake.
Consider what you have in the world of JavaScript. You can integrate transpilers and write in different languages like TypeScript. Or have your linters automatically fix code style rules. Or write React JSX components. There are a million different use cases that can be achieved with concepts like Bundling, transpiling, and linting.
So my 2023 Christmas wish list is to have the .NET build process open up and allow more extensibility. If Microsoft enabled such capabilities for the community, I’m sure we would see amazing things happen. Here are some of the specific requests that will enable this.
Disclaimer: I’m a Microsoft employee myself, but I have no relation to the .NET development team. All opinions are my own.
My Extensibility Wish List
- I want to be able to have add-ons that change the source code that’s compiled while keeping the original source code and being able to debug it. A simple example would be to automatically inject logs on every method with a
[LogMethod]
attribute. More interesting examples might be to transpile a newer C# version to work with an older runtime. Right now this is impossible because once the source code is changed, debugging against the original source code won’t work. - I want to be able to add changes like the above just by adding a NuGet package. This means NuGet libraries should be able to modify the build process itself, without the developer changing
.csproj
files or handling MSBuild. Such a library might have its ownJSON
config file that you can modify. - I want to be able to add formatting and linting rules via NuGet packages so that my code changes every time I build the document. This is similar to today’s Roslyn Analyzers, except now it shows as a code fix in quick actions, and I want the option to apply code fixes automatically. Even better, I’d like the option for community libraries to do as they choose. They might change the code on a build, add quick actions, add big arrows in Visual Studio UI, or make beeping sounds. Let’s allow everything.
- Following the previous thought, I want NuGet packages to be able to access Visual Studio API and change whatever. In other words, I want NuGet packages to have the abilities of Visual Studio extensions. Those extensions can let you debug in a certain way, change the solution explorer tree, add tool windows, or show UI for your specific source control client.
- I’d like for my projects to be able to automatically install and activate Visual Studio extensions. If I have NUnit tests, I want to have the NUnit extension installed when I’m opening my project. The same goes for an SQL Server extension, NCrunch, or anything else I want my team to work with. These extensions might be available from the Visual Studio marketplace, from a private NuGet server, or be embedded in a referenced NuGet package as suggested before.
- If we’re going to allow NuGet packages to extend Visual Studio, let’s allow them to extend Visual Studio Code as well. They should be able to extend just one or both.
Possible Implementations
As a user of Visual Studio, I probably should stop at requesting features. But as a meddling software developer, I can’t help but suggest how those features would be implemented. So here are a few ideas.
- The problem with NuGet packages changing source code is that debugging won’t work. The symbols (.PDB files) contain a mapping between the compiled IL Code and the source code. If the source code in Visual Studio is different than the one built, debugging stops working. I suggest doing what JavaScript already does: introduce source maps as another layer of mapping. The PDB would still point to the source code that was compiled, but if there was any kind of instrumentation, we will have an additional source map that points to the original source code.
- Since I want NuGet packages to change the build process itself, and not the application, they shouldn’t be included in the build target folder. They should be separate dependencies that execute only during development and build. It’s the same concept as
devDependencies
in npm. - I mentioned that I want dev NuGet packages to be able to access Visual Studio API, change UI, or do whatever. But as you know, Visual Studio is not the only popular IDE for C#. There’s also Visual Studio Code, Rider, and Visual Studio for Mac. Having other IDEs implement the huge Visual Studio extensibility API is practically impossible. This means that either this functionality will be limited to Visual Studio, which makes sense in an Enterprise that can direct employees to use a specific IDE, allow different implementations for different IDEs, or create a protocol that’s shared between IDEs. Such a protocol is not unheard of. In fact, Microsoft already created something similar in VS Code with the Language Server Protocol .
Finishing up
I think .NET has a great deal to gain by opening up its build and runtime for extensibility. Consider that the Visual Studio and .NET teams can work on exposing APIs instead of developing features like Roslyn Analyzers, docker support, Visual Studio built-in style rules, etc. All of those could have been developed by non-Microsoft .NET developers around the world. Once you open the possibility, the community always creates amazing things.
There are downsides I suppose. If such APIs were developed, Microsoft would lose some control over the platform. It could change in ways I can’t even imagine. Maybe those directions would create new languages that will be transpiled to C#. Or add more incentives to use IDEs other than Visual Studio. Or, god forbid, add incentives to use a cloud solution that’s not Azure. I have a hard time imagining how such scenarios can realize, but nobody can predict the future.
Got some thoughts on my wish list or some wishes of your own? Add your comments below. Happy coding.