Speaker 1: Welcome listener to this custom tailored deep dive. Today we
Speaker 1: are well, we're doing a bit of demolition.
Speaker 2: Yeah, quite a bit actual.
Speaker 1: So, if you were building an enterprise web app on
Speaker 1: the Microsoft Stack anytime over say a sixteen year period,
Speaker 1: you are basically living in this massive, incredibly luxurious mansion.
Speaker 2: Oh absolutely, it had everything.
Speaker 1: Literally everything, Intricate security systems, elaborate plumbing, pre built rooms
Speaker 1: for any feature you could ever possibly want. But there
Speaker 1: was a catch, a huge catch. Yeah, it was completely
Speaker 1: hopelessly bolted to the ground. You could not move this house, right.
Speaker 3: The plumbing was like physically welded to the city's main
Speaker 3: water line, which in this case was Windows Internet Information Services.
Speaker 1: Or IA exactly. So if you wanted just to pick
Speaker 1: up your application and move it to a cheaper Linux server,
Speaker 1: good luck. You'd have to rip the entire city's pipe
Speaker 1: system out of the ground of.
Speaker 2: It, which is obviously impossible.
Speaker 1: Right. So today our mission is to unpack the mechanics,
Speaker 1: the history, and the architecture of the moment Microsoft decided
Speaker 1: to just dynamite that mansion. We're looking at how they
Speaker 1: rebuilt modern web architecture from the ground up with ASP
Speaker 1: dot net.
Speaker 3: Core, and we're using Andrew Locke's book asp Net Core
Speaker 3: in Action as our primary source material for this.
Speaker 1: Yes we are. But strangely enough, to really understand how
Speaker 1: they pulled this off, we have to start by looking
Speaker 1: at an illustration from eighteen oh two.
Speaker 2: Yeah, the cover of the book.
Speaker 1: It's so good, it's wild. It's a picture of an
Speaker 1: ottoman admirle right.
Speaker 3: A capuota on pasha, and he's looking incredibly regal. He's
Speaker 3: got this towering hat, a fur lined robe. I mean,
Speaker 3: it is a massive departure from your standard minimalist tech
Speaker 3: book esthetic, definitely.
Speaker 1: But the story of how that specific piece of art
Speaker 1: ended up on an asp net manual, it perfectly captures
Speaker 1: the whole philosophical shift Microsoft ad to make.
Speaker 2: It really does.
Speaker 3: So. An editor from Manning Publications actually found this antique
Speaker 3: illustration at a flea market in New York City.
Speaker 1: Just sitting there at flea market, Cort.
Speaker 2: Yeah.
Speaker 3: The editor didn't have the cash on hand to buy it,
Speaker 3: and the seller was actually flying back to Anchor a
Speaker 3: Turkey that very night, so.
Speaker 1: They couldn't just do it the next day, right, So.
Speaker 3: They made a handshake deal. The seller just handed over
Speaker 3: the portfolio based purely on a promise that the funds
Speaker 3: would be wired the next morning.
Speaker 1: I mean that is just that transaction relied entirely on trust, right, trust,
Speaker 1: modularity and this incredible cross border exchange.
Speaker 3: Yeah, the seller trusted a completely disparate system to deliver
Speaker 3: the results.
Speaker 1: And the funny thing is Microsoft's original ASP dot net
Speaker 1: operated in the exact opposite.
Speaker 2: Way, completely the opposite.
Speaker 1: It was this closed, deeply entangled ecosystem, and the core
Speaker 1: of the problem rested on one single immovable dependency, System
Speaker 1: dot web dot DL.
Speaker 3: Yeah, System dot web dot DLL. That specific file was
Speaker 3: the concrete foundation of that old mansion you were talking about, right.
Speaker 3: It wasn't just like a library your code referenced. It
Speaker 3: was woven directly into the broader dot net framework.
Speaker 1: Which was baked right into Windows itself.
Speaker 3: Exactly deep into the Windows Operating System kernel.
Speaker 1: And so if system dot web dot do well is
Speaker 1: tied to the OS kernel, that means updating your web
Speaker 1: framework is practically impossible without updating Windows itself.
Speaker 2: Yeah, it was an absolute nightmare.
Speaker 1: I can't even imagine a developer couldn't just you know,
Speaker 1: patch a minor web routing bug without forcing the whole
Speaker 1: enterprise to do a massive system wide Windows regression test.
Speaker 3: Right, So release cycles routinely took years years, Yeah, because
Speaker 3: the framework had to maintain backward compatibility with over a
Speaker 3: decade of legacy enterprise features. And worse than that, it
Speaker 3: aggressively locked out developers working on macOS or Linux machine.
Speaker 1: You just you couldn't participate in the ASP dot and
Speaker 1: an ecosystem natively at all.
Speaker 2: You really couldn't.
Speaker 3: So the paradigm shift finally happened when Microsoft introduced dot
Speaker 3: net Core as an entirely separate open source runtime.
Speaker 1: They finally decoupled it exactly.
Speaker 3: They decoupled the web framework from the operating system entirely.
Speaker 3: It finally delivered on that compile once on anywhere promise.
Speaker 1: So a developer could finally sit on a Mac, write
Speaker 1: some c shark code, build it, and deploy those exact
Speaker 1: same binaries too, like a nUbuntu server in the cloud.
Speaker 3: Yep and breaking those dependencies didn't just make it cortable,
Speaker 3: it opened the door for staggering performance games.
Speaker 1: Oh the speed, let's talk about the speed.
Speaker 2: Yeah.
Speaker 3: Microsoft introduced a brand new built in cross platform web
Speaker 3: server called Kestrel.
Speaker 1: Kestrel and when you look at the tech empower benchmarks
Speaker 1: for this, Kestrel consistently ranks among the top ten fastest
Speaker 1: mainstream full stack web frameworks in the world.
Speaker 3: It's incredibly fast, and the performance leap comes mostly from.
Speaker 2: What Kestrel doesn't do.
Speaker 1: Okay, what do you mean, Well.
Speaker 3: The legacy ICE integration forced every single HTTP request through
Speaker 3: this bloated pipeline of modules, right like it would check
Speaker 3: for legacy Windows authentication protocols or active directory hooks, things
Speaker 3: that modern rest APIs.
Speaker 2: Simply don't use.
Speaker 1: Just a bunch of dead weight.
Speaker 2: Exactly, So Kestrel strips all of that away.
Speaker 3: It's built on modern asynchronous IO and non blocking.
Speaker 1: Sockets, not just sitting around waiting, right.
Speaker 3: It doesn't waste thread capacity waiting for a disc or
Speaker 3: network operation to finish. It acts as this incredibly lean,
Speaker 3: specialized processing engine optimized purely for raw HTTP throughput.
Speaker 1: Okay, let's unpack this because knowing Kestrel is that fast
Speaker 1: makes the actual deployment architecture seem well a little contradictory.
Speaker 1: How so, so our source material points out that an
Speaker 1: average web page day the Amazon hometage, for example, it
Speaker 1: fires off nearly three hundred separate HTTP requests just to
Speaker 1: render a single view.
Speaker 3: Oh yeah, mostly images and scripts.
Speaker 1: Right, So that obviously needs to be handled with extreme efficiency.
Speaker 1: But when one of those requests hits an ASP dot
Speaker 1: net core server, it doesn't actually go straight to Kestrel.
Speaker 2: No, it doesn't.
Speaker 1: It's a reverse proxy first, like Nginx or apacheon Linux
Speaker 1: or isis on Windows. So why build a blazing fast
Speaker 1: server like Kestrel only to bottleneck the whole architecture by
Speaker 1: placing a second, older web server directly in front of it.
Speaker 3: It's a great question, and it comes down to a
Speaker 3: really strict architectural boundary. It's about the separation of concerns. Okay,
Speaker 3: the public Internet is frankly.
Speaker 1: Chaotic, absolute wild west.
Speaker 3: Yeah, server is constantly getting bombarded with slow Loris attacks,
Speaker 3: malformed headers, dedoss attempts, just endless idle connections.
Speaker 1: Right, all this garbage traffic exactly.
Speaker 3: So Kestrel is an Olympic sprinter. You do not want
Speaker 3: your sprinter fighting off a mob before the race even starts.
Speaker 3: Oh I like that analogy, right, So a reverse proxy
Speaker 3: like Nginx acts as the riot shield.
Speaker 1: Riot shield.
Speaker 3: Yeah, it's battle hardened over decades to absorb the chaos
Speaker 3: of the public Internet. It handles TLS termination, decrypting the
Speaker 3: HTTPS traffic, and it manages connection pooling.
Speaker 1: So the proxy sanitizes the environment exactly. Kestrel never has
Speaker 1: to worry about security protocols or dropped connection yeah. Ngix
Speaker 1: just filters out the noise, takes the clean raw bites
Speaker 1: of the actual HTTP request, and hands off to Kestral
Speaker 1: over a super secure local looppac.
Speaker 3: And Kestrel's only concern at that point is parsing those
Speaker 3: clean bites. It packages them into a neatly organized C
Speaker 3: sharp object called an HTTP.
Speaker 1: Context HTTP context Yeah, and.
Speaker 3: Then it passes that context down the line for the
Speaker 3: application to evaluate.
Speaker 1: And because we've severed the application from the operating system,
Speaker 1: the application is entirely responsible for figuring out what to
Speaker 1: do with that HTTP context, right.
Speaker 3: It can't rely on ICE to boot it up anymore
Speaker 3: or to tell it how to route the traffic, which.
Speaker 1: Leads us perfectly into the anatomy of how an as
Speaker 1: dot net core application actually constructs itself. Because when a
Speaker 1: developer opens a new project, they are immediately confronted with
Speaker 1: two foundational files, program dot cs and startup dot cs.
Speaker 3: Yeah, and for developers coming from legacy web backgrounds. Program
Speaker 3: dot cs appears deeply counterintuitive, oh for sure, because it
Speaker 3: contains a static void main.
Speaker 1: Function, which is I mean, that's the exact signature you
Speaker 1: use for a standard run of the mill console application
Speaker 1: in like a beginner's programming class.
Speaker 2: Exactly.
Speaker 3: An enterprise grade cloud scalable web app is, under the hood,
Speaker 3: just a console application that spins up a web post
Speaker 3: and refuses to acceit.
Speaker 1: That is so wild. So program dot cs handles all
Speaker 1: the heavy structural plumbing yep. It configures kestrol, it wires
Speaker 1: up the logging providers, It establishes the connection to that
Speaker 1: Nginx reverse proxy we just talked about. Basically, it builds
Speaker 1: the physical.
Speaker 3: Building, right, but the building is completely empty until the
Speaker 3: framework evaluates startup dot cs.
Speaker 1: The personalities exactly.
Speaker 3: Startup dot CS injects the logic, the routing rules, the
Speaker 3: whole personality of the application.
Speaker 1: So it's the menu and the staff of the restaurant.
Speaker 3: That's a perfect way to put it. And the really
Speaker 3: fascinating mechanical detail here is how the framework actually interacts
Speaker 3: with this file.
Speaker 1: Right. Because it's not a standard interface, is it.
Speaker 3: No, startup doesn't implement a rigid, predefined interface. Instead, the
Speaker 3: framework utilizes reflection.
Speaker 1: Reflection.
Speaker 3: Yeah, so during the boot process, the dot Net run
Speaker 3: time scans its own compiled assembly memory. It actively searches
Speaker 3: for a class named startup, and then it stands inside
Speaker 3: that class for two specific method signatures.
Speaker 1: Configure services and configure You got it, And reflection allows
Speaker 1: the framework to dynamically invoke those methods at runtime without
Speaker 1: making the developer inherit from some bloated base class.
Speaker 2: Exactly. It keeps things so clean.
Speaker 1: So let's look at that first dynamically invoked method, configure services.
Speaker 1: This is the mechanism the application uses to handle dependency injection. Ah. Yes,
Speaker 1: dependency injection, which is a concept that often gets treated
Speaker 1: like you know, dark magic. But it's actually a very
Speaker 1: rigid system built around the single responsibility principle.
Speaker 3: Yeah, it's very logical once you break it down.
Speaker 1: So how does the source break it down?
Speaker 3: Well, say an application needs to calculate an order total.
Speaker 3: That logic shouldn't be cluttered up with all the math
Speaker 3: required to determine state tax or figure out shipping weight.
Speaker 1: Right, you want to keep that separate.
Speaker 3: So you create a distinct tax calculator class. And a
Speaker 3: separate shipping service.
Speaker 1: Class makes sense.
Speaker 3: Now, in a tightly coupled legacy application, your order service
Speaker 3: would manually instantiate those dependencies using the new keyword.
Speaker 1: Oh so you'd say new tax.
Speaker 3: Calculator exactly, which means your order service becomes hard coded
Speaker 3: to those specific implementations.
Speaker 1: And if the tax calculator certainly needs to say poll
Speaker 1: data from a third party API, and now it requires
Speaker 1: an apikey in its constructor, you have to go back
Speaker 1: and rewrite the order service just to pass that new
Speaker 1: parameter down right.
Speaker 3: It causes this cascating failure across your entire code base.
Speaker 1: It's an absolute headache.
Speaker 3: But dependency injection solves this by using an inversion of
Speaker 3: control container, which is basically a centralized registry of recipes recipe. Yeah,
Speaker 3: so inside configure services, the developer registers those recipes. They
Speaker 3: tell the IOC container, Hey, whenever a class asks for
Speaker 3: the i tax calculator interface, instantiate this specific tax calculator class.
Speaker 1: Got it. So when the order service boots up, it
Speaker 1: simply declares its requirements in its constructor yep, and then
Speaker 1: the framework just pauses consults its internal registry recursively builds
Speaker 1: the entire tree of required dependencies and injects them seamlessly exactly.
Speaker 3: The service never cares how the text calculator was built
Speaker 3: or what its underlying dependencies are. It just trusts the
Speaker 3: container to provide it.
Speaker 1: That is so elegant. So once the services are mapped
Speaker 1: out in configure services, the framework moves on to the
Speaker 1: second method it found vieaw reflection.
Speaker 2: The configure method, right, and this.
Speaker 1: Method explicitly defines the middleware pipeline. It dictates exactly how
Speaker 1: that httke pot context object, the one generated by kestrel,
Speaker 1: is going to be processed.
Speaker 3: Fundamentally, the pipeline is an assembly line. The HTTP context
Speaker 3: travels through a sequence of middleware components. These are small,
Speaker 3: really focused blocks of code that can inspect the request,
Speaker 3: modify it, or generator response. The application defines this sequence
Speaker 3: in configure, and this is crucial. The order of execution
Speaker 3: is absolute.
Speaker 1: It is absolute, and that can be a trap. Right,
Speaker 1: Like what happens if a developer carelessly places authorization middleware
Speaker 1: before authentication middleware.
Speaker 3: Oh that triggers a catastrophic logic failure.
Speaker 1: Yeah.
Speaker 3: Yeah, because the pipeline attempts to verify if the user
Speaker 3: has admin privileges before the system has even extracted the
Speaker 3: user's identity claims from their authentication cookie.
Speaker 1: Because they haven't authenticated.
Speaker 3: Yet exactly, So the pipeline triggers a four oh one
Speaker 3: unauthorized instantly. It locks out valid users simply because the
Speaker 3: HTTP context assembly line.
Speaker 2: Was out of order.
Speaker 1: Wow, so order is everything.
Speaker 3: Absolutely, But beyond strict ordering, the pipeline's behavior can also
Speaker 3: dynamically mutate based on its deployment environment.
Speaker 1: Right, and that's managed by an injected parameter called IE
Speaker 1: hosting environment.
Speaker 3: Yes, the framework checks a simple environment variable on the
Speaker 3: host machine to determine if it's running locally on a
Speaker 3: developer's laptop or if it's you know, live in a
Speaker 3: production server cluster.
Speaker 1: Which is so smart because if the environment variable reads development,
Speaker 1: the framework wires up the developer exception page middleware.
Speaker 3: Ah, the white screen of death.
Speaker 1: The white screen of death, but a helpful one. When
Speaker 1: the code inevitably crashes, this middleware catches the exception and
Speaker 1: renders this deeply diagnostic web page.
Speaker 2: It's incredible.
Speaker 3: It exposes raw stack traces, memory variables, database connection strings.
Speaker 1: Even the exact line of failing c Sharre code directly
Speaker 1: in the browser.
Speaker 3: Yeah, it is an amazing tool for tracking down a
Speaker 3: null reference bug.
Speaker 1: But exposing all those deep structural details. It's also a
Speaker 1: massive security vulnerability if that ever got deployed to the
Speaker 1: public Internet.
Speaker 3: Oh, a catastrophic vulnerability.
Speaker 1: Right. So, by reading the environment variable, the framework structurally
Speaker 1: protects the application.
Speaker 3: Exactly in a production environment, it bypasses that developer exception
Speaker 3: page entirely, and it wires up an exception handler middleware instead.
Speaker 1: And what does that do.
Speaker 3: It catches the crash, swallows the sensitive stack trace, logs
Speaker 3: it securely to an internal file, and then returns are
Speaker 3: really benign, stylized five hundred internal server error page.
Speaker 2: To the user.
Speaker 1: Nothing to see here, basically.
Speaker 2: Exactly just a polite error message.
Speaker 1: Now, since we've removed the rigid structure of ICE, the
Speaker 1: application is completely responsible for its own file security too.
Speaker 3: Right, It can't hide behind Windows directory permissions anymore.
Speaker 1: So that forces a new architectural paradigm for handling static assets,
Speaker 1: which introduces a dedicated directory called ww root.
Speaker 3: Yeah, the ww root folder it establishes a non negotiable boundary,
Speaker 3: a safe zone, a completely safe zone. It acts as
Speaker 3: the singular public facing directory for the entire application. Okay,
Speaker 3: so the castral server is configured to serve static files
Speaker 3: like CSS style sheets, compiled JavaScript bundles images exclusively from
Speaker 3: this folder.
Speaker 1: So if a malicious actor attempts, say a path traversal
Speaker 1: attack like manipulating the URL to request the raw sea
Speaker 1: Sharp back end files located just one directory up from ww.
Speaker 3: Root, the static file middleware simply ignores the request and
Speaker 3: return 's a four h four not found.
Speaker 1: Wow.
Speaker 3: Yeah, the internal source code is architecturally walled off from
Speaker 3: the public routing table.
Speaker 1: That is so clean. And this systemic cleanup of the
Speaker 1: application structure extends directly into how the project files are
Speaker 1: managed too.
Speaker 3: Oh thank goodness, because legacy dot net developers spent years
Speaker 3: fighting with c sproge files.
Speaker 1: Ooh, the c sproge files.
Speaker 3: Yah is massive monolithic XML documents filled with seemingly random goods,
Speaker 3: and every single file in the application had to be
Speaker 3: manually declared in that XML document.
Speaker 1: Right, So if two developers on a team added different
Speaker 1: files to the project on separate branches, merging, that resulting
Speaker 1: c's prod conflict was.
Speaker 2: Agonizing hours of lost productivity.
Speaker 1: But aspn at core modernized the build engine to use
Speaker 1: implicit file includes. Yes, the compiler simply scans the project
Speaker 1: directory and automatically assumes any c sharp file it finds
Speaker 1: is part of the application. So the XML file is
Speaker 1: stripped down to just a few readable lines, and.
Speaker 3: The dependency management got the same aggressive optimization.
Speaker 1: Right.
Speaker 3: Instead of a massive list of individual package references, developers
Speaker 3: now use a meta package like Microsoft dot asp Net Core.
Speaker 1: Oh so it's like an umbrella exactly.
Speaker 3: It acts as an umbrella reference, pulling in the entire
Speaker 3: supported ecosystem of asp dot net Core libraries behind the
Speaker 3: scenes without cluttering up the project file.
Speaker 1: Now here's where it gets really interesting. Abstracting away that
Speaker 1: complexity enables the most significant workflow shift of all.
Speaker 2: Yeah, it really does.
Speaker 1: Because the build engine and the project files are so lean. Now,
Speaker 1: developers are no longer shackled to a massive, gigabyte heavy
Speaker 1: integrated development environment like visual Studio.
Speaker 3: Right, the underlying compiler mechanics are exposed directly through the
Speaker 3: dot Net command line interface, the CLI. The CLI it
Speaker 3: completely democratizes the framework. A developer opens a basic terminal
Speaker 3: on a Linux machine and runs dot net new MBC
Speaker 3: to generate the templated.
Speaker 1: Architecture just one command yep.
Speaker 3: Then running dot net restore resolves the package dependencies over
Speaker 3: the network. Dot Net build invokes the MS build engine
Speaker 3: to comp file the source.
Speaker 1: Code, and then dot net run spins up the Kestrel server,
Speaker 1: binding it to a local port for testing. So a
Speaker 1: workflow that previously required a dedicated Windows machine and expensive
Speaker 1: IDE license and hours of configuration can now be executed
Speaker 1: entirely from a lightweight text editor like visual Studio code
Speaker 1: on a MacBook.
Speaker 2: It's beautiful.
Speaker 3: It removes every barrier to entry that kept the Microsoft
Speaker 3: stack isolated from the broader open source community for a decade.
Speaker 2: And a half.
Speaker 1: So what does this all mean?
Speaker 3: Well, stepping back to look at the entire scope of
Speaker 3: what we've unpacked, it becomes pretty clear that asp net
Speaker 3: core is not merely an iterative update, not at all.
Speaker 3: It is a fundamental reinvention of Microsoft's web philosophy. It
Speaker 3: prioritizes decoupled modularity, relentless speed via Kestrel, and absolute platform independence.
Speaker 1: You the listener, now have a comprehensive mental map of
Speaker 1: how a modern web request travels. You know why Nginx
Speaker 1: acts as the riot shield, absorbing the chaos before handing
Speaker 1: the raw bites to Kestrel. You understand how Kestrel packages
Speaker 1: that data and sends it down a rigidly defined middleware
Speaker 1: pipeline dictated by startup dot cos. You see how the
Speaker 1: IOC container uses reflection and dependency injection to map interfaces
Speaker 1: to implementations on the fly.
Speaker 2: You aren't just memorizing syntax.
Speaker 1: Anymore, right, You are deeply understanding the architectural machinery driving
Speaker 1: the modern web.
Speaker 3: And analyzing that machinery presents a really fascinating concept to
Speaker 3: consider going forward.
Speaker 1: What's that?
Speaker 3: Well, we've seen how asp dot net core turns everything
Speaker 3: into an interchangeable dependency. The application is completely decoupled from
Speaker 3: the operating system, and the Kestral server itself is just
Speaker 3: another modular component spun up by a console app.
Speaker 1: Yeah.
Speaker 3: So if back end architecture is becoming this lightweight, this
Speaker 3: universally portable, and this fundamentally disconnected from the underlying host.
Speaker 1: Hardware, where are you going with this?
Speaker 3: What is stopping the traditional boundary between the server and
Speaker 3: the browser from eventually blurring into one unified, location agnostic
Speaker 3: execution environment.
Speaker 1: Oh wow, that implies a future where the execution environment
Speaker 1: is completely location agnostic, like a compiled code doesn't care
Speaker 1: if it's processing an HTTP context on an AWS server
Speaker 1: cluster in Virginia or if it's executing directly inside the
Speaker 1: memory space of the web browser on the phone in
Speaker 1: your pocket.
Speaker 3: It's all just modular, portable infrastructure.
Speaker 1: That is wild, and it brings us full circle to
Speaker 1: that antique portfolio in the New York flea market. It
Speaker 1: really does de banning editor shaking hands with a stranger,
Speaker 1: trusting that the framework of their transaction would hold up
Speaker 1: across international borders. That is precisely what this architecture accomplishes.
Speaker 1: It reaches across operating systems, shakes hands across disparate environments,
Speaker 1: and seamlessly delivers the result