- •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
From this point on, the CLI will start printing the debug output from the different running containers. If you want to run your containers in the background, you can use the -d flag.
Listing 9-10. Running Docker Compose in the background
docker-compose up -d
The Docker Compose file can be further expanded by adding volumes for persistent storage or network capabilities; all the information on how to do that can be found at the official Docker Compose documentation.
Dapr
The Distributed Application Runtime (Dapr) provides APIs that simplify microservice connectivity. The complete documentation for Dapr is found at https://docs.dapr.io/. It is a Microsoft-owned open-source project that can help simplify the management
of large distributed systems. Consider it a “Microservices toolkit.” Dapr provides capabilities such as service-to-service communication, state management, publish/ subscribe messaging pattern, observables, secrets, and so on. All these capabilities are abstracted away by Dapr’s building blocks. Dapr by itself is large enough to fill an entire book; what I want to do here is give you an idea of what Dapr is about so you can determine for yourself if you can use it in your project.
Installing Dapr
First step is installing the Dapr CLI. Dapr provides scripts that download the binaries and updates path variables. The easiest way is to execute the script in Listing 9-11. Other ways to install can be found on https://docs.dapr.io/getting-started/install- dapr-cli/.
Listing 9-11. Installing Dapr CLI
powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/ master/install/install.ps1 | iex"
270
Chapter 9 Application Architecture
Once the CLI is installed, we need to initialize our Dapr environment by calling dapr init on the command line. Make sure to have Docker installed before Dapr, as Dapr relies on containers to get its components up and running locally.
Figure 9-9. Setting up Dapr
Once initialized, we can find some new containers running in our local Docker setup.
Figure 9-10. Dapr containers running on Docker
Now we have everything set up, we can get to work. Dapr works according to the sidecar pattern. Meaning that we don’t have to include all components and code in our own application; we only need to make Dapr API calls that go to the sidecar that is attached to our application. That sidecar abstracts all logic away from us.
The sidecar pattern is a design pattern where components of an application are deployed into separate processes or containers. This provides isolation and encapsulation.
271
Chapter 9 Application Architecture
Dapr State Management
Let’s use the Dapr state management component as an example. State management in Dapr is done by default through Redis Cache. Dapr abstracts the logic of setting up Redis and calling its APIs away from us. We only need to call Dapr APIs to get state management up and running.
For this example, I have created a blank Console application using .NET 6.
Listing 9-12. Calling Dapr state management
using Dapr.Client;
const string storeName = "daprstate"; const string key = "counter";
var daprClient = new DaprClientBuilder().Build();
var counter = await daprClient.GetStateAsync<int>(storeName, key);
while (true)
{
Console.WriteLine($"Counter state: {counter++}");
await daprClient.SaveStateAsync(storeName, key, counter); await Task.Delay(1000);
}
We need to add the Dapr.Client NuGet package to the project and make sure Dapr is up and running. Once everything is set up correctly, we can start Dapr and run our .NET 6 application inside the Dapr environment with the Redis sidecar. Listing 9-13 shows the command that we can use to launch our application.
Listing 9-13. Launching the application using Dapr CLI
dapr run --app-id DaprCounter dotnet run
272