2013-06-06 3 views
4

칼 쉬페 (Karl Shiffet)가 'InTheBox' WPF Training을 작성했으며 WPF 학습을위한 훌륭한 자료가되었습니다. 그것이 가져온 한 가지는 의존성 주입과 연합 컨테이너 (Unity Container)의 사용이었습니다. 종속성이 UnityContainer에 등록하고 MainWindowViewModel UnityContainer에 의해 분사되는왜 의존성 주입 컨테이너를 사용합니까?

public partial class App : Application { 

    protected override void OnStartup(StartupEventArgs e) { 

     IUnityContainer container = new UnityContainer(); 

     container.RegisterType<IDialogService, ModalDialogService>(
      new ContainerControlledLifetimeManager()); 

     container.RegisterType<IEventRepository, EventRepository>(
      new ContainerControlledLifetimeManager()); 

     MainWindow window = container.Resolve<MainWindow>(); 

     window.DataContext = container.Resolve<MainWindowViewModel>(); 

     window.Show(); 
    } 
} 

: 여기 날 일부 문제를 제기 코드 섹션이다. 내 질문은 왜 컨테이너를 사용하는 것입니까? 이유는 단지까지 의존성 주입에 관한 한 같은 일을 실현 다음 코드 조각을 사용하지 :

protected override void OnStartup(StartupEventArgs e) 
{ 
    IDialogService dialogService = new ModalDialogService(); 
    IEventRepository eventRepository = new EventRepository(); 

    MainWindow window = new MainWindow(); 
    window.DataContext = 
     new MainWindowViewModel(eventRepository, dialogService); 
    window.Show(); 
} 

나는이 경우 어떤 혜택을 볼 수 있도록 나는 아직도 합성 루트에서 생성자에 종속성을 주입하고 UnityContainer를 사용하는 방법.

분명히 이유가 있음을 감사하지만 누군가이 상황에서 추가 사항을 설명 할 수 있습니까? 또한, 이와 같은 용기의 사용이 참으로 까다로운 또 다른 상황이 있습니까?

답변

5

간단한 케이스에서 DI 컨테이너를 사용하면 실제로 많이 도움이되지 않습니다. 상황이 더 복잡해지면 종속성 변경의 효과를 최소화 할 때 더 이해하기 시작합니다.

예를 들어, 모든 종속성이 현재 사용하는 ILoggingService가 있다고 가정 해보십시오. Unity와 같은 DI 컨테이너를 사용할 때 한 줄의 코드 만 추가하면됩니다.

protected override void OnStartup(StartupEventArgs e) 
    { 
     IUnityContainer container = new UnityContainer(); 
     container.RegisterType<IDialogService, ModalDialogService>(); 
     container.RegisterType<IEventRepository, EventRepository>(); 
     container.RegisterType<ILoggingService, LoggingService>(); // added 

     MainWindow window = container.Resolve<MainWindow>(); 
     window.DataContext = container.Resolve<MainWindowViewModel>(); 
     window.Show(); 
    } 

직접 할 때는 한 줄의 코드를 추가하고 3 줄의 코드를 수정해야합니다.

등록 할 유형을 검색 할 수있는 고급 컨테이너를 사용하는 경우 구성 루트의 코드를 변경할 필요가 없을 수 있습니다. 다음은 AutoFac을 사용한 예입니다.

protected override void OnStartup(StartupEventArgs e) 
    { 
     var builder = new ContainerBuilder(); 
     var assembly = Assembly.GetExecutingAssembly(); 
     builder.RegisterAssemblyTypes(assembly) 
       .AsSelf() 
       .AsImplementedInterfaces(); 
     var container = builder.Build(); 

     MainWindow window = container.Resolve<MainWindow>(); 
     window.DataContext = container.Resolve<MainWindowViewModel>(); 
     window.Show(); 
    } 
+0

새로운 의존성을 도입 할 때 컨테이너가 코드 변경을 허용 할 수있는 방법을 보여주는 추가 예제를 보내 주셔서 감사합니다. –

2

당신은 좋은 지적입니다. 두 번째 예는 Mark Seemann이 '불쌍한 사람의 DI'라고 부르는 것을 사용합니다. 아직 DI이지만 자네가 직접하고있어.

IoC 컨테이너는 라이프 스타일 관리 및 협약에 의한 유형 등록과 같은 다양한 유형의 주입 및 관리 기능을 시작할 때 막대한 노동력 절약자가됩니다.

최소한의 의존성 관리로 작은 작업을 할 때, 제안한 것처럼 과도한 작업 일 수 있습니다.

자세한 내용은 Seemann의 책과 블로그를 참조하십시오. IMHO, 그는 누구보다 주제를 더 잘 설명합니다.

+0

시간을내어 주셔서 감사 드리며, 우리의 의존성 주입 방식을 확장 할 것을 고려할 때 Seemann의 책을 살펴 보겠습니다. –

+0

이 책을 권하고 싶습니다. 아직 끝내지는 않았지만 읽은 부분이 도움이되었습니다. –