Files
EnglewoodLAB/Assets/Sample/Injector/InjectorSamples.cs
2026-03-10 11:35:30 +09:00

291 lines
12 KiB
C#

using System;
using UnityEngine;
using UVC.Core;
namespace Sample
{
/*
* ============================================================================
* Injector 샘플 - 인터페이스 및 순수 C# 클래스
* ============================================================================
*
* 이 파일에는 MonoBehaviour가 아닌 인터페이스와 순수 C# 클래스가 정의되어 있습니다.
* MonoBehaviour를 상속받는 클래스들은 별도 파일로 분리되어 있습니다.
*
* [ 4가지 등록 타입 ]
* - Type A: 순수 C# 클래스 (new T()로 생성)
* - Type B: MonoBehaviour 동적 생성 (별도 파일: InjectorSampleAudioManager.cs 등)
* - Type C: Prefab 기반 MonoBehaviour (별도 파일: InjectorSampleUIManager.cs 등)
* - Type D: Singleton 연동 (별도 파일: InjectorSampleSettingsManager.cs 등)
*
* [ 3가지 라이프사이클 ]
* - App: 애플리케이션 전체 유지 (DontDestroyOnLoad)
* - Scene: 현재 씬에서만 유지 (씬 전환 시 해제)
* - Transient: 매번 새 인스턴스 생성
*
* ============================================================================
*/
#region ========== Type A: C# ==========
/// <summary>
/// 로깅 서비스 인터페이스 - 애플리케이션 전역 로깅 기능을 제공합니다.
/// </summary>
/// <remarks>
/// <para><b>구현체:</b> ConsoleLogger</para>
/// <para><b>등록:</b> Injector.Register<ILogService, ConsoleLogger>(ServiceLifetime.App)</para>
/// <para><b>사용:</b> [Inject] private ILogService _logger;</para>
/// </remarks>
public interface ILogService
{
/// <summary>일반 로그 메시지를 출력합니다.</summary>
void Log(string message);
/// <summary>경고 로그 메시지를 출력합니다.</summary>
void LogWarning(string message);
/// <summary>에러 로그 메시지를 출력합니다.</summary>
void LogError(string message);
}
/// <summary>
/// Type A 예시: 순수 C# 클래스 - Unity Debug.Log를 래핑한 콘솔 로거
/// </summary>
/// <remarks>
/// <para><b>타입:</b> Type A - 순수 C# 클래스</para>
/// <para><b>라이프사이클:</b> App (애플리케이션 전체 유지)</para>
/// <para><b>특징:</b></para>
/// <list type="bullet">
/// <item><description>MonoBehaviour가 아니므로 GameObject 없이 동작</description></item>
/// <item><description>new ConsoleLogger()로 생성됨</description></item>
/// <item><description>모든 로그에 [ConsoleLogger] 접두어 추가</description></item>
/// </list>
/// </remarks>
public class ConsoleLogger : ILogService
{
private readonly string _prefix = "[ConsoleLogger]";
public void Log(string message) => Debug.Log($"{_prefix} {message}");
public void LogWarning(string message) => Debug.LogWarning($"{_prefix} {message}");
public void LogError(string message) => Debug.LogError($"{_prefix} {message}");
}
/// <summary>
/// 씬 설정 인터페이스 - 현재 씬의 설정 정보를 제공합니다.
/// </summary>
/// <remarks>
/// <para><b>구현체:</b> SceneConfig</para>
/// <para><b>등록:</b> Injector.Register<ISceneConfig, SceneConfig>(ServiceLifetime.Scene)</para>
/// <para><b>또는 Factory:</b> Injector.RegisterFactory<ISceneConfig>(injector => new SceneConfig { ... })</para>
/// </remarks>
public interface ISceneConfig
{
/// <summary>현재 씬 이름</summary>
string SceneName { get; }
/// <summary>난이도 배율 (1.0 = 기본)</summary>
float Difficulty { get; }
}
/// <summary>
/// Type A 예시: 순수 C# 클래스 - 씬별 설정 정보
/// </summary>
/// <remarks>
/// <para><b>타입:</b> Type A - 순수 C# 클래스</para>
/// <para><b>라이프사이클:</b> Scene (씬 전환 시 해제) 또는 App (Factory 사용 시)</para>
/// <para><b>용도:</b> 씬별 난이도, 이름 등 설정 정보 관리</para>
/// </remarks>
public class SceneConfig : ISceneConfig
{
public string SceneName { get; set; } = "Default";
public float Difficulty { get; set; } = 1.0f;
}
/// <summary>
/// 게임 서비스 인터페이스 - 게임 초기화 및 저장 기능을 제공합니다.
/// </summary>
/// <remarks>
/// <para><b>구현체:</b> GameService</para>
/// <para><b>특징:</b> 다른 서비스(ILogService)에 대한 의존성을 가짐</para>
/// </remarks>
public interface IGameService
{
/// <summary>게임을 초기화합니다.</summary>
void Initialize();
/// <summary>게임을 저장합니다.</summary>
void SaveGame();
}
/// <summary>
/// Type A 예시: 순수 C# 클래스 - 다른 서비스에 대한 의존성 주입
/// </summary>
/// <remarks>
/// <para><b>타입:</b> Type A - 순수 C# 클래스</para>
/// <para><b>라이프사이클:</b> App</para>
/// <para><b>핵심 포인트:</b></para>
/// <list type="bullet">
/// <item><description>순수 C# 클래스도 [Inject] 어트리뷰트로 의존성 주입 가능</description></item>
/// <item><description>Injector가 인스턴스 생성 후 자동으로 ILogService를 주입</description></item>
/// <item><description>생성자 주입이 아닌 필드 주입 방식 사용</description></item>
/// </list>
/// </remarks>
/// <example>
/// <code>
/// // 등록
/// Injector.Register<IGameService, GameService>(ServiceLifetime.App);
///
/// // 사용
/// [Inject] private IGameService _gameService;
/// _gameService.Initialize();
/// </code>
/// </example>
public class GameService : IGameService
{
[Inject] private ILogService _logger;
public void Initialize() => _logger?.Log("GameService initialized");
public void SaveGame() => _logger?.Log("Game saved!");
}
#endregion
#region ========== Type B: MonoBehaviour ==========
/// <summary>
/// 오디오 매니저 인터페이스 - BGM/SFX 재생 기능을 제공합니다.
/// </summary>
/// <remarks>
/// <para><b>구현체:</b> InjectorSampleAudioManager (별도 파일)</para>
/// <para><b>타입:</b> Type B - MonoBehaviour 동적 생성</para>
/// <para><b>등록:</b> Injector.Register<IAudioManager, InjectorSampleAudioManager>(ServiceLifetime.App)</para>
/// <para><b>특징:</b> 런타임에 새 GameObject가 생성되고 AudioSource 등 Unity 컴포넌트 활용 가능</para>
/// </remarks>
public interface IAudioManager
{
/// <summary>효과음을 재생합니다.</summary>
void PlaySFX(string clipName);
/// <summary>배경음악을 재생합니다.</summary>
void PlayBGM(string clipName);
/// <summary>모든 오디오를 중지합니다.</summary>
void StopAll();
}
/// <summary>
/// 적 스포너 인터페이스 - 적 오브젝트 생성 기능을 제공합니다.
/// </summary>
/// <remarks>
/// <para><b>구현체:</b> InjectorSampleEnemySpawner (별도 파일)</para>
/// <para><b>타입:</b> Type B - MonoBehaviour 동적 생성</para>
/// <para><b>등록:</b> Injector.Register<IEnemySpawner, InjectorSampleEnemySpawner>(ServiceLifetime.Scene)</para>
/// <para><b>라이프사이클:</b> Scene - 씬 전환 시 적 스포너와 생성된 적들이 함께 정리됨</para>
/// </remarks>
public interface IEnemySpawner
{
/// <summary>지정된 위치에 적을 스폰합니다.</summary>
void SpawnEnemy(Vector3 position);
/// <summary>현재 활성화된 적의 수</summary>
int EnemyCount { get; }
}
#endregion
#region ========== Type C: Prefab ==========
/// <summary>
/// UI 매니저 인터페이스 - 팝업 및 로딩 UI 기능을 제공합니다.
/// </summary>
/// <remarks>
/// <para><b>구현체:</b> InjectorSampleUIManager (별도 파일)</para>
/// <para><b>타입:</b> Type C - Prefab 기반 MonoBehaviour</para>
/// <para><b>등록:</b> Injector.RegisterPrefab<IUIManager>(uiManagerPrefab, ServiceLifetime.App)</para>
/// <para><b>특징:</b></para>
/// <list type="bullet">
/// <item><description>프리팹에 미리 설정된 UI 요소들이 유지됨</description></item>
/// <item><description>Inspector에서 시각적으로 UI 구성 가능</description></item>
/// <item><description>Canvas, Button, Text 등 Unity UI 컴포넌트 활용</description></item>
/// </list>
/// </remarks>
public interface IUIManager
{
/// <summary>팝업을 표시합니다.</summary>
void ShowPopup(string title, string message);
/// <summary>팝업을 숨깁니다.</summary>
void HidePopup();
/// <summary>로딩 UI를 표시합니다.</summary>
void ShowLoading();
/// <summary>로딩 UI를 숨깁니다.</summary>
void HideLoading();
}
/// <summary>
/// 씬 UI 인터페이스 - 씬별 HUD 기능을 제공합니다.
/// </summary>
/// <remarks>
/// <para><b>구현체:</b> InjectorSampleSceneUI (별도 파일)</para>
/// <para><b>타입:</b> Type C - Prefab 기반 MonoBehaviour</para>
/// <para><b>등록:</b> Injector.RegisterPrefab<ISceneUI>(sceneUIPrefab, ServiceLifetime.Scene)</para>
/// <para><b>라이프사이클:</b> Scene - 씬 전환 시 UI가 함께 정리됨</para>
/// </remarks>
public interface ISceneUI
{
/// <summary>씬 UI를 초기화합니다.</summary>
void Initialize();
/// <summary>HUD를 표시합니다.</summary>
void ShowHUD();
/// <summary>HUD를 숨깁니다.</summary>
void HideHUD();
}
#endregion
#region ========== Transient ==========
/// <summary>
/// 요청 핸들러 인터페이스 - 개별 요청 처리 기능을 제공합니다.
/// </summary>
/// <remarks>
/// <para><b>구현체:</b> RequestHandler</para>
/// <para><b>라이프사이클:</b> Transient - 매번 새 인스턴스 생성</para>
/// <para><b>용도:</b> HTTP 요청, 이벤트 처리 등 상태를 공유하지 않아야 하는 경우</para>
/// </remarks>
public interface IRequestHandler
{
/// <summary>고유 요청 ID</summary>
string RequestId { get; }
/// <summary>데이터를 처리합니다.</summary>
void Process(string data);
}
/// <summary>
/// Transient 라이프사이클 예시: 매번 새 인스턴스가 생성되는 클래스
/// </summary>
/// <remarks>
/// <para><b>라이프사이클:</b> Transient</para>
/// <para><b>특징:</b></para>
/// <list type="bullet">
/// <item><description>Resolve 호출 시마다 새 인스턴스 생성</description></item>
/// <item><description>각 인스턴스는 고유한 RequestId를 가짐</description></item>
/// <item><description>상태를 공유하지 않아야 하는 경우에 적합</description></item>
/// </list>
/// </remarks>
/// <example>
/// <code>
/// // 등록
/// Injector.Register<IRequestHandler, RequestHandler>(ServiceLifetime.Transient);
///
/// // 사용 - 매번 다른 인스턴스
/// var handler1 = Injector.Resolve<IRequestHandler>(); // RequestId: "a1b2c3d4"
/// var handler2 = Injector.Resolve<IRequestHandler>(); // RequestId: "e5f6g7h8"
/// </code>
/// </example>
public class RequestHandler : IRequestHandler
{
[Inject] private ILogService _logger;
public string RequestId { get; } = Guid.NewGuid().ToString().Substring(0, 8);
public void Process(string data)
{
_logger?.Log($"[{RequestId}] Processing: {data}");
}
}
#endregion
}