Clean Architecture & Coding Standards

Best Practices für C#‑Projekte

graph TD
    %% Schichten
    CR["<b>Composition Root</b><br/>Program.cs"]
    Pres["<b>Presentation</b><br/>UI & ViewModels"]
    App["<b>Application</b><br/>Use-Cases & Interfaces"]
    Dom["<b>Domain</b><br/>Entities & Rules"]
    Infra["<b>Infrastructure</b><br/>Persistence & External Services"]

    %% Abhängigkeitsfluss mit technischer Begründung
    CR -- "Dependency Injection & Config" --> Pres
    CR -- "Dependency Injection & Config" --> App
    CR -- "Dependency Injection & Config" --> Infra

    Pres -- "nutzt App-Services / DTOs" --> App
    
    App -- "nutzt Fachobjekte" --> Dom
    
    Infra -- "implementiert Interfaces (Ports)" --> App
    Infra -- "persistiert / nutzt" --> Dom

    %% Colors
    style Dom fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px
    style App fill:#fff9c4,stroke:#fbc02d
    style CR fill:#f9f,stroke:#333
    style Infra fill:#f5f5f5,stroke:#999
    style Pres fill:#e1f5fe,stroke:#01579b
    
Schicht / Projekt Verantwortung / Inhalt
Composition Root App‑Start, Dependency Injection, Konfiguration, Options‑Binding (Program.cs).
Presentation UI (Razor Pages), WPF, PageModel, Input‑Validierung, Mapping auf DTOs/ViewModels, Lokalisierung über .resx. Keine Fachlogik.
Application Use‑Cases / Anwendungslogik (Orchestrierung), Commands/Queries, DTOs, Ports/Interfaces (z. B. IOrderRepository). Keine UI- und keine DB‑Details.
Domain Fachlicher Kern (Core Business): Entities, Value Objects, Invarianten/Regeln, Domain Events. Keine Abhängigkeit zu EF Core, ASP.NET Core, UI.
Infrastructure Technische Details: DB/EF Core, Repository‑Implementierungen, externe Services (HTTP, Mail, File), Caching, Identity‑Adapter. Referenziert Application/Domain, nicht umgekehrt.

Clean Architecture: Simplified and In-Depth Guide | by DrunknCode | Medium

Clean Architecture Reference Guide: Everything You Need to Know About Clean Architecture | Bitloops Docs

Clean Code and Clean Architecture | by Configr Technologies | Stackademic

1. Clean Architecture & Feature Isolation

Clean Architecture trennt Software in klar definierte Schichten, sodass Geschäftslogik unabhängig von Frameworks, UI und Datenquellen bleibt. Dadurch entsteht ein System, die testbar, flexibel und langfristig wartbar sind.

graph TD
    subgraph Circle4 [Frameworks & Drivers]
        direction TB
        subgraph Circle3 [Interface Adapters]
            subgraph Circle2 [Use Cases]
                subgraph Circle1 [Entities]
                end
            end
        end
    end

    style Circle1 fill:#c8e6c9,stroke:#2e7d32
    style Circle2 fill:#fff9c4,stroke:#fbc02d
    style Circle3 fill:#e1f5fe,stroke:#01579b
    style Circle4 fill:#f5f5f5,stroke:#999

Ergänzend sorgt Feature Isolation (Vertical Slice Architecture) dafür, dass Use‑Cases und fachliche Funktionen vertikal gekapselt werden. Zusammen entsteht eine Architektur, die sowohl technisch sauber als auch fachlich modular ist.

