
이전 기사 에 따라 클린 아키텍처의 기본 사례를 소개했습니다. 이제 디렉터리 구조부터 시작하여 ASP.NET Core 3을 사용하여 애플리케이션을 빌드할 것입니다. 계속 진행하기 전에 빠른 요약.
요약

이 다이어그램에서 종속성은 가장 안쪽 원으로 흐릅니다. Application Core는 이 다이어그램의 핵심 위치에서 이름을 따왔습니다. 그리고 다이어그램에서 Application Core가 다른 애플리케이션 계층에 대한 종속성이 없음을 확인할 수 있습니다. 애플리케이션의 엔티티와 인터페이스는 바로 그 중심에 있습니다. 바로 바깥에 있지만 여전히 Application Core에는 일반적으로 내부 원에 정의된 인터페이스를 구현하는 도메인 서비스가 있습니다. Application Core 외부에서 UI 및 인프라 계층은 모두 Application Core에 의존하지만 서로 의존하지는 않습니다(반드시).
Application Core는 인프라에 의존하지 않기 때문에 이 계층에 대한 자동화된 단위 테스트를 작성하기가 매우 쉽습니다.

UI 계층은 인프라 프로젝트에 정의된 유형에 대한 직접적인 종속성이 없기 때문에 테스트를 용이하게 하거나 변화하는 애플리케이션 요구 사항에 대한 응답으로 구현을 교체하는 것도 마찬가지로 매우 쉽습니다. ASP.NET Core의 종속성 주입에 대한 기본 제공 사용 및 지원 덕분에 이 아키텍처는 사소하지 않은 모놀리식 애플리케이션을 구조화하는 가장 적절한 방법입니다.
전제 조건
- 비주얼 스튜디오
- .NET Core SDK (사용 중인 Visual Studio 버전을 지원하는 SDK를 찾으세요. 저는 Visual Studio 2019 및 .NET Core 3.1을 사용 중입니다.)
- .NET Core 웹 애플리케이션, MVC, C#, SQL Server, 마이그레이션, ID, Entity Framework 및 Visual Studio에 대한 기본적인 이해
Visual Studio 2017 또는 이전 버전을 사용 중인 경우 .NET Core 2.1이 지원되는 버전입니다. 올바른 버전 받기
이 문서는 .NET Core가 아니라 Clean Architecture를 위한 프로젝트 구조를 설정하는 방법에 관한 것입니다.
혼란을 피하기 위해 이 프로젝트를 복제하고 프로젝트를 확인하여 단계별로 문서를 읽는 것이 좋습니다.
nishanc/CleanArchitectureDemo
.NET Core Clean 아키텍처를 기반으로 구축된 데모 프로젝트 – nishanc/CleanArchitectureDemo
디렉토리 구조
빈 솔루션을 만듭니다.


이제 솔루션 탐색기는 다음과 같아야 합니다.

이제 개별 프로젝트를 저장하는 데 사용할 폴더를 생성하겠습니다.
솔루션 내에 다음 폴더를 만드십시오. 이것은 단지 제안일 뿐입니다.


애플리케이션 은 인터페이스, 서비스, 비즈니스 규칙을 관리합니다. 도메인 은 엔티티로 구성되며 데이터는 데이터 에 액세스하는 방법을 알고 IoC (Inversion of Control)는 종속성 주입에 도움이 됩니다.
사용자 인터페이스
UI.MVC 폴더 아래에 MVC 웹 애플리케이션을 생성해 봅시다.


동일한 명명 규칙에 따라 프로젝트 이름을 ‘CleanArchitecture.MVC’로 지정하고 ‘만들기’를 누릅니다.


이렇게 하면 새 프로젝트가 생성되고 일부 코드가 스캐폴딩됩니다. 클린 아키텍처 접근 방식을 취하고 있으므로 나중에 모델을 나중에 엔터티로 옮길 것입니다. 완료되면 SQL Server 데이터베이스를 가리키도록 연결 문자열을 빠르게 변경해 보겠습니다. (SQL Server가 설치되어 있지 않은 경우 여기에서 개발자 버전을 다운로드하고 여기에서 SQL Server Management Studio를 다운로드 하는 것이 좋습니다 . )
로 이동 하여 서버를 가리키도록 연결 문자열을 변경합니다. Demoappsettings.json 라는 데이터베이스를 만듭니다 .
마이그레이션을 사용하여 ID 모델 클래스로 데이터베이스를 업데이트해 보겠습니다. 패키지 관리자 콘솔(도구 -> NuGet 패키지 관리자 -> 패키지 관리자 콘솔)을 열고 다음을 입력합니다.
add-migration "InitialMigration" -Context ApplicationDbContext
나중에 다른 엔터티에 대해 다른 DbContext를 갖게 되므로 여기에 DbContext 클래스 이름을 지정했습니다 . 이 명령은 “InitialMigration”이라는 마이그레이션을 생성합니다. 비어 있는 것처럼 보이지만 원하는 ID 테이블 세트를 생성합니다.

