Skip to content
Karim-w

You should probably stop using .NET

Author: Karim Hassan

Published: 2023-06-06

DotNetMasoctPic

Preface

DotNet Core is a great framework. It’s fast*, it’s cross-platform, and it’s open source. Microsoft is fully simping for it and seems to be pushing it as the future of webdev. That’s probably why you need to stop writing .NET.

The Problem

The problem is that .NET is a framework desgined to make you a dumber developer. Notice that I didn’t say stop using C#. C# is a great language and I love it.

My issue with the Framework is that it desgined to make things easier for you.

need to make a web server? just create a webapi project Need to create a web job? just create a console app Need to create a desktop app? just create a WPF app Need to have a curd app? just use Entity Framework

It’s easy… way too easy. It’s so easy that you don’t need to think about happening under the hood. You don’t need to think about how the web server works, you don’t even need to think about what is a web server. all of the thinking is done for you. You just need to write the code.

Writing Code

I’m gonna assume you use a windows machine. If you plan on writing .NET code you’re gonna need to install Visual Studio. Visual Studio is a great IDE, probably the best one out there. It’s also one of the reasons that makes you dumb.

Let’s say you want to create a web api. You open up Visual Studio, create a new project, select the web api template, and you’re done. You have a web server with an example controller. You can run it and it works. you can open up /swagger in your browser and you can see the swagger page. all of this was done in 5-8 clicks.

now in those 5-8 clicks, you have created:

  • a web server
  • a controller with a get method that returns the weather forecast
  • a swagger page
  • a launch profile
  • a docker file(if you selected docker support)
  • Dependency Injection

assume you’re a new developer, chances are you don’t know what any of those are. the system has done all of the work for you.

A more realistic usecase

Let’s say you want to extend the template you’re provided with. You want to create a new controller with five methods. Create, Read, Update, Delete, and List. You then right click on the controllers folder, select add new item, select controller, select the api controller template, and you’re done. You have a new controller.

disregarding the fact that those three clicks just created a new handler route on your web server without u having to do anything. you now have a new controller. you can now add your methods and you’re done.

there’s one issue though. to create and presist data you need a database. ah Entity Framework to the rescue. you do a quick google search and you find a tutorial on how to use Entity Framework. you follow the tutorial and you learn you probably need to use SqlServer(disgusting) and that you need to create a model, a context then run dotnet ef migrations add and dotnet ef database update and you’re done. you have a database.

Questions:

  1. what did you just do?
  2. what is a SQL Database?
  3. what is a model?
  4. what is a context?
  5. what is a migration?
  6. is the database setup?
  7. did I create the users table?

long story short, you don’t know what you just did. you just followed a tutorial and you got a database. you don’t know what a database is, you don’t know what the table looks like and you don’t know how to query it. you just know that it works. because the applicaiton hasnt forced you to interact with the database directly. you just know that you can call context.Users.Add(user) and it will add a user to the database.

your controller now looks like this:

[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
    private readonly ILogger<UsersController> _logger;
    private readonly UsersContext _context;

    public UsersController(ILogger<UsersController> logger, UsersContext context)
    {
        _logger = logger;
        _context = context;
    }

    [HttpGet]
    public IEnumerable<User> Get()
    {
        return _context.Users.ToList();
    }

    [HttpGet("{id}")]
    public User Get(int id)
    {
        return _context.Users.FirstOrDefault(x => x.Id == id);
    }

    [HttpPost]
    public void Post([FromBody] User user)
    {
        _context.Users.Add(user);
        _context.SaveChanges();
    }

    [HttpPut("{id}")]
    public void Put(int id, [FromBody] User user)
    {
        var userToUpdate = _context.Users.FirstOrDefault(x => x.Id == id);
        userToUpdate.Name = user.Name;
        userToUpdate.Email = user.Email;
        _context.SaveChanges();
    }

    [HttpDelete("{id}")]
    public void Delete(int id)
    {
        var userToDelete = _context.Users.FirstOrDefault(x => x.Id == id);
        _context.Users.Remove(userToDelete);
        _context.SaveChanges();
    }
}

this is garbage code, don’t write code like this

you now have a fully functional crud api. it’s not a good one, but it works. because for someone just starting out. you care about getting it to work. doesn’t really matter how it works. you just want it to work.

“That is not DotNet”… I know

before you get mad at me, I know that this is not how you’re supposed to write dotnet code. you’re supposed to use the repository, unit of work,service patterns a little bit of Domain Driven Design with Clean Architecture maybe even some mediatr pipelines and CQRS. but then why do you need to learn all of that? especially if your applicaiton works that way.

why do you need to learn how to write good code if you can just write code that works?

The jump from writing code that works to writing good code is a big one. it’s not something you can do in a day. it’s not something you can do in a week. not even in a month. we’re talking about years of experience. years of reading books, watching videos, and writing code. you need to learn about SOLID, DRY, KISS, all that BS. you need to learn about design patterns, you also need to learn about desgin principles and software architecture.

all of this comes easier to you if you have a grasp of what’s happening under the hood. if you know how a web server works, you can write better code. if you know how a database works, you can write better more optimized and performant queries. if you know how the framework works, you can write better software.