graph TD

    %% --- FEATURE: ORDERS ---
    subgraph Orders ["Feature: Orders"]
        direction TB
    
        ODom["<b>Domain</b><br/>Entities & Rules"]
        OApp["<b>Application</b><br/>Use-Cases & Interfaces"]
        OPres["<b>Presentation</b><br/>UI & ViewModels"]
        OInfra["<b>Infrastructure</b><br/>Persistence & External Services"]
    end
    
    %% --- FEATURE: CUSTOMERS ---
    subgraph Customers ["Feature: Customers"]
        direction TB
    
        CDom["<b>Domain</b><br/>Entities & Rules"]
        CApp["<b>Application</b><br/>Use-Cases & Interfaces"]
        CPres["<b>Presentation</b><br/>UI & ViewModels"]
        CInfra["<b>Infrastructure</b><br/>Persistence & External Services"]
    end
    
    %% --- OPTIONAL: COMPOSITION ROOT ---
    CR["<b>Composition Root</b><br/>Program.cs"]
    
    %% --- DEPENDENCIES ---
    %% Orders
    OPres --> OApp
    OApp --> ODom
    OInfra --> OApp
    OInfra --> ODom
    
    %% Customers
    CPres --> CApp
    CApp --> CDom
    CInfra --> CApp
    CInfra --> CDom
    
    %% Composition Root wiring
    CR --> OPres
    CR --> OApp
    CR --> OInfra
    
    CR --> CPres
    CR --> CApp
    CR --> CInfra
    
    %% --- COLORS ---
    %% Domain
    style ODom fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px
    style CDom fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px
    
    %% Application
    style OApp fill:#fff9c4,stroke:#fbc02d
    style CApp fill:#fff9c4,stroke:#fbc02d
    
    %% Presentation
    style OPres fill:#e1f5fe,stroke:#01579b
    style CPres fill:#e1f5fe,stroke:#01579b
    
    %% Infrastructure
    style OInfra fill:#f5f5f5,stroke:#999
    style CInfra fill:#f5f5f5,stroke:#999
    
    %% Composition Root
    style CR fill:#f9f,stroke:#333

Softwarearchitektur – Grundlagen
https://learn.microsoft.com/de-de/azure/architecture/guide/

2. Dependency Rule

Die Dependency Rule besagt, dass alle Abhängigkeiten nur nach innen zur Domäne zeigen dürfen, nie von der Domain nach außen. So bleibt die Geschäftslogik unabhängig von technischen Details wie Datenbanken, UI oder Frameworks.

public interface IOrderRepository
{
    Task<int> AddAsync(Order order);
}

Architekturprinzipien (inkl. Dependency Inversion)
https://learn.microsoft.com/de-de/azure/architecture/guide/design-principles/

3. Schichtenmodell & Aufgaben

Domain
 ├─ Entities
 ├─ Value Objects
 └─ Domain Rules

Application
 ├─ Use Cases
 ├─ DTOs
 └─ Interfaces

Infrastructure
 ├─ Persistence
 ├─ External Services
 └─ Implementations

Presentation
 ├─ API / Controllers
 └─ UI

Das Schichtenmodell sorgt dafür, dass jede Ebene eine klar abgegrenzte Verantwortung hat. Änderungen in UI oder Infrastruktur beeinflussen die Domäne so wenig wie möglich.

Layer Aufgabe
Domain Geschäftslogik (use case), Entities, Value Objects, Regeln, Repository-Interface.
Unabhänig von Frameworks, UI, Datenbanken.
Alle Abhängigkeiten zeigen nach innen (Dependency Rule)
Application Interface, Use‑Case‑Orchestrierung, DTOs, Services.
Kommuniziert nur über Interface mit Domain & Infrastruktur.
Keine UI- oder Datenbanklogik.
Infrastructure Implementierung Repository-Interface, Datenzugriff, APIs, ORM (EF Core), externe Systeme, Implementierungen
Presentation UI, Controller (MVC, Razor Pages), API‑Endpoints.
Ruft Use Cases auf, enthält keine Gechäftslogik

Beispiel‑Entity

public class Order
{
    public int Id { get; }
    public decimal Amount { get; }

    public Order(int id, decimal amount)
    {
        if (amount <= 0)
            throw new ArgumentException("Amount must be positive.");

        Id = id;
        Amount = amount;
    }
}

Beispiel‑Use‑Case

public class CreateOrder
{
    private readonly IOrderRepository _repo;

    public CreateOrder(IOrderRepository repo)
    {
        _repo = repo;
    }

    public Task<int> ExecuteAsync(decimal amount)
    {
        var order = new Order(0, amount);
        return _repo.AddAsync(order);
    }
}

Beispiel‑Repository‑Implementierung

public class OrderRepository : IOrderRepository
{
    private readonly AppDbContext _db;

    public OrderRepository(AppDbContext db)
    {
        _db = db;
    }