원하는 경우 ID 마이그레이션을 위한 다른 프로젝트도 가질 수 있습니다. MVC 프로젝트에서 핵심 엔터티를 이동하여 이를 수행하는 방법을 보여 드리겠습니다. 그러나 먼저 마이그레이션을 생성한 후 데이터베이스를 업데이트하겠습니다.
데이터베이스 갱신
완료되면 데이터베이스에 새로운 테이블 집합이 있는 것을 볼 수 있습니다.

이 시점에서 slandered toolbar에서 시작 프로필을 ‘CleanArchitecture.MVC’로 변경하여 이 프로젝트를 실행하고 새 사용자를 등록하고 작동하는지 확인할 수 있습니다.

애플리케이션을 반영하도록 솔루션 폴더의 이름을 바꿀 수 있다는 점을 지적하고 싶습니다. 제 이름 지정 방식을 따를 필요는 없지만 물론 깨끗한 아키텍처를 고수해야 합니다.
도메인
핵심 엔터티를 보유할 도메인 계층에 클래스 라이브러리 프로젝트를 추가해 보겠습니다.


Class1.cs 를 제거 하고 새 폴더 Models (또는 Entities)를 추가합니다. 이 기사에서는 라이브러리 시스템을 구축한다고 가정 하고 Models 폴더에 Book 모델을 추가합니다.

엔터티에 원하는 속성을 추가합니다.
수업을 공개했습니다.
이제 이 새 모델로 데이터베이스를 업데이트할 수 있도록 새 데이터베이스 컨텍스트를 만들어 보겠습니다. 인프라 계층 에서 수행할 것입니다 . Infrastructure.Data 아래 에 CleanArchitecture.Infra.Data 라는 새 클래스 라이브러리를 추가 하고 해당 폴더 아래에 Context 를 추가 합니다. 다음으로 LibraryDbContext 라는 클래스를 만듭니다 .

계속해서 이 프로젝트를 구성하는 데 필요한 패키지를 추가해 보겠습니다. 하지만 그 전에 패키지 관리자 콘솔에서 dotnet restore지금까지 가지고 있는 3개의 프로젝트를 모두 실행합니다. 그런 다음 Build -> Rebuild Solution 을 수행하십시오.

CleanArchitecture.Infra.Data 의 종속성 을 마우스 오른쪽 단추로 클릭하고 NuGet 패키지 관리 를 선택 하십시오 . 그런 다음 찾아보기 탭을 클릭하고 설치하십시오.
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
모두 안정적인 버전(미리보기가 아님)이고 동일한 버전인지 확인하세요.
이제 Microsoft.EntityFrameworkCore 에서 제공하는 DbContext에서 LibraryDbContext를 상속할 수 있습니다 . CleanArchitecture.Domain.Models 에서 제공하는 Book 엔터티를 참조하고 있음을 알 수 있습니다 . LibraryDbContext 에 다음 콘텐츠를 추가합니다.
MVC 프로젝트의 Startup.cs에서 이 새 DbContext를 구성해 보겠습니다. ConfigureServices 메서드 에 다음 줄을 추가 합니다.
LibraryConnection 연결 문자열을 확인 하여 appsettings.json에 추가해야 합니다. 이 새 연결 문자열은 도메인 엔터티를 저장할 다른 데이터베이스를 가리킵니다.
"ConnectionStrings": {
"DefaultConnection": "Server=.;Database=Demo;Trusted_Connection=True;MultipleActiveResultSets=true",
"LibraryConnection": "Server=.;Database=Library;Trusted_Connection=True;MultipleActiveResultSets=true"
}
완료되면 LibraryDbContextadd-migration 에 대해 실행합니다.

이렇게 하면 인프라 아래에 새로운 마이그레이션이 생성됩니다.

다음을 사용하여 데이터베이스 업데이트,
업데이트 데이터베이스 -Context LibraryDbContext
애플리케이션 코어
모든 서비스, 인터페이스 및 ViewModel이 여기로 이동합니다. 이전 단계와 마찬가지로 ‘ CleanArchitectureDemo.Application ‘ 폴더 아래에 CleanArchitecture.Application이라는 새 클래스 라이브러리(.NET Core) 를 만들고 다음과 같이 해당 폴더를 추가합니다.

