지금까지 IoC Container를 쓰기 시작한 뒤로 쭉 Microsoft.Extensions.DependencyInjection을 사용했습니다.
하지만 이것을 WPF나 Windows Forms 써보신 분들을 아실텐데 AddScoped()를 활용하기가 힘듭니다. 이것은 애초에 Microsoft.Extensions.DependencyInjection가 aspnetcore를 염두하고 만들어졌기 때문이라고 알고 있습니다.
aspnetcore에서 AddScoped를 사용하면 web session 단위로 인스턴스를 관리할 수 있고, 그냥 쓰게 된다면 아래처럼 Scope를 잡아서 쓰게 될 것입니다.
using (IServiceScope scope = serviceProvider.CreateScope()) {
var singletonService = scope.ServiceProvider.GetService<SingletonOperation>();
var scopedService = scope.ServiceProvider.GetService<ScopedOperation>();
var transientService = scope.ServiceProvider.GetService<TransientOperation>();
}
AutoFac은 사실상 .NET에서 Microsoft.Extensions.DependencyInjection과 비빌 수 있는 가장 거대한 IoC Container라 믿음직스럽고 최근까지도 업데이트가 활발하게 이뤄지고 있습니다.
그 밖에는 DryIoC 는 Prism에서 주로 쓰는 것으로 알고 있고, Simple Injector는 DevExpress에서 Sample Project를 제공받을 때 주로 적용되어 알게 되었고, Ninject는 몇년 전에 반짝 떴던 것 같은데 지금은 업데이트가 안되는 듯하고, Splat은 ReactiveUI 전용이라 RxUI를 안쓰면 적용하기 어려울 것 같습니다.
혹시 WPF에서 사용하기에 적합하고 추천할만한 IoC Container 가 있다면 추천부탁드리겠습니다.
웹앱은 기본적으로 요청이 들어와야 뭔가가 돌아가는 앱이라서, 의존성의 생명 주기를 요청 세션으로 한정하는 Scope가 의미가 있습니다.
즉, 요청 세션 동안에는 Singlton 인 것이죠.
그러나, 데스크탑 앱이나 프론트 앱은 세션 개념이 없어서, Scoped 생명 주기가 큰 의미가 없습니다.(제가 아는 한)
앱의 생명 주기(시작 ~ 종료) 동안 Singleton 이냐 Transient 냐의 구분만 중요하죠.
그리고, 아래 코드처럼, 임의의 Scope를 생성하는 것은 특별한 이유가 있지 않는 한 불필요한 복잡성입니다. 실제로, Scoped 로 등록되어 있지만 생명주기는 Transient 와 같(거나 짧)습니다. using 의 범위가 끝나면, Scope 도 사라지고, 생성된 모든 객체도 사라지기 때문입니다.
데스크톱 앱을 개발하면서 닷넷 플랫폼 확장(Microsoft.Extensions.DependencyInjection) 외의 IoC 컨테이너를 선택해본 적이 없었던 것 같습니다. Generic Host에 완벽히 통합되고, DI를 달성하기 위한 기본 기능 구현에 충실해 불필요한 러닝 커브도 없습니다.
닷넷 플랫폼 확장을 사용하면서 아쉬울 만한 부분이라면 기본 기능을 넘어선 고급 기능이 필요할 때일 텐데, 닷넷 플랫폼 확장은 확장이 용이하게 설계되어 있기 때문에 대체하지 않고 확장할 수 있는 라이브러리를 적용하면 됩니다. 대표적으로 Scrutor가 있습니다.
닷넷 플랫폼 확장에서 제공하는 DI를 사용하면서 한계가 느껴졌다면, 이러한 닷넷 플랫폼 확장의 확장을 사용해 보는 것도 좋을 것 같습니다.
10년 전에 NInejct를 DI용도로만 쓰는 형태로 진행했었습니다. WPF 였기 때문에 성능상의 큰 이점 및 문제는 보이지 않았습니다.
WPF의 개발 패턴에서는 수많은 객체들이 실시간으로 동적 호출되는 상황은 그렇게 많지 않기 때문에 아마도 성능상의 이점을 확인하시기 위해서는 WPF가 아닌 서버류로 확인 하셔야 할것입니다.
제가 질문드렸던 의도는 아쉽다기보단 거슬린다는 맥락이었습니다.
현재 WPF를 주업으로 삼고 있는 저에게 Microsoft.Extensions.DependencyInjection은 AddScoped를 쓰지 못하기에 없어도 되는 기능인 것이죠.
사실 베가본드님께서 좋은 경험공유를 해주셨다고 생각합니다. 하지만 자주있는 경우는 아니고 저는 아직 접한적이 없습니다. 그래서 차라리 AddScoped가 아닌 다른 Windows Desktop Application의 특징을 살린 라이프사이클 옵션이 추가로 존재할 수 있는 Ioc Container가 있으면 좋지 않을까 했던 것입니다.
Multi-Window나 Multi-Page 앱을 타겟팅해서 Scoped를 기반으로 Window나 Page에 한정된 수명 범위를 만들 수는 있을 것 같은데, 그러한 경우 DI 라이브러리 자체에서 해결하기 보다는 UI 프레임워크에 종속된 Window, Page 등의 컨트롤을 참조하거나 확장함으로써 이루어질 수밖에 없고, 그러다 보면 개발 방향성이 새로운 IoC 컨테이너 라이브러리가 아닌 UI 프레임워크의 DI 확장형 라이브러리로 향할 수밖에 없을 것 같다는 생각이 드네요.