    public async Task<int> AddAsync(Order order)
    {
        _db.Orders.Add(order);
        await _db.SaveChangesAsync();
        return order.Id;
    }
}

Beispiel‑API‑Controller

[ApiController]
[Route("api/orders")]
public class OrdersController : ControllerBase
{
    private readonly CreateOrder _createOrder;

    public OrdersController(CreateOrder createOrder)
    {
        _createOrder = createOrder;
    }

    [HttpPost]
    public async Task<IActionResult> Create(decimal amount)
    {
        var id = await _createOrder.ExecuteAsync(amount);
        return Ok(new { OrderId = id });
    }
}

Architektur‑Stile & Schichtenmodelle
https://learn.microsoft.com/de-de/azure/architecture/guide/architecture-styles/

4. Projektstruktur

Die physische Projektstruktur in Visual Studio sollte das logische Schichtenmodell widerspiegeln. So wird die Architektur im Code sichtbar und ist für alle Teammitglieder intuitiv nachvollziehbar.

src/
 ├── Project.Domain
 ├── Project.Application
 ├── Project.Infrastructure
 ├── Project.Api 
 └── Project.Web / Desktop 
 

.NET Projektstruktur & Best Practices
https://learn.microsoft.com/de-de/dotnet/architecture/modern-web-apps-azure/

5. Architektur‑Guidelines

Architektur‑Guidelines stellen sicher, dass die Struktur auch bei wachsender Codebasis stabil bleibt. Sie helfen, Abhängigkeiten zu kontrollieren und technische Entscheidungen von der Geschäftslogik zu entkoppeln.

Prinzip Bedeutung
Independence of Frameworks Frameworks sind austauschbare Details
Separation of Concerns Jede Schicht hat eine klar abgegrenzte Aufgabe
Interface‑Driven Design Kommunikation über Interfaces statt Implementierungen
Testability Domain & Use Cases isoliert testbar
Business Logic Independence Geschäftslogik bleibt frei von technischen Details (UI, DB, Frameworks)
Feature Isolation Modularität durch vertikale Slices; Features sind klar gekapselt
Layer Stability Wartbarkeit durch definierte Schichten
Technology Flexibility Austauschbarkeit von UI, Datenbank oder Infrastruktur ohne Domänenänderung

Design‑Prinzipien (SOLID, DRY, KISS, SoC)
https://learn.microsoft.com/de-de/azure/architecture/guide/design-principles/

6. Domain‑Driven Design (DDD)

DDD ergänzt Clean Architecture, indem es die inhaltliche Gestaltung der Domäne in den Mittelpunkt stellt. Ziel ist ein Modell, das die Fachlichkeit präzise abbildet und gemeinsam mit den Fachexperten entwickelt wird.

6.1 Kernkonzepte

DDD arbeitet mit einem Set klarer Bausteine, um die Domäne zu strukturieren. Diese helfen, Fachlogik explizit zu machen und technische Details außen vor zu lassen.

Konzept Bedeutung
Ubiquitous Language Gemeinsame Sprache von Fach & Entwicklung
Entities Objekte mit Identität
Value Objects Unveränderliche Werte ohne Identität
Aggregates Konsistenzgrenzen
Aggregate Root Einstiegspunkt eines Aggregats
Domain Events Fachliche Ereignisse
Repositories Zugriff auf Aggregate

DDD – Domain Model
https://learn.microsoft.com/de-de/azure/architecture/microservices/model/domain-model

6.2 Aggregate

Ein Aggregate bündelt logisch zusammengehörende Daten und Regeln hinter einer Root, um Konsistenz und Invarianten zentral zu halten. Alle Zugriffe laufen über die Aggregate Root. Beispiel:

classDiagram
    class Order {
        <<Aggregate Root>>
        +Guid OrderId
        -List~OrderLine~ _orderLines
        +AddLine(Product product, int quantity)
        +Total() decimal
    }

    class OrderLine {
        <<Value Object>>
        +int Quantity
        +decimal Price
        +Guid ProductId
    }

    Order "1" *-- "many" OrderLine : enthält

DDD – Domain Model
https://learn.microsoft.com/de-de/azure/architecture/microservices/model/domain-model

