01 - Intro
What this course is really about
This course is about building web applications with C# and ASP.NET Core, but the long-term topic is architecture.
We will use ASP.NET Core and EF Core as practical tools, but the bigger question is this:
How do you structure a codebase so that it stays understandable when the project grows?
That is why this lecture is a map of the course, not a deep technical tutorial.
The big picture
Most applications in this course follow the same high-level flow:
Browser / frontend client
↓ HTTP
ASP.NET Core application
↓
Business logic
↓
Database
Sometimes the ASP.NET Core application returns HTML for a browser. Sometimes it returns JSON for another program. The transport is still HTTP.
What we are going to build
There are two main kinds of outputs in this course:
- Server-rendered web applications
- ASP.NET Core MVC or Razor Pages
- the server returns HTML
- Web APIs
- ASP.NET Core Web API
- the server returns JSON or other serialized data
Both use the same platform. The main difference is what the client expects in the response.
What the next lectures will cover
This lecture stays high level. The next lectures go into the mechanics in detail:
- ASP.NET Core
- project structure
- controllers, views, routing, model binding, middleware
- MVC and Web API
- EF Core
- entities,
DbContext, relationships, migrations, queries - how relational databases fit into ASP.NET Core applications
- entities,
- Architecture
- N-tier as a baseline
- Clean / Onion architecture
- modular monoliths
- microservices and their trade-offs
So the course starts with framework basics, but architecture becomes the main focus.
HTTP in one page
Web applications and APIs communicate over HTTP.
Every interaction is basically:
- a request from client to server
- a response from server to client
Common HTTP methods:
GET- read dataPOST- create data or submit a formPUT/PATCH- update dataDELETE- remove data
Common response codes:
200 OK201 Created204 No Content400 Bad Request401 Unauthorized403 Forbidden404 Not Found409 Conflict500 Internal Server Error
For APIs in this course, the most common data format is JSON.
MVC vs Web API
ASP.NET Core supports both server-rendered applications and APIs.
MVC / Razor Pages
- Best when the server renders HTML
- Good for classic CRUD apps, admin panels, and internal tools
- Browser talks directly to the ASP.NET Core app
Web API
- Best when the server returns data instead of HTML
- Good when the backend is consumed by JavaScript, mobile apps, or another backend
- The client app becomes separate from the server
The important idea is that these are not separate worlds. They are two delivery styles on top of the same platform.
Why EF Core matters
Almost every real application needs persistence.
Entity Framework Core gives us:
- entity classes
DbContext- LINQ queries
- relationship mapping
- migrations
EF Core is a productivity tool, not magic.
You still need to understand:
- relational data
- keys and relationships
- SQL basics
- what kind of SQL your ORM generates
If the generated SQL is bad, the application is still bad.
Architecture progression in this course
The course is not just about building one app. It is about seeing how architecture evolves as complexity grows.
1. N-tier as the baseline
The starting point is usually something like this:
Web -> Services -> Data Access -> Database
This is simple, fast to explain, and good enough for many small systems.
It also teaches useful habits:
- controllers should not do everything
- business logic should not live in views
- data access should not be scattered across the whole app
But N-tier has an important weakness: dependencies usually flow toward the data access layer. That makes large systems harder to test and harder to change.
2. Clean / Onion architecture
Later we revisit the same problem and flip the dependency direction:
Infrastructure -> Domain <- Application <- Web
The core idea is simple:
- business rules should be at the center
- frameworks and databases should stay on the outside
- external technology choices should be replaceable
This is where dependency inversion becomes practical, not theoretical.
3. Modular monolith
Even clean layers are not enough if the whole system becomes one tangled blob.
A modular monolith keeps one deployment, but splits the codebase into clear modules with explicit boundaries.
One deployable application
└── multiple internal modules
This is often the most useful real-world middle ground:
- simpler than microservices
- more structured than a classic monolith
- easier to evolve later
4. Microservices
Microservices go one step further:
- separate deployables
- separate ownership boundaries
- communication over the network
That can help in the right context, but it also introduces new problems:
- distributed communication
- partial failures
- eventual consistency
- deployment and monitoring overhead
So the point of this course is not "microservices are modern, therefore use them". The point is to understand when extra architectural complexity is justified and when it is not.
Low coupling and high cohesion
Two ideas will keep showing up throughout the course:
- Low coupling
- one part of the system should not know too much about another part
- a change in one area should not force unrelated changes elsewhere
- High cohesion
- code that belongs together should stay together
- one module or class should have one clear reason to exist
If you remember only one architecture heuristic from this lecture, remember this:
Low coupling between parts, high cohesion inside parts.
Web services in this course
In a broad sense, a web service means program-to-program communication over the web.
In this course, when we say "service" or "API", we usually mean:
- HTTP
- JSON
- REST-style endpoints
- OpenAPI / Swagger documentation
SOAP still exists in enterprise systems, but it is not the main focus here.
What the course is trying to teach you
This course is not mainly about memorizing framework APIs.
It is trying to teach you how to:
- build working ASP.NET Core applications
- persist data with EF Core
- expose and consume APIs over HTTP
- keep controllers thin and responsibilities clear
- understand why architectural boundaries exist
- make trade-offs instead of copying trends
Practical mindset for the course
A few working rules:
- Start simple, but structure the code so it can evolve.
- Do not put all logic into controllers.
- Do not treat EF Core as a substitute for database knowledge.
- Do not choose microservices just because the word sounds modern.
- Prefer designs you can explain and defend.
- AI can help with implementation, but it does not replace design judgment.
Course aims
By the end of the course, you should be able to:
- build ASP.NET Core MVC applications and Web APIs
- use EF Core for common relational data access tasks
- explain the difference between N-tier, Clean / Onion, modular monolith, and microservices
- choose an architecture appropriate to the problem
- justify your technical decisions in terms of coupling, cohesion, maintainability, and trade-offs
One-sentence summary
We will use ASP.NET Core and EF Core to learn not only how to build web applications, but how to structure them so they remain maintainable as they grow.
Some drawings to visualize the concepts
Clean Architecture

