Blog Dla Programistów C#/.NET

Czysta architektura to styl projektowania aplikacji, który kładzie nacisk na uporządkowanie kodu w wyraźne warstwy i oddzielenie logiki biznesowej od szczegółów technicznych. Dzięki temu rdzeń aplikacji (domena) może działać niezależnie od np. bazy danych czy frameworków. Koncepcję tę spopularyzował Robert C. Martin (Uncle Bob), a w środowisku .NET często łączy się ją z takimi podejściami jak architektura cebuli (Onion) czy portów i adapterów (hexagonal). Główną zasadą jest odwrócenie zależności: logika biznesowa i model aplikacji trafiają do centrum systemu, a wszelkie komponenty infrastruktury (dostęp do danych, serwisy zewnętrzne itp.) zależą od tego rdzenia, nie odwrotnie. Dzięki takiemu rozdziałowi warstwy aplikacji są luźniej sprzężone – łatwiej jest je rozwijać niezależnie i pisać dla nich testy jednostkowe.

Czysta Architektura w .NET - Praktyczny Przewodnik z Przykładami

Kluczowe założenia i warstwy


Czysta architektura realizuje kilka kluczowych zasad (m.in. SOLID). Kod dzieli się zazwyczaj na warstwy Core (domena), Infrastruktura i Prezentacja (UI):
    
Warstwa Core/Domena: zawiera encje biznesowe (modele domenowe), agregaty oraz interfejsy abstrakcji dla operacji technicznych (np. IRepository, interfejsy usług domenowych). Ta warstwa nie zna szczegółów implementacyjnych, określa co aplikacja ma robić, a nie jak.
    
Warstwa Infrastruktury: zawiera implementacje interfejsów z warstwy Core (np. klasę DbContext i repozytoria EF Core, usługi logowania, dostęp do plików itp.). Projekt infrastruktury odnosi się do Core, realizując konkretne operacje technologiczne.
    
Warstwa Prezentacji/UI: to np. projekt ASP.NET Core MVC lub Web API z kontrolerami, widokami i modelami widoków. Odwołuje się do interfejsów zdefiniowanych w Core i łączy je ze szczegółowymi implementacjami poprzez Dependency Injection (w Program.cs). W tej warstwie nie powinno być bezpośrednich odniesień do klas infrastruktury, wszystko podłączamy przez zadeklarowane w Core interfejsy.

Poniższy przykład pokazuje uproszczony układ zależności: mamy serwis domenowy ProductService korzystający z interfejsu repozytorium, a konkretna klasa SqlProductRepository realizuje dostęp do bazy. Dzięki temu ProductService nie zna szczegółów bazy, tylko operuje na interfejsie z warstwy Core.

/* Warstwa Core: interfejs repozytorium w domenie */
public interface IProductRepository
{
Product GetById(int id);
}

/* Warstwa Infrastruktury: implementacja repozytorium (np. EF Core) */
public class SqlProductRepository : IProductRepository
{
public Product GetById(int id) { /* kod dostępu do bazy */ }
}

/* Warstwa Core: serwis domenowy korzystający z repozytorium */
public class ProductService
{
private readonly IProductRepository _repo;

public ProductService(IProductRepository repo)
{
_repo = repo;
}

public Product GetProduct(int id)
{
return _repo.GetById(id);
}
}

W powyższym przykładzie ProductService komunikuje się wyłącznie przez interfejs IProductRepository zdefiniowany w rdzeniu aplikacji, a SqlProductRepository dostarcza konkretną implementację. Taki układ sprawia, że możemy łatwo zastępować warstwę infrastruktury (np. zmienić bazę danych) i testować logikę domenową w izolacji (bez konieczności podpinania prawdziwej bazy).


Zalety czystej architektury


Stosowanie czystej architektury przynosi kilka istotnych korzyści:

-Niezależność od technologii: Logika biznesowa jest odizolowana od szczegółów implementacyjnych (baz danych, frameworków, API zewnętrznych itp.), co ułatwia zmiany (np. migrację danych) bez przebudowy całego kodu.

-Testowalność: Warstwy Core (domena) można testować samodzielnie, bo nie wymagają podłączenia zewnętrznych usług. Rdzeń aplikacji nie zależy od infrastruktury, co znacznie upraszcza pisanie testów jednostkowych.

-Modularność i wymienialność: Poszczególne komponenty (jak repozytoria, mechanizmy uwierzytelniania czy logowania) są łatwe do zastąpienia lub modyfikacji, bo wystarczy dostarczyć nową implementację interfejsów z Core.

-Przejrzysta organizacja kodu: Jasny podział na warstwy pomaga zespołowi łatwiej zrozumieć strukturę projektu, każdy wie, gdzie umieszczać nowe klasy (np. encje i logikę domenową w Core, implementacje dostępu do danych w Infrastruktury).


Przykład struktury projektu w .NET


W praktyce projekty .NET często dzieli się na osobne biblioteki odpowiadające warstwom:

-Proj.Core – biblioteka z modelem biznesowym, interfejsami i logiką domenową (encje, serwisy, specyfikacje).

-Proj.Infrastructure – biblioteka z implementacją dostępu do danych i innych usług technicznych (np. DbContext EF Core, klasy repozytoriów, usługi logowania).

-Proj.Web (lub API) – aplikacja ASP.NET Core (MVC/Web API) zawierająca kontrolery, widoki, modele widoków oraz konfigurację ( Startup/Program ), która rejestruje w DI odpowiednie implementacje (services.AddScoped<IProductRepository, SqlProductRepository>() itp.).

-(opcjonalnie) Proj.Application/Services – dodatkowa warstwa (biblioteka) z przypadkami użycia (serwisami aplikacyjnymi) jako pośrednik między UI a domeną, jeśli potrzebna jest bardziej złożona logika koordynująca operacje na wielu modelach.

Taki układ pozwala zachować porządek – kod każdego projektu ma jasne przeznaczenie, a wdrożenie aplikacji pozostaje proste.


Podsumowanie


Czysta architektura to sprawdzony sposób na budowanie elastycznych i łatwych w rozwoju aplikacji .NET. Dzięki wyraźnemu oddzieleniu warstw (domena, infrastruktura, UI) kod staje się przejrzystszy, mniej podatny na przypadkowe powiązania i gotowy na przyszłe zmiany. Ważne jest konsekwentne stosowanie zasady odwrócenia zależności oraz rejestracja implementacji w centralnym miejscu (composition root), co pozwala utrzymać porządek i zapewnić testowalność.

Jeśli temat Cię zainteresował i chcesz zobaczyć, jak projektować takie aplikacje od podstaw oraz tworzyć zaawansowane rozwiązania ASP.NET Core (MVC + Web API), zapraszam do szkolenia online Szkoła ASP.NET Core, w którym praktycznie pokazuję, jak krok po kroku budować nowoczesne, dobrze zaprojektowane systemy.

Autor artykułu:
Kazimierz Szpin
Kazimierz Szpin
CTO & Founder - FindSolution.pl
Programista C#/.NET. Specjalizuje się w Blazor, ASP.NET Core, ASP.NET MVC, ASP.NET Web API, WPF oraz Windows Forms.
Autor bloga ModestProgrammer.pl
Dodaj komentarz

Wyszukiwarka

© Copyright 2025 modestprogrammer.pl | Sztuczna Inteligencja | Regulamin | Polityka prywatności. Design by Kazimierz Szpin. Wszelkie prawa zastrzeżone.