6.3 Entity & Value Object

Entities repräsentieren Objekte mit Identität, Value Objects fassen Werte zusammen, die durch ihre Eigenschaften definiert sind. Zusammen bilden sie die Grundlage für ein reiches Domänenmodell.

public record Money(decimal Amount);

public class Order
{
    private readonly List<OrderLine> _lines = new();
    public IReadOnlyCollection<OrderLine> Lines => _lines;

    public void AddLine(int productId, Money price, int quantity)
        => _lines.Add(new OrderLine(productId, price, quantity));
}

public class OrderLine
{
    public int ProductId { get; }
    public Money Price { get; }
    public int Quantity { get; }

    public OrderLine(int productId, Money price, int quantity)
    {
        ProductId = productId;
        Price = price;
        Quantity = quantity;
    }
}

DDD – Entities & Value Objects
https://learn.microsoft.com/de-de/azure/architecture/microservices/model/domain-model#entities-and-value-objects

6.4 Zusammenspiel mit Clean Architecture

Clean Architecture liefert das technologische Gerüst, DDD füllt die Domänenschicht mit fachlich sauberen Modellen. Gemeinsam verhindern sie, dass Geschäftslogik in Controller, ORM‑Modelle oder Infrastruktur abrutscht.

Clean Architecture DDD‑Bezug
Entities Entities & Value Objects
Use Cases Application Services / Use Cases
Domain Layer im Zentrum Bounded Context / Domänenkern

DDD – Strategic Design (Bounded Contexts)
https://learn.microsoft.com/de-de/azure/architecture/microservices/model/domain-driven-design

7. Design‑Patterns

CQS:
  Command = Zustand ändern
  Query   = Daten lesen

Factory:
  Erzeugt komplexe Objekte/Requests

Strategy:
  Austauschbare Policies (z.B. UploadPolicy)

Facade:
  Einfache API über komplexen Abläufen

Parser:
  XML/JSON → Domain-Objekte

Design‑Patterns liefern erprobte Lösungsansätze für wiederkehrende Struktur‑ und Verhaltensprobleme. In Kombination mit Clean Architecture und DDD sorgen sie für klaren, gut wartbaren Code.

7.1 Command/Query Separation (CQS)

CQS trennt Operationen in solche, die Zustand ändern (Commands), und solche, die nur lesen (Queries). Das erhöht Verständlichkeit und erleichtert Testbarkeit.

public interface ICommand<TRequest, TResponse>
{
    Task<TResponse> ExecuteAsync(TRequest request, CancellationToken ct = default);
}

CQRS Pattern
https://learn.microsoft.com/de-de/azure/architecture/patterns/cqrs

7.2 Factory Pattern

Factories kapseln die Erstellung komplexer Objekte oder Requests, sodass Erzeugungslogik nicht in der Geschäftslogik verstreut wird.

public interface IRequestFactory
{
    HttpRequestMessage CreateGetRequest(string path);
}

Factory Method Pattern
https://learn.microsoft.com/de-de/azure/architecture/patterns/factory-method

7.3 Strategy Pattern

Strategien kapseln austauschbare Verhaltensweisen (z. B. Upload‑Politiken oder Retry‑Strategien), ohne dass der aufrufende Code geändert werden muss.

public interface IUploadPolicy
{
    void Apply(HttpRequestMessage request, UploadRequest upload);
}

Strategy Pattern
https://learn.microsoft.com/de-de/azure/architecture/patterns/strategy

7.4 Facade Pattern

Eine Fassade versteckt komplexe Abläufe hinter einer einfachen API und entkoppelt Clients von internen Services. Das vereinfacht die Nutzung und reduziert Abhängigkeiten.

public class DocumentProviderFacade : IDocumentProvider
{
    private readonly IRequestFactory _requestFactory;
    private readonly IResponseParser _parser;
    private readonly HttpClient _httpClient;

    public DocumentProviderFacade(
        IRequestFactory requestFactory,
        IResponseParser parser,
        HttpClient httpClient)
    {
        _requestFactory = requestFactory;
        _parser = parser;
        _httpClient = httpClient;
    }

