본문 바로가기
C#/WPF

WPF와 WinForms에서 DI(Dependency Injection) 사용법

by jhwannabe 2025. 1. 22.

안녕하세요! 오늘은 WPF와 WinForms 애플리케이션에서 **DI(Dependency Injection)**를 효과적으로 활용하는 방법에 대해 이야기해볼게요. 😊


1. DI(Dependency Injection)란?

DI는 객체 간의 의존성을 주입하여 코드의 결합도를 낮추고 테스트 가능성과 유지보수성을 높이는 설계 패턴입니다.

(1) DI의 주요 장점

  • 유연성 향상: 코드 수정 없이 의존성 교체 가능
  • 테스트 용이성: Mock 객체를 사용한 단위 테스트 가능
  • 재사용성 증가: 모듈화된 코드 작성

(2) DI 컨테이너

DI를 효율적으로 구현하려면 컨테이너를 사용하는 것이 일반적입니다. 대표적인 DI 컨테이너로는 다음이 있습니다:

  • Microsoft.Extensions.DependencyInjection
  • Autofac
  • Unity

2. WinForms에서 DI 사용하기

WinForms 애플리케이션에서 DI를 사용하려면 프로그램 진입점에서 DI 컨테이너를 설정하고 각 폼에 의존성을 주입해야 합니다.

 

(1) DI 컨테이너 설정

var services = new ServiceCollection();
services.AddTransient<IMyService, MyService>();
services.AddSingleton<MainForm>();
var serviceProvider = services.BuildServiceProvider();

 

(2) 폼에 의존성 주입

[STAThread]
static void Main()
{
    var serviceProvider = ConfigureServices();
    Application.Run(serviceProvider.GetRequiredService<MainForm>());
}

private static ServiceProvider ConfigureServices()
{
    var services = new ServiceCollection();
    services.AddTransient<IMyService, MyService>();
    services.AddSingleton<MainForm>();
    return services.BuildServiceProvider();
}

 

(3) 의존성 주입된 폼 코드

public partial class MainForm : Form
{
    private readonly IMyService _myService;

    public MainForm(IMyService myService)
    {
        _myService = myService;
        InitializeComponent();
    }

    private void Button_Click(object sender, EventArgs e)
    {
        _myService.DoWork();
    }
}

3. WPF에서 DI 사용하기

WPF에서는 DI를 사용하기 위해 ViewModel과 DataContext를 연결하고 의존성을 주입합니다.

 

(1) DI 컨테이너 설정

var services = new ServiceCollection();
services.AddTransient<IMyService, MyService>();
services.AddSingleton<MainWindow>();
var serviceProvider = services.BuildServiceProvider();

 

(2) 앱 진입점에서 설정

public partial class App : Application
{
    private ServiceProvider _serviceProvider;

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        _serviceProvider = ConfigureServices();
        var mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
        mainWindow.Show();
    }

    private ServiceProvider ConfigureServices()
    {
        var services = new ServiceCollection();
        services.AddTransient<IMyService, MyService>();
        services.AddSingleton<MainWindow>();
        return services.BuildServiceProvider();
    }
}

 

(3) ViewModel에 의존성 주입

public class MainViewModel
{
    private readonly IMyService _myService;

    public MainViewModel(IMyService myService)
    {
        _myService = myService;
    }

    public void ExecuteCommand()
    {
        _myService.DoWork();
    }
}

 

(4) View와 ViewModel 연결

public partial class MainWindow : Window
{
    public MainWindow(MainViewModel viewModel)
    {
        InitializeComponent();
        DataContext = viewModel;
    }
}

4. DI 사용 시 주의할 점

  • 수명 주기 관리: Transient, Scoped, Singleton 등의 수명 주기를 적절히 설정하세요.
  • 지나친 의존성 주입 방지: 의존성이 너무 많아지면 복잡도가 증가할 수 있습니다.
  • DI 컨테이너 선택: 애플리케이션 규모와 요구사항에 맞는 DI 컨테이너를 선택하세요.

5. 결론

DI는 WPF와 WinForms 애플리케이션 모두에서 결합도를 낮추고 유지보수성을 높이는 데 큰 도움을 줍니다. 오늘 소개한 예제와 팁을 활용해 DI를 적용하고, 더욱 효율적이고 유연한 애플리케이션을 개발해보세요! 😊


728x90
반응형