본문으로 건너뛰기

ArchUnitNET 치트시트

ArchUnitNET의 핵심 API를 빠르게 참조할 수 있는 치트시트입니다. 타입 선택, 필터링, 규칙 정의, 레이어 의존성 검증까지 자주 사용하는 패턴을 코드 예제와 함께 정리했습니다. Functorium의 Validator 확장과 함께 사용하는 방법도 포함되어 있으니, 규칙 작성 시 옆에 두고 참고하세요.

using ArchUnitNET.Domain;
using ArchUnitNET.Fluent;
using ArchUnitNET.Loader;
using static ArchUnitNET.Fluent.ArchRuleDefinition;
static readonly Architecture Architecture =
new ArchLoader()
.LoadAssemblies(
typeof(SomeClass).Assembly,
typeof(AnotherClass).Assembly)
.Build();
코드설명
Classes()모든 클래스 선택
Interfaces()모든 인터페이스 선택
Types()모든 타입 선택
필터설명
.That().ResideInNamespace(ns)네임스페이스에 위치
.That().DoNotResideInNamespace(ns)네임스페이스에 위치하지 않음
.That().HaveNameStartingWith(prefix)이름이 접두사로 시작
.That().HaveNameEndingWith(suffix)이름이 접미사로 끝남
.That().HaveNameContaining(fragment)이름에 문자열 포함
.That().ArePublic()public 타입
.That().AreInternal()internal 타입
.That().AreSealed()sealed 타입
.That().AreAbstract()abstract 타입
.That().AreNotAbstract()abstract가 아닌 타입
.That().ImplementInterface(typeof(I))인터페이스 구현
.That().AreAssignableTo(typeof(T))타입에 할당 가능
.That().HaveAnyAttributes(typeof(A))어트리뷰트 보유
// And: 조건 추가
.That()
.ResideInNamespace(ns)
.And().ArePublic()
.And().AreNotAbstract()
// Or: 조건 분기
.That()
.HaveNameEndingWith("Service")
.Or().HaveNameEndingWith("Repository")
코드설명
.Should().BePublic()public이어야 함
.Should().BeInternal()internal이어야 함
.Should().BeSealed()sealed여야 함
.Should().BeAbstract()abstract여야 함
코드설명
.Should().HaveNameStartingWith(prefix)이름 접두사
.Should().HaveNameEndingWith(suffix)이름 접미사
.Should().HaveNameContaining(fragment)이름 포함
코드설명
.Should().NotDependOnAnyTypesThat().ResideInNamespace(ns)네임스페이스 의존 금지
.Should().OnlyDependOnTypesThat().ResideInNamespace(ns)허용 네임스페이스만
.Should().NotHaveDependencyOtherThan(ns)지정 네임스페이스 외 의존 금지
코드설명
.Should().ImplementInterface(typeof(I))인터페이스 구현 필수
.Should().BeAssignableTo(typeof(T))타입 할당 가능 필수
// ArchUnitNET 기본 방식
rule.Check(Architecture);
// Functorium 확장 방식
ArchRuleDefinition.Classes()
.That()
.ResideInNamespace(ns)
.ValidateAllClasses(Architecture, @class => @class
.RequirePublic()
.RequireSealed(),
verbose: true)
.ThrowIfAnyFailures("Rule Name");
using static ArchUnitNET.Fluent.ArchRuleDefinition;
// 도메인 → 애플리케이션 의존 금지
[Fact]
public void DomainLayer_ShouldNotDependOn_ApplicationLayer()
{
Types().That().ResideInNamespace(DomainNamespace)
.Should().NotDependOnAnyTypesThat()
.ResideInNamespace(ApplicationNamespace)
.Check(Architecture);
}
// 도메인 → 인프라 의존 금지
[Fact]
public void DomainLayer_ShouldNotDependOn_InfrastructureLayer()
{
Types().That().ResideInNamespace(DomainNamespace)
.Should().NotDependOnAnyTypesThat()
.ResideInNamespace(InfrastructureNamespace)
.Check(Architecture);
}
ArchRuleDefinition.Classes()
.That()
.ResideInNamespace(DomainNamespace)
.And().AreAssignableTo(typeof(Entity<>))
.And().AreNotAbstract()
ArchRuleDefinition.Interfaces()
.That()
.ResideInNamespace(PortNamespace)
.And().HaveNameStartingWith("I")
ArchRuleDefinition.Classes()
.That()
.ResideInNamespace(DomainNamespace)
.And().DoNotResideInNamespace(DomainNamespace + ".Ports")

아키텍처 테스트 도입 시 자주 등장하는 질문과 트러블슈팅 가이드를 정리합니다.

부록 C: FAQ