    public async Task<ListDocumentsResponse> ListDocumentsAsync(string path, CancellationToken ct = default)
    {
        var request = _requestFactory.CreateGetRequest(path);
        var response = await _httpClient.SendAsync(request, ct);
        return await _parser.ParseListDocumentsAsync(response, ct);
    }
}

Facade Pattern
https://learn.microsoft.com/de-de/azure/architecture/patterns/facade

7.5 Parser Pattern

Parser kapseln die Transformation externer Datenformate (XML, JSON, etc.) in Domain‑Objekte. So bleibt das Domänenmodell frei von Format‑ und Protokoll‑Details.

public interface IResponseParser
{
    Task<ListDocumentsResponse> ParseListDocumentsAsync(HttpResponseMessage response, CancellationToken ct = default);
}

public class XmlDocumentResponseParser : IResponseParser
{
    public async Task<ListDocumentsResponse> ParseListDocumentsAsync(HttpResponseMessage response, CancellationToken ct = default)
    {
        var xml = await response.Content.ReadAsStringAsync(ct);
        var xDoc = XDocument.Parse(xml);

        var items = xDoc.Descendants("item")
            .Select(x => new DocumentItem(
                name: (string)x.Element("name")!,
                size: (long?)x.Element("size") ?? 0,
                modified: DateTime.Parse((string)x.Element("modified")!)
            ))
            .ToList();

        return new ListDocumentsResponse(items);
    }
}

Adapter Pattern (offizielles Microsoft‑Äquivalent)
https://learn.microsoft.com/de-de/azure/architecture/patterns/adapter

8. Implementierungsregeln

  • Horizontal: technische Trennung (Domain, Application, Infra, UI)
  • Vertikal: fachliche Trennung (z.B. Orders, Customers, Billing)
  • DDD liefert das Modell im Zentrum
  • CQS/CQRS strukturiert Use‑Cases pro Feature
graph TD

    subgraph OrdersFeature ["Feature: Orders"]
        direction TB
    
        subgraph OrdersUI ["Presentation (API/UI)"]
            OUI["CreateOrderEndpoint"]
        end
    
        subgraph OrdersApp ["Application (Use Cases)"]
            OCmd["CreateOrderCommand"]
            OHandler["CreateOrderHandler"]
            ODTO["OrderDto"]
        end
    
        subgraph OrdersDomain ["Domain (Entities & Rules)"]
            OEnt["Order Entity"]
            OVal["OrderLine ValueObject"]
            OEvent["OrderCreatedEvent"]
        end
    
        subgraph OrdersInfra ["Infrastructure (Implementations)"]
            ORepo["OrderRepository"]
            OEF["EF Core Config"]
        end
    end
    
    %% Dependencies
    OUI --> OCmd
    OCmd --> OHandler
    OHandler --> OEnt
    OHandler --> ORepo
    ORepo --> OEnt
    
    style OrdersDomain fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px
    style OrdersApp fill:#fff9c4,stroke:#fbc02d
    style OrdersInfra fill:#e1f5fe,stroke:#01579b
    style OrdersUI fill:#f5f5f5,stroke:#999
// Command Interface
Task<TResponse> ExecuteAsync(TRequest req, CancellationToken ct);

// Entity
public class Order { List<OrderLine> _lines; }

// Retry‑fähiger Stream
using var s = await req.ContentFactory(ct);

// TLS‑Client
RemoteCertificateValidationCallback = (_,_,_,e) => e == None;

Implementierungsregeln übersetzen Architektur‑ und Design‑Entscheidungen in konkrete Vorgaben für den Code. Sie helfen, Konsistenz und Robustheit im Alltag sicherzustellen.

8.1 Async First + CancellationToken

I/O‑Operationen sollten standardmäßig asynchron sein und einen CancellationToken akzeptieren. So bleiben Anwendungen reaktionsfähig und können sauber abgebrochen werden.

public async Task<UploadResponse> ExecuteAsync(
    UploadRequest request,
    CancellationToken cancellationToken = default)
{
    using var stream = await request.ContentFactory(cancellationToken);
    // Upload-Logik
}

Asynchrone Programmierung in C#
https://learn.microsoft.com/de-de/dotnet/csharp/asynchronous-programming/

8.2 Retry‑fähige Streams

