Codementor Events

Things I Wish I was Taught in School

Published May 20, 2025

In many ways I feel like my formal education was sorely lacking in some of the things that really matter when it comes to development. Sure, I learned how to use a for loop, if statements, try/catch, all the usual suspects. It provided a baseline for writing code. But it didn't prepare me for all the nuances that come from all angles when you actually start coding.

Version Control

I managed to make it out of college without knowing what git was. At best I'd heard about github but I wasn't convinced I should care yet. "Why would I put my code up there, I do all my work down here!" "Change tracking? Why?" Never did it occur to me I might have to work on a project with anyone else. When I finally got into it about 3 years into my career, I started to see the light. There's so much value it can bring to development, even working solo. I don't need to go into details here, this is just a list, but if there's enough interest maybe there's something I can write about in more detail.

Depenency Injection

Basically in .NET, most of the time I use the new keyword is when I'm actually creating a new thing. A new domain entity, for example. Creating a new service is usually the wrong thing to do in production code, simply because you're also taking on the responsibility of providing each of its dependencies, as well as their dependencies, and so on. First off let me just say that I wasn't even properly taught about the idea of "domains" or why there should be services for interacting with them, so I was already off to a rough start handling most logic directly in controller actions. Even if I did have services to use, handling the dependency tree manually would be enough to convince me that something was wrong somewhere. However not even knowing the words would put me at a huge disadvantage. Eventually I came across Ninject in .NET Framework, which sort of introduced me to the idea of dependency injection, but it was strange to me. I didn't understand what it was doing. I didn't know what "registering a service" meant, I didn't know how this magically meant I could add something to my constructors and now it will have a value. It all seemed so disconnected to me and I couldn't figure out what any of it meant.

Domain Driven Design

I hinted at this in the above section, but it gets its own section too. Thinking in these terms really helps to separate the implementation from the semantics. Most of the time it's more valuable to have a dedicated thing-doer than it is to just do the thing yourself. This might seem counter-intuitive to some, but when it saves you the effort of writing the same thing-doing code for the umpteenth time, you might start to see its value. Plus separating it out into isolated code means it can be better unit tested. On that note...

Unit Testing

At best in college I learned that unit testing is a thing, and it's "good". Why? Dunno. It was a few years into my career that I finally did any unit testing, and if I'm being honest, a few years after that when I realized that some tests are more valuable than others, and if all you're doing is setting up a mock and then testing that mock, you're not really testing your logic, and the test is essentially pointless.

Clean Architecture

This was a revelation when I finally got a job that used clean architecture. It gets a mixed reputation from a lot of devs, and I guess the thing is I wouldn't say it's the right structure for every project. But decoupling your business logic from your infrastructure, and your application, is huge. It means you should be able to properly unit test your entire Core while only mocking some interfaces, so you can ensure that your business logic is solid regardless of whatever else is going on. A separate project for infrastructure means that it shouldn't matter how or where anything is stored, as long as it implements the appropriate interfaces, everything else should "just work". And then the front-end can do whatever it needs to in order to tie it all together. Dependency injection is a must here, and that blew my mind first too. "How can the core project use the database if it doesn't actually have a dependency on the infrastructure project?" Inversion of control. The application picks the implementations and then as long as everything is connected properly, it just works. It's incredible.

Honorable mentions

To some lesser degrees I wish I was taught more about things like OpenTelemetry, proper logging, and how to actually configure an application, but some of that gets a little subjective.

I suppose this all has been pretty subjective, but by and large I feel like the things I've mentioned here have done more for my professional development than college did. Even if you disagree with anything here, I feel like it's important to understand these things so you can choose to use them, or not use them, from a place where you know what they provide and what the trade-offs are, because when we get down to it, every design decision we make in an application has trade-offs. It's knowing what they are and whether or not you can afford them that will make you an effective developer.

Discover and read more posts from Alex Froese
get started