The Power of Convention
Tony Hicks
Posted on September 16, 2023
While doing some investigation into AvaloniaUI, I came across some great open-source projects that use it and was delighted to find that they follow the more conventional, modern ways of setting up a C# project. I just want to specifically talk about my experience when looking at the startup code.
Keeping all the config and bootstrapping code in one, easy to find and read place makes it a pleasure to see what's going on in the project at a moment's glance.
I see environment variables being set, the projects dependencies - what needs to be registered (and some idea why), command line arguments that it accepts, background jobs being hosted and all the other things that you'd expect from a non-trivial application written in modern day C#.
This tells me many things about the code.
Whoever wrote this cared enough to make this maintainable for themselves and everyone else - they took the time to follow industry standard conventions.
I can expect a certain standard of code quality from this project - It is probably written using decent SOLID principles and hopefully a sane amount of Object Oriented design. Why do I think this? Because looking at the way the dependencies are loaded, and just browsing to look at the code inside a few, it's clear what each portion of the code is responsible for, and what other parts of the system it interacts with. One could easily trace the pieces together with a diagram, and you'd probably be able to follow it without it looking like a bird's nest of dependency overlap.
The code is easy to isolate and therefore test if need be - seeing this approach gives me a level of confidence that the code is written in a way that the dependencies are clear and any static classes used do not hold any state. This may be false, by the way. The subsystems may be a total mess! But seeing the almost unspoken conventions that they've adhered to, gives me a good feeling in the design of their software. I have a high degree of confidence that they have adhered to other, familiar ways of structuring an application.
I already know how to configure this because I'm familiar with the dependencies used.
i.e)
- ServiceCollection for the DI container
- Extension methods on ServiceCollection used to register subsystems
- Option objects for setting on the services
- Serilog for logging
It makes me realize how far we've come in the .NET world from the days of opening a new project and seeing a completely different DI container being used, each having different ways of doing the same thing, or even worse - performing all sorts of highly customized, black magic that is tough to understand and also to debug (looking at you Castle.Windsor).
It's amazing how much convention plays a role in our daily lives and how useful it is. I don't just mean inside of .NET projects. All of software benefits from conventions and the more widespread, the more transferable and useful they are.
Just think of the rules of the road while driving. It's great to go to most places in the world and still be able to drive there. This convention is not always enforced but even when it isn't, people still follow it to some degree because it minimizes the chance of something bad happening.
It's why opinionated frameworks like Angular have always drawn me more then React - Angular projects generally have pre-defined conventions, whereas the less opinionated ones tend to have a bespoke, naturally-evolved one or, worse, something that has been fitted retro-actively which always leads to inconsistencies in the codebase (rewriting is a lie).
You always end up with a convention - a "right" or a "wrong" way to do things in any project. I just prefer to have that as clearly defined as possible and is widely known and understood.
Backend code in general has also benefited by convention in the now, pretty much universal, Web API. All the conventional business 3rd party integrations I've done as well as new backend applications I've written in the past few years have all been Web API's. JSON and Web API's have become the default choice.
No more needing to deal with weird compatibility issues of WCF and Autofac. Trying to debug WCF services with their strange policy of breaking whenever the smallest thing is wrong with the data contract, and then being completely obscure when it comes to telling you exactly what the problem was. Downloading and parsing files over FTP and parsing them with complex XML code, or managing a custom, delimited format. Nope - it's all Rest API's, JSON and OpenAPI (Swagger) documentation.
None of this is new though. Conventions are basically loose versions of protocols. As our software stacks mature, natural ones begin to emerge and I'm excited to see that happen more in the software I deal with. Everything becomes so much simpler and I don't see how that's a bad thing for anyone.
Posted on September 16, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.