
- •Table of Contents
- •About the Author
- •Acknowledgments
- •Introduction
- •Version Support
- •Supported Versions
- •A Unified Platform
- •Roadmap
- •Supported Operating Systems
- •Command Line Interface
- •Desktop Development
- •Blazor
- •MAUI
- •Wrapping Up
- •.NET 6 Architecture
- •Runtimes
- •CoreCLR
- •Mono
- •WinRT
- •Managed Execution Process
- •Desktop Packs
- •Wrapping Up
- •Dotnet New
- •Dotnet Restore
- •NuGet.config
- •Dotnet Build
- •Dotnet Publish
- •Dotnet Run
- •Dotnet Test
- •Using the CLI in GitHub Actions
- •Other Commands
- •Wrapping Up
- •WinAPI
- •WinForms
- •STAThread
- •WinForms Startup
- •DPI Mode
- •Responding to Scale Events
- •Visual Styles
- •Text Rendering
- •The Message Loop
- •The Form Designer
- •WPF Startup
- •XAML Layout
- •Visual Tree
- •Data Binding
- •Windows App SDK
- •Building a Windows App SDK application
- •Using Windows APIs with Windows App SDK
- •Packaging
- •Migrating to .NET 6
- •Upgrade Assistant
- •Wrapping Up
- •Blazor WebAssembly
- •Creating a Blazor Wasm Project
- •Blazor Progressive Web Apps
- •Exploring the Blazor Client Project
- •Blazor in .NET 6
- •Blazor Component System
- •Creating Blazor Pages
- •Running a Blazor App
- •Blazor Server
- •SignalR
- •Blazor Desktop
- •Wrapping Up
- •Project Structure
- •Exploring MAUI
- •The Cross-Platform World
- •Application Lifecycle
- •MVVM
- •MVVM Toolkit
- •Wrapping Up
- •Model-View-Controller
- •Routing
- •Views
- •Controllers
- •Controller-Based APIs
- •Minimal APIs
- •Wrapping Up
- •Web Apps
- •Creating an App Service
- •Static Web Apps
- •Web App for Containers
- •Docker
- •Azure Functions
- •Deploying Azure Functions
- •Wrapping Up
- •Record Types
- •Monolith Architecture
- •Microservices
- •Container Orchestration
- •Kubernetes
- •Docker Compose
- •Dapr
- •Installing Dapr
- •Dapr State Management
- •Wrapping Up
- •Roslyn
- •Compiler API
- •Diagnostic API
- •Scripting API
- •Workspace API
- •Syntax Tree
- •Roslyn SDK
- •Source Generators
- •Writing a Source Generator
- •Debugging Source Generators
- •Wrapping Up
- •Garbage Collector
- •The Heap
- •The Stack
- •Garbage Collection
- •A Look at the Threadpool
- •Async in .NET 6
- •Await/Async
- •Cancellations
- •WaitAsync
- •Conclusion
- •Index

Chapter 9 Application Architecture
Monolith Architecture
Monolith applications are applications that contain everything in one or two services. Usually a frontend and a backend. Before Microservices, which we will talk about next, monoliths were very common. Figure 9-1 describes what a monolith architecture looks like.
Figure 9-1. Monolith architecture
In this example, we have a web client and a mobile client; both speak to the same API that in turn is connected to a data store. Depending on the size of the application, this API can potentially be huge. Let’s say there is one part of the API that is seeing intense usage and is slowing the entire API down. To solve this, we would need to scale the entire API or move it to a server with more power. Even worse, the entire system can go down because of a bottleneck in one place.
Another disadvantage of monolith services is maintainability. One big service containing all business logic is hard to maintain or even to keep an overview of what is where in the source code.
However, not everything is bad about monolith architecture. Depending on the size and complexity of your application, this might still be the right choice for you as microservices create extra layers of complexity besides the advantages they bring.
263

Chapter 9 Application Architecture
Microservices
Microservice architecture is a variation on service-oriented architecture. Creating a Microservices-based application means that the backend is split up into different loosely coupled services. Each service has its own responsibility and has no knowledge of the other services. Communication between services usually happens over a message bus. To prevent applications having to implement multiple endpoints, we can implement a gateway per application or type of application should we need to. That gateway knows the endpoints of the Microservices the application needs. Figure 9-2 shows a high-level architecture schema for a Microservices-based application.
Figure 9-2. Microservices architecture
There is a lot to like about a Microservices-oriented architecture. The split responsibilities mean that we can scale the parts where scaling is needed instead of just pumping more memory into the virtual server. We can create gateways per client so that only the absolute necessary parts of the backend platform are exposed and so on. It also brings with it added complexity and cost; since each service is basically its own application, we need a lot of application servers; all of those servers need to be
maintained. Even if we went with a container orchestration system like Kubernetes, we get extra overhead, and exactly this is the danger of overengineering or over-architecting an application. Microservices are a great architecture pattern, but they are not the silver bullet for all applications; depending on your use case, a monolith application might be just fine.
264