subindev 개발 블로그

[MAUI] 3. MAUI 의존성 주입(DI) 본문

.NET/MAUI

[MAUI] 3. MAUI 의존성 주입(DI)

subindev 2026. 4. 1. 10:04

3. MAUI 의존성 주입(DI)


1. 의존성 주입(DI)

1.1 의존성(Dependency)이란?

클래스 A가 클래스 B의 객체를 생성하거나 사용한다면, A는 B에 의존한다고 한다. 이건 자연스러운 구조지만, A가 B를 직접 new로 생성하는 순간 강한 결합(Tight Coupling)이 생긴다. 예를 들어 데이터베이스에 접근하는 ProductService가 MySqlRepository를 직접 생성하고 있다면, 나중에 SqlServerRepository로 바꿀 때 ProductService 코드까지 수정해야 하는 상황이 생긴다.

// 강한 결합의 예시
public class ProductService
{
    // ProductService가 MySqlRepository에 의존하고 직접 생성함
    private readonly MySqlRepository _repository = new MySqlRepository();

    public void GetProducts()
    {
        _repository.GetProducts();
    }
}

1.2 의존성 주입(DI)의 원리

DI의 핵심은 제어의 역전(Inversion of Control)이다. 객체가 자신의 의존성을 직접 만드는 대신, 외부에서 주입받는 구조로 바뀌는 것을 의미한다. 이렇게 구조를 바꾸면 결합도를 낮출 수 있고, 코드도 훨씬 유연하게 가져갈 수 있다.


1.2.1 생성자 주입 (Constructor Injection)

가장 많이 쓰고 권장되는 DI 방식이다. 의존성을 클래스의 생성자를 통해 전달받는다. 보통은 인터페이스를 사용해서 특정 구현체에 직접 의존하지 않도록 만드는 방식으로 같이 사용한다.


1.3 DI 컨테이너(DI Container)

DI 컨테이너는 의존성 주입을 자동으로 처리하고 관리해주는 도구라고 보면 된다. 개발자는 인터페이스와 구현체를 한 번 등록해두기만 하면, 컨테이너가 필요한 시점에 알아서 의존성을 해결해서 객체를 생성해준다. MAUI 프로젝트에서는 .NET에 기본으로 포함된 DI 컨테이너를 그대로 사용할 수 있다.

// MauiProgram.cs에서 의존성 등록
public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();

    // 서비스 등록
    builder.Services.AddSingleton<IProductRepository, MySqlRepository>();
    builder.Services.AddTransient<ProductService>();
    builder.Services.AddSingleton<MainPage>();

    // ViewModel 등록
    builder.Services.AddTransient<MainViewModel>();

    return builder.Build();
}

// Page에서 ViewModel 주입
public partial class MainPage : ContentPage
{
    public MainPage(MainViewModel viewModel)
    {
        InitializeComponent();
        this.BindingContext = viewModel;
    }
}