Modular monolith



Microservices

How to communicate between modules?
- Synchronous communication between modules is easy to implement, and it's performant. But it comes at the cost of tight coupling between modules.
- Asynchronous communication using a message broker is loosely coupled. But it's more complex to implement.
We will look into mediator pattern (behavioral design pattern that lets you reduce chaotic dependencies between objects).
HTTP Reminder
- Request
GET https://localhost:44363/People/Create HTTP/1.1
Host: localhost:44363
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: https://localhost:44363/People
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,et;q=0.8
Cookie: _ga=GA1.1.1433392067.1524809543;
- Response
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/10.0
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcYWthdmVyXHNvdXJjZVxyZXBvc1xIVFRQVGVzdFxXZWJBcHBcUGVvcGxlXENyZWF0ZQ==?=
X-Powered-By: ASP.NET
Date: Sat, 26 Jan 2019 12:24:13 GMT
Content-Length: 3367
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Create - WebApp</title>
HTTP - POST
- Request
POST https://localhost:44363/People/Create HTTP/1.1
Host: localhost:44363
Connection: keep-alive
Content-Length: 194
Cache-Control: max-age=0
Origin: https://localhost:44363
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: https://localhost:44363/People/Create
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,et;q=0.8
Cookie: _ga=GA1.1.1433392067.1524809543;
Name=Andres&__RequestVerificationToken=CfDJ8JXfYWVYzpxPgG_38dOFAzHQGkoaDtNMXtzBr3vNUFUDOYe7XT_ueh6IMyEfRXYWTTOvd2Bjm8gxjOwN8jRBGngeIIKZmnJB-xD4Wvd1enqy0M5GrgAWVgAOg0vZPgHNzvIYDBTmwJqi3L2WYM-5mm4
- Response
HTTP/1.1 302 Found
Location: /People
Server: Microsoft-IIS/10.0
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcYWthdmVyXHNvdXJjZVxyZXBvc1xIVFRQVGVzdFxXZWJBcHBcUGVvcGxlXENyZWF0ZQ==?=
X-Powered-By: ASP.NET
Date: Sat, 26 Jan 2019 12:17:16 GMT
Content-Length: 0
Response codes
- 1xx Informational response
- 100 continue
- 101 switching protocols
- 2xx Success
- 200 OK
- 201 Created
- 202 Accepted
- 204 No Content
- 3xx Redirection
- 300 Multiple choices
- 301 Moved Permanently
- 302 Found
- 303 See other
- 304 Not Modified
- 4xx Client errors
- 400 Bad Request
- 401 Unauthorized
- 403 Forbidden
- 404 Not Found
- 409 Conflict
- 5xx Server errors
- 500 Internal Server Error
- 501 Not implemented
- 503 Service Unavailable
What to Know for Code Defense
Be prepared to explain:
- Why start with N-tier before Clean Architecture? — N-tier teaches the fundamentals of layer separation. You need to feel the coupling pain of downward-pointing dependencies before dependency inversion makes practical sense.
- Why does architecture matter if the app is small? — Small apps grow. Structuring code so it can evolve prevents rewrites later. The cost of adding structure early is low; the cost of restructuring a tangled codebase later is high.
- What is the difference between MVC and Web API in ASP.NET Core? — They are two delivery styles on the same platform. MVC returns HTML for browsers; Web API returns serialized data (JSON) for programmatic clients. The underlying middleware, routing, and DI infrastructure are shared.
- Why is "low coupling, high cohesion" the central architecture heuristic? — Low coupling means a change in one part does not force unrelated changes elsewhere. High cohesion means code that belongs together stays together. Together they make systems understandable, testable, and evolvable.
- Why not jump straight to microservices? — Microservices add distributed communication, partial failures, eventual consistency, and deployment overhead. These costs are only justified when organizational or scaling constraints demand separate deployables. Most projects benefit more from a well-structured monolith or modular monolith.
- Why is EF Core not a substitute for SQL knowledge? — EF Core generates SQL. If the generated SQL is inefficient, the application is still slow. Understanding relational data, keys, indexes, and joins is necessary to evaluate and optimize what the ORM produces.