Unity DI(Dependency Injection) 에 관한 생각...

Yumin·2025년 2월 3일

Unity

목록 보기
4/17

요즘 유니티 DI(Dependency Injection)에 많은 생각이 있습니다.

의존성 주입이란 게 Spring에서는 Spring Framework가 알아서 잘 해주는데
유니티는 Inspector에서 주입을 해주거나 해야 하기 때문에..

그래서 이전까지의 프로젝트에서는 싱글톤과 MVP 패턴을 이용했습니다만
새로운 프로젝트에선 MVP 패턴과 서비스 로케이터 패턴을 이용하고 있습니다.

using System;
using System.Collections.Generic;

public static class ServiceLocator
{
    public static IDictionary<Type, object> Services { get => _services; }
    private static Dictionary<Type, object> _services = new();
    
    // 서비스 등록
    public static void Register<T>(T service)
    {
        if (!_services.ContainsKey(typeof(T)))
        {
            _services[typeof(T)] = service;
        }
        else
        {
            throw new InvalidOperationException($"Service of type {typeof(T)} is already registered.");
        }
    }

    // 서비스 가져오기
    public static T Get<T>()
    {
        if (_services.TryGetValue(typeof(T), out var service))
        {
            return (T)service;
        }
        else
        {
            throw new KeyNotFoundException($"Service of type {typeof(T)} is not registered.");
        }
    }
    
    // 서비스 제거
    public static void UnRegister<T>()
    {
        if (_services.ContainsKey(typeof(T)))
        {
            _services.Remove(typeof(T));
        }
        else
        {
            throw new KeyNotFoundException($"Service of type {typeof(T)} is not registered.");
        }
    }
}

물론 서비스 로케이터패턴도 남발하면 전역 종속성이 강해져서 테스트가 어려워지는 단점과 블랙박스화가 발생한다는 문제가 있습니다.

물론 해결 방법도 있습니다.

인터페이스 분리: 서비스 로케이터에 의존하는 대신, 각 서비스가 제공하는 인터페이스를 별도로 정의하고, 이를 사용하도록 변경하면 종속성을 명확하게 관리가능. 이를 통해 서비스 로케이터의 직접적인 의존을 줄일 수 있음.

블랙박스화도 마찬가지로 로깅을 하면 되긴 하지만 코드의 효율성이 무엇일까에 관한 많은 생각이 드는 요즘입니다..

Zenject ( Extenject ) , VContainer , Etc..를 사용하면 어떨까?

외부 DI Framework를 사용하는 방법도 있겠습니다만
고려를 안 해본 건 아닙니다. 물론 이 또한 장단점이 있을 거고 채용하지 않은 이유는

Zenject의 경우 업데이트 미지원, VContainer는 새롭게 적용하는데 시간이 걸림

개인 프로젝트에서는 이용하지 않기로 결정했습니다.
그래서 서비스 로케이터 패턴에서 다음과 같은 내용을 생각해 개발을 해보기로 했습니다.

동적 서비스 등록 및 해제 기능 추가 (Register(), Unregister())
인터페이스 기반으로 관리하여 유연성 확보 (IAudioService 등)
씬 별 서비스 관리 (Lazy Loading & Cleanup)
Lazy Initialization 적용하여 필요할 때만 인스턴스 생성

요즘 .net core랑 ef core를 공부하고 있습니다.
요즘 개발 공부가 너무 재밌네요.

profile
일본 게임회사에서 클라이언트 엔지니어로 활동중

0개의 댓글