starting with a dotnet IMHO is like starting behind the eight ball. you’re just increasing the things you have to unlearn so that you can start learning the right way.

You can do that in any language, why single out .NET with C#?

maybe I have a grudge. but maybe I’m seeing young developers who capabale of doing great things but they’re stuck in the .NET ecosystem. they’re stuck in the Microsoft Ecosystem.

but let’s examine the languages:

  • c/c++: good luck :)
  • java: spring boot is a thing
    • spring is not as easy as dotnet and you will have to be more hands on
  • python: seek professional help if you want to write a web server in python
    • yet, you still get to learn more using python than using dotnet
  • ruby: no one uses ruby anymore
    • same as python
  • php: YUCK
    • same as python
  • javascript/typescript
    • there is like a billion frameworks and libraries and you will most likely create your own framework
  • go: same as js/ts but much better more low level and you will most likely create your own fork on top of the net/http or valyala/fasthttp package
  • rust: good luck :)

so why single out dotnet? because it’s the easiest to get started with. it’s the easiest to get something working. Microsoft is doing one hell of a marketing job. it’s documented well and it does the most harm.

dw javascript does the second most harm. but that’s a different story. bc the framework freenzy over there is just insane ahem react ahem express ahem angular ahem

The Microsoft Ecosystem

C# and .NET are made by Microsoft. A company that has a monopoly on the development tools market. they have a monopoly on the operating system market. they have a monopoly on the office suite market. they have a great presense in the cloud market.

let’s go back to the example we had earlier. you want to publish your web api. you right click on the project, select publish, select azure, select the subscription, select the resource group, select the app service, and you’re done.

you now have a web server running on azure. you can open up /swagger and see the swagger page. once call the api and it works.

now sure everyone loves to use the

“I’m a software engineer, why should I care about code deployment”

but you should. you should care about how your code is deployed. you should care where your code is deployed.

what is an App Service?

TL;DR: it’s the most horrible way to deploy a web server.

in all fairness it ONLY plays nice with .NET. but it’s bad. it’s slow, it’s expensive. it’s just all bad.

the majority of the world runs on linux.

Let’s say you want to deploy your web api to a linux virtual machine. well… you can’t. not because it’s impossible. but because you don’t know how to.

you have a dockerfile, but how do you run it … well back on windows you just press the green play button and it works.

but on linux the story is different, the system expects you to know the basics. But how will you know the basics if you’ve never done it before especially when you always had a green play button that does it for you with a single click.

what if you wanna run multiple instances of your web api on a linux server?

NGINX: *enters the chat*

These are all things you will have to deal with as a software engineer. I Know words like reverse proxy, load balancer, docker, kubernetes, linux, nginx are scary but they’re not. they’re just words. they’re just tools. and these are tools you should be familiar with even as a junior developer.

An Anecdote

I handle a fair share of the interviews at my company. For context, we’re a Microsoft Partner. Naturally we would get a lot of .NET developers applying for jobs. I would say 90% of the .NET developers who applied have a minimum of 8-10 years of experience. and they all have the same problem. they’re all stuck. They deal with programming concepts via the ways their framework tells them to.

I would ask them what is a middleware? ANS: “I’m not sure”

I would ask them what is a Filter? ANS: “functions that run before or after a request”

Middlewares and Filters are the same thing. but they don’t know that. they don’t know that because they never had to deal with the underlying concepts.

I would ask what protocols does HTTP use? No one knows.

I would ask what is a reverse proxy? No one knows.

-- given the following table
CREATE TABLE Rankings(
    name varchar(40) not null unique,
    category varchar(40) not null,
    time integer not null
);

Values:

namecategorytime
John100M4020
Emma200M4901
Alex100M4123
Anne100M3999
Oliver200M4805

I would ask them to write a query that returns the the name, category, and time of the fastest runner in each category.

Most of them would struggle to get through the question since there is a restriction on only using raw SQL. they’re used to using Entity Framework,and once I’ve allowed them to use EF, they would get through the question in a breeze.

see the problem here is that they don’t know how to write SQL and that’s the problem with being a one framework andy. you don’t know how to do things without the abstractions of the framework. being too reliant on the framework is a bad thing. it inherently limits you by the amount of abstractions and shortcut it has.

In the end

I’m not the authority on what you should or shouldn’t do. I’m just sharing my opinion. If you like .NET and you want to learn it, go ahead more power to you. but if you’re just starting out, I would recommend you start with something else. something that doesn’t abstract away the underlying concepts. Abstractions and Shortcuts are great, but they’re only powerful if you are familiar with what’s being abstracted away.

Getting a shortcuts doesnt work when the foundation of your knowledge is a zero.

What should I learn then?

Well that’s a good question. Sadly I’m not the authority on that either. I shouldn’t be the one to tell you what to learn. You should be the one to decide what works best for you. This only works if you do your research. Research helps you make informed decisions. It also helps you avoid the pitfalls of the hype train. Just because everyone is trying go, oCaml, Rust, or Zig doesn’t mean you should too. no one knows what works best for you better than you.

if there is one thing I can recommend is that you learn the basics. pick a compiled strongly typed language. learn the basics of the language, try to avoid the frameworks.