이제 ViewModel에 대해 작업하겠습니다. A view model는 정적 텍스트에 사용되든 데이터베이스에 추가(또는 편집 가능)할 수 있는 입력 값(텍스트 상자 및 드롭다운 목록과 같은)에 사용되든 보기/페이지에 표시하려는 데이터를 나타냅니다. ). 그것은 당신의 domain model. 뷰를 위한 모델입니다. 즉, 도메인 모델에 대한 마스크를 생성합니다.
BookViewModel 이라는 ViewModels 폴더 아래에 새 클래스를 만듭니다 . 당분간 우리는 데이터베이스에서 책 목록을 얻을 것입니다. BookViewModel.cs 에 다음 코드를 추가합니다 . CleanArchitecture.Domain.Models 에서 책 을 가져오고 있음을 알 수 있습니다 .
구현하려는 기능에 대한 계약 역할을 할 새 인터페이스를 만듭니다. 나는 당신이 인터페이스에 대해 잘 알고 있기를 바라며 OOP에서 인터페이스를 만드는 이유는 이 기사의 범위를 벗어나기 때문에 여기에서 논의하지 않을 것입니다. Interfaces 폴더에서 새 인터페이스 를 만듭니다 .

이름, IBookService.cs
구현될 때 이 메서드는 책 목록을 반환하고 ViewModel에 대해서만 알고 핵심 도메인 모델인 Book에 대해서는 알지 못하므로 모든 것을 한 곳에 두는 대신 이렇게 하여 핵심 엔터티를 추상화합니다.
IBookService에 대한 구현을 작성하기 전에 데이터베이스에서 데이터를 가져오는 방법을 정의해야 합니다. 이를 위해 일반적으로 .NET에서 사용하는 것은 Entity Framework라는 ORM이지만 저장소 패턴 을 사용하여 비즈니스를 분리합니다. 응용 프로그램의 논리 및 데이터 액세스 계층.
C#의 리포지토리 디자인 패턴은 도메인 개체에 액세스하기 위해 컬렉션과 같은 인터페이스를 사용하여 도메인과 데이터 매핑 계층 사이를 중재합니다. 즉, 리포지토리 디자인 패턴은 애플리케이션의 나머지 부분과 데이터 액세스 논리 사이에서 중개자 또는 중간 계층 역할을 한다고 말할 수 있습니다.
CleanArchitecture.Domain 프로젝트 아래에 Interfaces라는 다른 폴더를 추가합니다 . IBookRepository.cs 라는 새 인터페이스를 추가합니다.

