Dreamine.Core Ver.1.0.7
Loading...
Searching...
No Matches
DMContainer.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Reflection;
5
7{
12 public static partial class DMContainer
13 {
14 private static readonly Dictionary<Type, Func<object>> _map = new();
15 private static readonly Dictionary<Type, object> _singletonCache = new();
16
22 public static void Register<T>(Func<T> factory) where T : class
23 => _map[typeof(T)] = () => factory();
24
30 public static void RegisterSingleton<T>(T instance) where T : class
31 => _map[typeof(T)] = () => instance;
32
39 public static T Resolve<T>() where T : class
40 {
41 if (_map.TryGetValue(typeof(T), out var factory))
42 return (T)factory();
43 throw new InvalidOperationException($"[{typeof(T).Name}] 등록되지 않음.");
44 }
45
52 public static object Resolve(Type type)
53 {
54 if (_map.TryGetValue(type, out var factory))
55 return factory();
56
57 // Fallback: 자동 생성 시도 (등록 안됐지만 생성 가능한 경우)
58 if (!type.IsAbstract && type.IsClass)
59 {
60 var ctor = type.GetConstructors()
61 .OrderByDescending(c => c.GetParameters().Length)
62 .FirstOrDefault();
63
64 if (ctor != null)
65 {
66 var args = ctor.GetParameters()
67 .Select(p => Resolve(p.ParameterType))
68 .ToArray();
69 var instance = Activator.CreateInstance(type, args)!;
70
71 // 선택: 한번 생성되면 캐시할 수도 있음
72 _map[type] = () => instance;
73
74 return instance;
75 }
76 }
77
78 throw new InvalidOperationException($"[{type.FullName}] 등록되지 않았고, 생성도 불가능합니다.");
79 }
80
81
87 public static void AutoRegisterAll(Assembly rootAssembly)
88 {
89 var assemblies = AppDomain.CurrentDomain.GetAssemblies()
90 .Where(a => !a.IsDynamic && !string.IsNullOrEmpty(a.FullName))
91 .Prepend(rootAssembly) // 우선 대상 Assembly 먼저
92 .Distinct();
93
94 foreach (var assembly in assemblies)
95 {
96 foreach (var type in SafeGetTypes(assembly))
97 {
98 if (!type.IsClass || type.IsAbstract || type.IsGenericType)
99 continue;
100
101 var name = type.Name;
102
103 // DreamineApp + SampleTest 구조 모두 대응
104 bool isTarget =
105 name.EndsWith("Model") ||
106 name.EndsWith("Event") ||
107 name.EndsWith("Manager") ||
108 name.EndsWith("ViewModel") ||
109 name.Contains(".xaml.ViewModel") ||
110 name.Contains(".xaml.Model") ||
111 name.Contains(".xaml.Event") ;
112
113 if (!isTarget)
114 continue;
115
116 if (_map.ContainsKey(type))
117 continue;
118
119 // 생성자 우선 등록
120 var ctor = type.GetConstructors()
121 .OrderByDescending(c => c.GetParameters().Length)
122 .FirstOrDefault();
123
124 if (ctor == null)
125 {
126 // 매개변수 없는 생성자라도 등록 시도
127 if (type.GetConstructor(Type.EmptyTypes) != null)
128 {
129 _map[type] = () => Activator.CreateInstance(type)!;
130 }
131 continue;
132 }
133
134 _map[type] = () =>
135 {
136 if (_singletonCache.TryGetValue(type, out var cached))
137 return cached;
138
139 var args = ctor.GetParameters()
140 .Select(p => Resolve(p.ParameterType))
141 .ToArray();
142 var instance = Activator.CreateInstance(type, args)!;
143
144 _singletonCache[type] = instance; // ✅ 진짜 Type 키로 캐싱
145 return instance;
146 };
147 }
148 }
149 }
150
156 private static IEnumerable<Type> SafeGetTypes(Assembly assembly)
157 {
158 try
159 {
160 return assembly.GetTypes();
161 }
162 catch (ReflectionTypeLoadException ex)
163 {
164 return ex.Types.Where(t => t != null)!;
165 }
166 }
167 }
168}
📦 Dreamine 전용 DI 컨테이너 클래스입니다. 타입별 팩토리 등록, 싱글턴 등록, 자동 등록, 생성자 기반 DI 등을 지원합니다.
static void RegisterSingleton< T >(T instance)
주어진 싱글턴 인스턴스를 타입 T로 등록합니다.
static readonly Dictionary< Type, object > _singletonCache
static readonly Dictionary< Type, Func< object > > _map
static void AutoRegisterAll(Assembly rootAssembly)
주어진 어셈블리 및 현재 AppDomain 내 어셈블리에서 Model, Event, Manager, ViewModel, View 타입들을 자동 등록합니다.
static T Resolve< T >()
타입 T의 인스턴스를 Resolve합니다. 등록된 팩토리를 통해 생성하며, 없을 경우 예외를 발생시킵니다.
static void Register< T >(Func< T > factory)
주어진 타입 T에 대한 팩토리 함수를 등록합니다.
static IEnumerable< Type > SafeGetTypes(Assembly assembly)
어셈블리 로드 오류 발생 시에도 가능한 타입을 반환하는 안전한 GetTypes
static object Resolve(Type type)
주어진 타입 인스턴스를 Resolve합니다. 등록되지 않은 경우 생성자 기반 자동 생성도 시도합니다.