Microsoft is making big changes to the way they are building and shipping software.
Personally, I think it’s a huge win for developers. It’s only a matter of time until .Net Core targets ARM processors and all of my homemade applications talk to each other via distributed messaging and scheduling on a Raspberry Pi network.
But the paradigm shift in project structure and style leaves some polarized in their opinion. The developers who understand the power of Open Source are generally immediately on board. The developers who still think the best answer to any problem is a stored procedure simply can’t comprehend why you would do anything in .Net Core when the existing .Net Framework “works”.
“Well, it works!”
Ever heard that?
That statement eventually gives birth to the infamous “Well, it works on MY machine…”
Let me tell you something about my philosophy on development. What really fuels why I do what I do.
The art of software development, in my opinion, is being able to design an evolving solution which adapts to an evolving problem. I might even give that as a definition to “Agile Code”, but I’ll leave that for another discussion. I don’t mean an evolving solution as in having to touch the code every second of every day in order to meet new requirements – I mean touching it a handful of times, and the answer to every new requirement is “sure, no problem” as opposed to “Crap – that code is a nightmare to modify for even the smallest tweaks”.
.Net Core facilitates this in so many ways – between amped up dependency management, DI as a requirement, and a middleware styled approach. Developers have known for decades this is how to build software, and for years have tried to shoehorn this paradigm into the .Net Framework via OWIN and a myriad of IoC containers. Greg Young, an architect whom I have the utmost respect for, has spoken out against DI containers(specifically the proposed benefit of hot swapping implementations at runtime), but after being confronted with some very challenging requirements, I honestly can’t make an app nowadays without it. Even for simple apps I make myself – I decide to switch up implementations and benchmark things against each other, but I don’t want to delete code that I’ve written on my own time for fear of reusing it at a later time (No TFS at home..yet…).
The most important aspect of .Net Core, in my opinion, is it forces you to think in terms of abstractions.
It’s disheartening when I’m working with other developers who:
A) Claim to be C# developers and can’t define “coding against an abstraction”
B) Don’t understand that how to properly separate the concerns of code
C) Believe that offloading business logic to the database is a good decision in the name of performance
I have to catch myself here. It’s easy to slip into a cynical view of others and begin to harshly criticize their talent as I put on my headphones for a three hour refactoring session. That’s not me. I believe anyone can code. I believe anyone can be a good coder. Good developers, and high performing people in general, are good thinkers. They know what they don’t know. They never settle for a single best solution, they pragmatically select the best tool for the job, critically assessing their problem and any potential solutions.
This is how I mentor the younger developers that drop their jaws when they see Startup.cs for the first time:
Ignore this entire file. You need to know two things. You configure services and you use middleware (thanks Daniel Roth!).
What is it that I need this package/code to do?
Pick the best tool for the problem, and drop it specifically where it belongs. Concretely, this means thinking about your problem space. There’s a 99.9% chance you are not the first person to encounter this problem. What is the most elegant and reusable solution?
This gets the developer thinking about scoping and narrowing their development focus. Too often they jump immediately to code that actually takes input A and outputs B – it’s our nature. Usually, as I pester them with questions, they end up verbalizing the abstraction without even realizing it, and half the time the words they use best describe the interface!
Dev: “Well, I’m really only using this code to provide data to my view model.”
Me: “Right – you didn’t even say web service in that sentence.”
Dev: “So it’s a ‘Data Provider’, but it will to go to the web. So it’s a Web Data Provider. ”
Me: “For local debugging though, you need to be able to provide some hardcoded values, and it shouldn’t impact or modify any other code.”
(Blank stare, moderate pause)
Dev: “…Should that be a hard coded data provider?”
Boom. My job here is done.
For anyone used to working with repositories, DI, and OWIN/MVC, this stuff is child’s play. The junior developer (and indeed, the fully mediocre developer) need a hand grasping these concepts. I find that guiding them through a discussion which allows them to discover the solution presents the most benefit. Simply telling them what to do and how to do it trains a monkey, not a problem solver. Anyone can write 500 lines of code in Page_Load. They need to understand the ‘why’. Personally, teaching on the job is one of my favorite things to do – there’s simply no substitute for the happiness that hits a developer when they realize the power that this new technique has awarded them.
More on this at a later point, but for now, understand the danger that you take on by using that new() keyword. You may be stuck with that code block for a long, long time.
On to today’s music. I found some more somber sounding folk-pop stuff. The EP by Lewis Del Mar was a really great find! (Minor language disclaimer).