11. IServiceProvider - Ioc(제어 반전)

1. 출처 및 참고자료
더보기
✔️ Microsoft Docs: MVVM Toolkit IoC


관련 네임스페이스:
using CommunityToolkit.Mvvm.DependencyInjection;
학습 목표
- IoC를 사용한 구조와 사용하지 않은 구조를 단계별 비교한다.
- Service, ViewModel, App.xaml.cs, MainWindow.xaml을 모두 작성한다.
- 최종적으로 WPF MVVM 프로젝트에서 IoC가 왜 중요한지 체험한다.
2. 기능명: Ioc.Default, IServiceProvider
더보기
✔️ Inversion of Control (제어의 역전)란?
- 객체의 생성과 관계 설정을 개발자가 직접 하지 않고, IoC 컨테이너가 대신 처리함
- IoC를 통해, 객체 생성을 프레임워크에 위임하여 의존성을 제거
- MVVM에서의 적용: ViewModel에서 Service를 직접 생성하지 않고, 생성자 주입(Dependency Injection)을 통해 주입받음
✔️ 작동 방식
- MVVM Toolkit은 내부적으로 간단한 IoC 컨테이너를 제공합니다.
- Ioc.Default.ConfigureServices(...) 메서드를 통해 서비스 및 ViewModel을 등록합니다.
- 등록된 인스턴스는 **Ioc.Default.GetService<T>() 또는 Ioc.Default.GetRequiredService<T>()로 가져옵니다.
- App.xaml.cs의 Startup 시점에 등록하고, 전역에서 주입받을 수 있습니다.
✔️ 왜 필요한가?
MVVM 구조에서 ViewModel 간 또는 ViewModel → Service 간의 의존성 관계가 생기기 마련입니다. 이를 생성자에서 직접 생성하면 유지보수와 테스트가 어려워지므로 IoC 컨테이너를 통해 객체 생성 및 생명주기 관리를 분리합니다.
🟢 장점
- 의존성 분리 → 테스트 용이
- 싱글턴/스코프/트랜지언트 객체 제어 가능
- 생성자 주입 및 속성 주입 모두 지원
- 경량이며 설정이 간편함
🔴 단점
- Microsoft.Extensions.DependencyInjection 보다 기능이 제한적
- DI 패턴에 익숙하지 않으면 초기 이해가 어려움
3. 예제1 - IoC 미사용
더보기





✔️ 동작 시나리오
- IMessageService는 메시지를 반환하는 인터페이스
- 버튼 클릭 시, 메시지 박스에 “IoC를 사용한 메시지입니다” 출력
- (참고) 이 예는 IoC 없이 ViewModel 내부에서 서비스 객체를 직접 생성하는 방식을 설명하며,
강한 결합의 단점과 테스트 어려움을 학습자가 명확히 이해할 수 있도록 구성되었습니다.
📁 프로젝트 구조
IocDemo/ ├── Services/ │ └── IMessageService.cs │ └── MessageService.cs ├── ViewModels/ │ └── MainViewModel.cs ├── App.xaml.cs ├── MainWindow.xaml └── MainWindow.xaml.cs
✔️ 서비스 만들기

public interface IMessageService { string GetMessage(); }

public class MessageService : IMessageService { public string GetMessage() { return "IoC 없이 직접 생성된 메시지입니다."; } }
✔️ ViewModel 클래스 만들기 (MainViewModel.cs)

public partial class MainViewModel { private IMessageService _messageService; public MainViewModel() { // 직접 인스턴스 생성 → 강한 결합 (테스트 및 변경시 아래 코드를 직접 수정해야 함) _messageService = new MessageService(); } [RelayCommand] private void ShowMessage() { MessageBox.Show(_messageService.GetMessage()); } }
✔️ MainWindow 구성

public MainWindow() { InitializeComponent(); DataContext = new MainViewModel(); // ❌ ViewModel도 직접 생성 }

Title="IoC 데모" Height="200" Width="300"> <StackPanel Margin="20"> <Button Content="메시지 보기" Command="{Binding ShowMessageCommand}" /> </StackPanel>
✔️ 결과
- 항목
✔️ 소스코드
- 아래 IoC 사용 소스코드 파일 사용
4. 예제2 - IoC 적용
더보기






✔️ 동작 시나리오
- IMessageService는 메시지를 반환하는 인터페이스
- 버튼 클릭 시, 메시지 박스에 “IoC를 사용한 메시지입니다” 출력
- (참고) 이 예제는, 위 IoC 없이 ViewModel 내부에서 서비스 객체를 직접 생성하는 방식과 비교를 목적으로 합니다.
✔️ 패키지 설치
Install-Package CommunityToolkit.Mvvm Install-Package Microsoft.Extensions.DependencyInjection
📁 프로젝트 구조
IocDemo/ ├── Services/ │ └── IMessageService.cs │ └── MessageService.cs ├── ViewModels/ │ └── MainViewModel.cs ├── App.xaml.cs ├── MainWindow.xaml └── MainWindow.xaml.cs
✔️ 서비스 만들기

public interface IMessageService { string GetMessage(); }

public class MessageService : IMessageService { public string GetMessage() { return "IoC를 통해 생성된 메시지입니다."; } }
✔️ ViewModel 클래스 만들기 (MainViewModel.cs)

public partial class MainViewModel : ObservableObject { private readonly IMessageService _messageService; public MainViewModel(IMessageService messageService) { _messageService = messageService; } [RelayCommand] private void ShowMessage() { MessageBox.Show(_messageService.GetMessage()); } }
✔️ MainWindow 구성

public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // ViewModel 주입 DataContext = Ioc.Default.GetRequiredService<MainViewModel>(); } }

Title="IoC 데모" Height="200" Width="300"> <StackPanel Margin="20"> <Button Content="메시지 보기" Command="{Binding ShowMessageCommand}" /> </StackPanel>
✔️ App.xaml.cs 구성

// App.xaml.cs // 이 파일은 WPF 애플리케이션의 진입점으로, 애플리케이션이 시작될 때 IoC 설정을 초기화합니다. // CommunityToolkit.Mvvm 패키지의 Ioc.Default를 활용하여 의존성 주입(DI)을 구성합니다. using CommunityToolkit.Mvvm.DependencyInjection; // MVVM Toolkit에서 제공하는 IoC 컨테이너 using Microsoft.Extensions.DependencyInjection; // 서비스 등록을 위한 .NET 확장 메서드 제공 public partial class App : Application { // 애플리케이션이 시작될 때 호출되는 메서드 protected override void OnStartup(StartupEventArgs e) { // IoC 컨테이너 구성 (의존성 주입 설정) // ServiceCollection은 DI를 위한 서비스들을 등록하는 컨테이너입니다. Ioc.Default.ConfigureServices( new ServiceCollection() // 서비스 등록: IMessageService를 요청하면 MessageService 인스턴스를 반환 .AddSingleton<IMessageService, MessageService>() // 뷰모델 등록: MainViewModel도 싱글턴으로 등록하여 어디서든 공유 가능 .AddSingleton<MainViewModel>() // 등록된 서비스들을 기반으로 ServiceProvider 인스턴스를 구성 .BuildServiceProvider() ); // 반드시 base.OnStartup을 호출하여 WPF 애플리케이션이 정상적으로 시작되도록 함 base.OnStartup(e); } }
✔️ 결과
- 항목
✔️ 소스코드
WPF_ToolKit11.zip
0.09MB
댓글을 사용할 수 없습니다.