Für Uploads oder Downloads sollte der Inhalt über eine Factory bereitgestellt werden. Dadurch kann der Stream bei Retries neu erzeugt werden, ohne falsch wiederverwendet zu werden.

public class UploadRequest
{
    public string TargetPath { get; init; } = default!;
    public Func<CancellationToken, Task<Stream>> ContentFactory { get; init; } = default!;
}

public class UploadCommand : ICommand<UploadRequest, UploadResponse>
{
    private readonly HttpClient _client;

    public UploadCommand(HttpClient client) => _client = client;

    public async Task<UploadResponse> ExecuteAsync(UploadRequest request, CancellationToken ct = default)
    {
        using var stream = await request.ContentFactory(ct);

        var httpRequest = new HttpRequestMessage(HttpMethod.Put, request.TargetPath)
        {
            Content = new StreamContent(stream)
        };

        var response = await _client.SendAsync(httpRequest, ct);
        return new UploadResponse(response.IsSuccessStatusCode);
    }
}

Resilienz & Retry‑Strategien (Polly)
https://learn.microsoft.com/de-de/dotnet/core/resilience/

8.3 Domain‑spezifische Exceptions

Fehler sollten mit fachlich sinnvollen Exceptions signalisiert werden, statt mit generischen technischen Fehlern. Das erleichtert Logging, Monitoring und Fehlersuche.

public class ProviderException : Exception
{
    public ProviderException(string message, Exception inner)
        : base(message, inner) { }
}

Exception‑Design‑Guidelines
https://learn.microsoft.com/de-de/dotnet/standard/design-guidelines/exceptions

9. Naming Conventions

Konsistente Benennung macht Code vorhersagbar und leicht lesbar. Entwickler können sich auf Inhalte statt auf Stilunterschiede konzentrieren.

Element Konvention Beispiel
Klassen PascalCase OrderService
Interfaces I‑Prefix + PascalCase IOrderRepository
Methoden PascalCase CalculateTotal()
Async‑Methoden Async‑Suffix LoadDataAsync()
Private Felder _camelCase _logger
Parameter/Variablen camelCase orderId
DTOs Request/Response Suffix UploadRequest
Enums Singular TransferStatus

.NET Namenskonventionen
https://learn.microsoft.com/de-de/dotnet/standard/design-guidelines/naming-guidelines

10. Clean Code

Clean Code sorgt dafür, dass die Architektur im Alltag nicht „kaputtrefaktoriert“ wird. Lesbarkeit, Klarheit und Einfachheit stehen im Vordergrund.

10.1 Prinzipien

Diese Grundprinzipien helfen, unnötige Komplexität zu vermeiden und den Fokus auf das Wesentliche zu legen.

Prinzip Bedeutung
KISS Keep It Simple, Stupid Lösungen so einfach wie möglich halten. Keine unnötige Komplexität, keine übertriebenen Abstraktionen.
DRY Don’t Repeat Yourself Wiederholungen vermeiden. Logik, Regeln und Strukturen nur einmal definieren, um Fehlerquellen und Wartungsaufwand zu reduzieren.
YAGNI You Aren’t Gonna Need It Nichts implementieren, was aktuell nicht benötigt wird. Keine vorzeitigen Erweiterungspunkte oder Features einbauen.

Design‑Prinzipien (KISS, DRY, SoC, etc.)
https://learn.microsoft.com/de-de/azure/architecture/guide/design-principles/

10.2 Methoden‑ & Klassenstruktur

Kleine, fokussierte Methoden und Klassen mit klarer Verantwortung sind leichter zu verstehen, zu testen und zu ändern.

Element Empfehlung
Methoden 5–15 Zeilen
Parameter max. 3–4
Verschachtelung max. 2–3 Ebenen

.NET Design Guidelines
https://learn.microsoft.com/de-de/dotnet/standard/design-guidelines/

10.3 Fehlerbehandlung

Fehler sollen klar und eindeutig sein und nicht als Kontrollfluss missbraucht werden. Ausnahmen sollten gezielt und sparsam eingesetzt werden.

if (amount <= 0)
    throw new ArgumentException("Amount must be positive.");

Exception‑Guidelines
https://learn.microsoft.com/de-de/dotnet/standard/design-guidelines/exceptions