다음 메서드를 추가합니다. 이번에는 ViewModel이 아니라 도메인 엔터티 자체인 Book입니다.
좋습니다. 이 시점에서 MVC 프로젝트 또는 Presentation Layer( 도메인 엔터티 Book 에 대해 전혀 모르는 ) 가 “이봐, 책 목록을 원해요!”라고 말하면 BookService (우리가 IBookService 를 사용하여 아직 구현하지 않았 으며 BookService 는 BookRepository 에서 가져와야 합니다 ( IBookRepository 를 사용하여 아직 구현하지 않음 ) .
구현해 봅시다. 먼저, BookService입니다.
CleanArchitecture.Application 프로젝트 아래 services 폴더 아래에 새 클래스인 BookService.cs를 추가하고 IBookService 에서 상속합니다 .
이제 IBookRepository를 주입해야 합니다. 일반적으로 .NET에서 종속성 주입을 수행하는 것처럼 주입합니다.
다음은 BookRepository 입니다. CleanArchitecture.Infra.Data 프로젝트 에서 Repositories 라는 새 폴더 를 만들고 그 아래에 새 클래스인 BookRepository 를 만듭니다 .

BookService 를 구현한 것처럼 IBookRepository 에서 BookRepository 를 구현 한 다음 데이터베이스 컨텍스트를 주입해야 데이터베이스와 통신할 수 있습니다.
우리는 아직 BookService 및 BookRepository 에 메서드를 구현하지 않았 으므로 계속해서 해당 메서드를 구현해 보겠습니다.
먼저 BookRepository 로 이동 하고 주입된 컨텍스트를 사용하여 데이터베이스에서 책을 검색합니다.
다음은 BookService입니다.
다음으로 종속성을 포함하고 분리하는 데 도움이 되는 IoC 프로젝트의 구현을 살펴볼 필요가 있습니다.
통제 역전
따라서 CleanArchitectureDemo.Infrastructure.IoC 아래에서 CleanArchitecture.Infrastructure.IoC 라는 이전 프로젝트에서 했던 것처럼 새로운 .NET Core 클래스 라이브러리를 생성합니다 . Class1.cs를 제거하고 종속성 -> NuGet 패키지 관리 -> 찾아보기 탭으로 이동하여 검색하십시오.
Microsoft.Extensions.DependencyInjection
우리가 설치한 이전 종속성과 동일한 버전을 설치하고 안정적인 버전인지 확인하십시오.

이제 CleanArchitecture.Infrastructure.IoC 프로젝트 아래에 종속성 컨테이너 클래스를 생성해 보겠습니다.

여러 프로젝트의 인터페이스와 구현을 단일 참조 지점으로 연결하는 방법에 주목하십시오. 이것이 IoC 계층의 목적입니다. 또한 차이점 을 알고 싶다면 여기에서 자세한 내용을 읽으십시오.
이제 이 새로운 서비스 컨테이너에 대해 MVC 프로젝트에 알려야 합니다. Configure 메서드 뒤에 다음 메서드를 추가 한 후 Startup.cs로 이동 합니다.
이제 ConfigureServices 메서드 내에서 이 메서드를 호출해야 합니다.
RegisterServices(서비스);
전체 Startup.cs 는 다음과 같습니다 .
이제 모든 레이어가 준비되었습니다. 그래서 다음으로 여기에서 논의한 모든 것을 사용하여 Controller 를 생성 하고 UI를 구현하는 방법을 살펴보겠습니다 .
먼저 데이터베이스에 일부 데이터를 추가해 보겠습니다. GetBooks 메서드 만 구현하고 있으므로 일부 데이터를 수동으로 추가해야 합니다.
데이터베이스에 데이터가 있으면 Controllers 폴더 아래 CleanArchitecture.MVC 프로젝트에 컨트롤러를 생성해 보겠습니다.

Controllers 폴더 -> 추가 -> 컨트롤러를 마우스 오른쪽 버튼으로 클릭 하고 MVC 규칙에 따라 BookController 로 이름을 지정합니다 . 그런 다음 다음과 같이 이 컨트롤러 에 BookService 를 주입합니다.
애플리케이션 계층에서 IBookService를 참조하고 있습니다.
이제 BookViewModel을 뷰에 전달합니다.
얼마나 깨끗한 지 보세요. 그것이 깨끗한 건축의 아름다움입니다. 이제 우리는 BookViewModel을 뷰에 전달했습니다. 계속해서 해당 뷰를 정의하겠습니다.
Views 폴더를 마우스 오른쪽 버튼으로 클릭하고 Book 이라는 새 폴더를 추가합니다 . Book 폴더 를 마우스 오른쪽 버튼 으로 클릭하고 Index.cshtml이라는 Razor View 를 추가합니다 .


Index.cshtml 에서 BookViewModel 을 가져오고 모델의 모든 항목(책)을 반복하여 테이블에 표시하는 다음 코드 세그먼트를 추가합니다.
그런 다음 Views/Shared 아래의 _Layout.cshtml 로 이동하고 방금 만든 보기에 다른 탐색 링크를 추가합니다. Book 컨트롤러와 Index 작업 을 가리킵니다 .
이제 MVC 프로젝트를 실행하고 https://localhost:5001/Book 으로 이동하여 책 을 볼 수 있습니다!

하지만 아직 로그인을 하지 않은 상태이기 때문에 사용자가 인증 없이 데이터를 볼 수 있도록 허용하는 것은 문제이며 해결하기 쉽습니다.
컨트롤러 자체의 Index() 메서드에 [Authorize] 특성을 추가 한 다음 https://localhost:5001/Book 으로 다시 이동해 봅니다.

로그인하라는 메시지가 표시됩니다. 또한 우리가 생성한 서비스와 리포지토리에 중단점을 배치하고 런타임에서 어떻게 작동하는지 확인할 수 있습니다.
그게 다야, 여기까지 와줘서 고마워. 이것은 모든 것을 설정하는 방법에 대한 소개 가이드일 뿐이며 클린 아키텍처를 구현하는 다양한 방법이 있지만 여기에서 논의한 핵심 개념이 있습니다. 따라서 다음에 더 광범위한 튜토리얼을 접할 때 길을 잃지 않을 것입니다.

이것에서 더 나아가고 싶다면 JASON TAYLOR 의 비디오를 보거나 Clean Architecture 에 대한 그의 놀라운 기사를 읽는 것이 좋습니다 .