using System; using System.Collections.Generic; namespace Assets._Project.Develop.Runtime.Infrastructure.DI { public class DIContainer { private readonly Dictionary _container = new(); private readonly List _requests = new(); private readonly DIContainer _parent; public DIContainer() { } public DIContainer(DIContainer parent) => _parent = parent; public IRegistrationOptions RegisterAsSingle(Func creator) { if (IsAlreadyRegister()) throw new InvalidOperationException($"{typeof(T)} already register"); Registration registration = new Registration(container => creator.Invoke(container)); _container.Add(typeof(T), registration); return registration; } public bool IsAlreadyRegister() { if (_container.ContainsKey(typeof(T))) return true; if (_parent != null) return _parent.IsAlreadyRegister(); return false; } public T Resolve() { if (_requests.Contains(typeof(T))) throw new InvalidOperationException($"Cycle resolve for {typeof(T)}"); _requests.Add(typeof(T)); try { if (_container.TryGetValue(typeof(T), out Registration registration)) return (T)registration.CreateInstanceFrom(this); if (_parent != null) return _parent.Resolve(); } finally { _requests.Remove(typeof(T)); } throw new InvalidOperationException($"Registration for {typeof(T)} not exists"); } public void Initialize() { foreach (Registration registration in _container.Values) { if (registration.IsNonLazy) registration.CreateInstanceFrom(this); registration.OnInitialize(); } } public void Dispose() { foreach (Registration registration in _container.Values) registration.OnDispose(); } } }