11. Testing

Tests sollten die Struktur des Produktionscodes widerspiegeln und das Verhalten der Software überprüfen, nicht interne Implementierungsdetails. So bleiben Tests robust gegenüber Refactorings.

Project.Tests/
 └── Application/
 └── Domain/
 └── Infrastructure/

Unit Testing in .NET
https://learn.microsoft.com/de-de/dotnet/core/testing/

12. Security & Operations

Security‑ und Betriebsaspekte müssen von Anfang an mitgedacht werden. Sie betreffen Konfiguration, Datenhaltung, Kommunikation und Fehlerbehandlung.

12.1 Data Protection API

Sensible Informationen wie Passwörter oder Tokens sollten niemals im Klartext gespeichert werden. Eine Schutz‑Abstraktion erleichtert den Austausch der zugrunde liegenden Technologie.

public interface ICredentialProtector
{
    string Protect(string plainText);
    string Unprotect(string encryptedText);
}

ASP.NET Core Data Protection
https://learn.microsoft.com/de-de/aspnet/core/security/data-protection/introduction

12.2 HTTPS/TLS

Kommunikation mit externen Systemen sollte standardmäßig über HTTPS erfolgen. Je nach Legacy‑Umgebung kann das Validierungsverhalten konfigurierbar gemacht werden, ohne Sicherheit zu verwässern.

public class ConnectionSettings
{
    public bool UseSsl { get; set; } = true;
}

public static class HttpClientFactoryExtensions
{
    public static IHttpClientBuilder AddSecureClient(
        this IServiceCollection services,
        ConnectionSettings settings)
    {
        return services.AddHttpClient("SecureClient")
            .ConfigurePrimaryHttpMessageHandler(() =>
            {
                return new SocketsHttpHandler
                {
                    SslOptions = new SslClientAuthenticationOptions
                    {
                        RemoteCertificateValidationCallback = (sender, cert, chain, errors) =>
                        {
                            if (settings.UseSsl)
                                return errors == SslPolicyErrors.None;

                            // Optionaler Legacy-Fallback
                            return true;
                        }
                    }
                };
            });
    }
}

HTTPS erzwingen & TLS‑Konfiguration
https://learn.microsoft.com/de-de/aspnet/core/security/enforcing-ssl

13. Tooling & CI/CD

Tooling und Pipelines stellen sicher, dass Qualitätsstandards automatisch überprüft und Builds reproduzierbar sind. Sie machen Architektur‑ und Coding‑Regeln im Alltag wirksam.

13.1 Tooling

Analyser, Code‑Style‑Regeln und IDE‑Erweiterungen helfen, Fehler früh zu erkennen und Standards durchzusetzen.

Tool/Extension Zweck
Roslynator Analyzer & Fixes
SonarLint Code Quality
.editorconfig Konsistenter Stil

Code‑Analyse & .editorconfig
https://learn.microsoft.com/de-de/dotnet/fundamentals/code-analysis/overview

13.2 CI/CD

Automatisierte Builds und Tests in der CI/CD‑Pipeline sichern Qualität und verhindern, dass instabiler Code in zentrale Branches gelangt.

trigger:
  branches: [main, develop]

steps:
  - task: UseDotNet@2
  - task: DotNetCoreCLI@2 build
  - task: DotNetCoreCLI@2 test

Azure DevOps Pipelines – .NET Build & Test
https://learn.microsoft.com/de-de/azure/devops/pipelines/ecosystems/dotnet-core

14. Gesamtfazit

Clean Architecture = technische Struktur
Feature Isolation  = fachliche Struktur
DDD                = inhaltliche Struktur
Clean Code         = Saubere Umsetzung

Clean Architecture und Feature Isolation definiert die Struktur, DDD sorgt für ein fachlich stimmiges Domänenmodell und Clean Code garantiert eine saubere Umsetzung im Detail. Zusammen bilden sie einen robusten, skalierbaren und professionellen Standard für moderne C#‑Projekte, der sich in Visual‑Studio‑Lösungen direkt abbilden lässt.

Microsoft .NET Application Architecture Guides
https://learn.microsoft.com/de-de/dotnet/architecture/