Rx.NET 7.0이 해결하는 문제: 불필요한 의존성
Rx.NET은 .NET 생태계에서 비동기 이벤트 스트림 처리를 위한 대표적인 라이브러리다. 기존 System.Reactive 메인 패키지에는 WPF, Windows Forms, UWP, Windows Runtime과 같은 UI 플랫폼별 통합 코드가 모두 포함되어 있었다. 문제는 대부분의 백엔드 또는 콘솔 애플리케이션이 이러한 UI 관련 코드를 전혀 사용하지 않음에도 불구하고, self-contained 배포 방식을 선택할 경우 수십 MB에 달하는 불필요한 프레임워크 의존성이 배포 산출물에 함께 포함된다는 점이었다.
self-contained 배포는 런타임을 포함하여 대상 환경에 .NET이 설치되어 있지 않아도 실행 가능하게 해주는 장점이 있다. 하지만 그만큼 포함되는 파일 수와 용량이 크게 늘어나는 트레이드오프가 존재한다. 여기에 사용하지도 않는 UI 프레임워크 의존성까지 딸려오면, 컨테이너 이미지 크기 증가나 배포 속도 저하로 이어질 수 있다.
7.0의 핵심 변경: UI 통합 모듈 분리
Rx.NET 7.0은 이 문제를 패키지 구조 재편으로 해결했다. UI 플랫폼별 통합 코드를 System.Reactive 메인 패키지에서 분리하여 각각의 독립 패키지로 제공하는 방식으로 변경된 것이다. 이제 개발자는 실제로 필요한 플랫폼 통합 모듈만 선택적으로 참조할 수 있다.
<!-- 기존: 메인 패키지에 모든 UI 통합 코드 포함 -->
<PackageReference Include="System.Reactive" Version="6.x.x" />
<!-- 7.0 이후: 필요한 UI 통합 패키지만 선택적 추가 -->
<PackageReference Include="System.Reactive" Version="7.0.0" />
<PackageReference Include="System.Reactive.Windows.Forms" Version="7.0.0" />
백엔드 서비스나 콘솔 애플리케이션처럼 UI가 전혀 필요 없는 프로젝트라면 System.Reactive 패키지만 참조하는 것으로 충분하다. 결과적으로 배포 패키지는 실제 사용하는 의존성만 포함하는 린(lean) 구성이 가능해진다.
실무에서 왜 중요한가
이번 변경은 단순한 패키지 정리가 아니라 현대적인 배포 환경에 직접적인 영향을 미친다.
- 컨테이너 이미지 최적화: Docker 기반 배포에서 이미지 레이어 크기는 곧 빌드 시간, 레지스트리 전송 속도, 보안 스캔 범위와 직결된다. 불필요한 의존성 제거는 이 모든 측면을 개선한다.
- 트리밍(Trimming) 효과 극대화: .NET의 publish trimming 기능은 사용되지 않는 코드를 제거하지만, 참조 자체가 존재하면 일부 의존성은 제거되지 않을 수 있다. 패키지 수준에서 분리하면 트리밍 효과가 더욱 확실해진다.
- 명시적 의존성 관리: 필요한 것만 참조한다는 원칙은 프로젝트의 의존성 그래프를 명확하게 유지하고, 예상치 못한 간접 의존성으로 인한 취약점 노출 가능성을 낮춘다.
Java 생태계의 모듈 시스템(JPMS)이나 Quarkus의 extension 분리 철학과도 일맥상통하는 방향이다. 필요한 것만 포함하는 것이 현대 클라우드 네이티브 배포의 기본 원칙이다.
정리
- Rx.NET 7.0은 WPF, Windows Forms 등 UI 플랫폼 통합 코드를 메인 패키지에서 분리하여 별도 패키지로 제공한다.
- self-contained 배포 시 불필요한 수십 MB 의존성을 제거할 수 있어 컨테이너 이미지 최적화에 직접적인 효과가 있다.
- 필요한 의존성만 명시적으로 참조하는 린 배포 구성은 보안, 성능, 유지보수성 모든 면에서 유리하다.