using Serein.Library.Api; using Serein.Library.Attributes; using System.Collections.Concurrent; using System.Reflection; namespace Serein.Library.Core.IOC { public class SereinIoc : ISereinIoc { private readonly ConcurrentDictionary _dependencies; private readonly ConcurrentDictionary _typeMappings; private readonly List _waitingForInstantiation; public SereinIoc() { _dependencies = new ConcurrentDictionary { [typeof(ISereinIoc).FullName] = this }; _typeMappings = new ConcurrentDictionary(); _waitingForInstantiation = []; } public object GetOrCreateServiceInstance(Type type, params object[] parameters) { Register(type); object instance; if (_dependencies.ContainsKey(type.FullName)) { instance = _dependencies[type.FullName]; } else { instance = Activator.CreateInstance(type); _dependencies[type.FullName] = instance; } return instance; } public T CreateServiceInstance(params object[] parameters) { return (T)GetOrCreateServiceInstance(typeof(T), parameters); } public ISereinIoc Reset() { foreach(var instancei in _dependencies.Values) { if (typeof(IDisposable).IsAssignableFrom(instancei.GetType()) && instancei is IDisposable disposable) { disposable.Dispose(); } } _dependencies.Clear(); _waitingForInstantiation.Clear(); //_typeMappings.Clear(); return this; } public ISereinIoc Register(Type type, params object[] parameters) { if (!_typeMappings.ContainsKey(type.FullName)) { _typeMappings[type.FullName] = type; } return this; } public ISereinIoc Register(params object[] parameters) { Register(typeof(T), parameters); return this; } public ISereinIoc Register(params object[] parameters) where TImplementation : TService { _typeMappings[typeof(TService).FullName!] = typeof(TImplementation); return this; } public object GetOrInstantiate(Type type) { if (!_dependencies.TryGetValue(type.FullName, out object value)) { Register(type); value = Instantiate(type); InjectDependencies(type); } return value; } public T GetOrInstantiate() { if(!_dependencies.TryGetValue(typeof(T).FullName, out object value)) { Register(); value = Instantiate(typeof(T)); } return (T)value; //throw new InvalidOperationException("目标类型未创建实例"); } public ISereinIoc Build() { foreach (var type in _typeMappings.Values) { if(!_dependencies.ContainsKey(type.FullName)) { _dependencies[type.FullName] = Activator.CreateInstance(type); } } foreach (var instance in _dependencies.Values) { InjectDependencies(instance); // 替换占位符 } //var instance = Instantiate(item.Value); TryInstantiateWaitingDependencies(); return this; } public object? Instantiate(Type controllerType, params object[] parameters) { var instance = Activator.CreateInstance(controllerType, parameters); if(instance != null) { InjectDependencies(instance); } return instance; } private void InjectDependencies(object instance) { var properties = instance.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(p => p.CanWrite && p.GetCustomAttribute() != null); foreach (var property in properties) { var propertyType = property.PropertyType; if (_dependencies.TryGetValue(propertyType.FullName, out var dependencyInstance)) { property.SetValue(instance, dependencyInstance); } } } private void TryInstantiateWaitingDependencies() { foreach (var waitingType in _waitingForInstantiation.ToList()) { if (_typeMappings.TryGetValue(waitingType.FullName!, out var implementationType)) { var instance = Instantiate(implementationType); if (instance != null) { _dependencies[waitingType.FullName] = instance; _waitingForInstantiation.Remove(waitingType); } } } } #region run() public ISereinIoc Run(Action action) { var service = GetOrInstantiate(); if (service != null) { action(service); } return this; } public ISereinIoc Run(Action action) { var service1 = GetOrInstantiate(); var service2 = GetOrInstantiate(); action(service1, service2); return this; } public ISereinIoc Run(Action action) { var service1 = GetOrInstantiate(); var service2 = GetOrInstantiate(); var service3 = GetOrInstantiate(); action(service1, service2, service3); return this; } public ISereinIoc Run(Action action) { var service1 = GetOrInstantiate(); var service2 = GetOrInstantiate(); var service3 = GetOrInstantiate(); var service4 = GetOrInstantiate(); action(service1, service2, service3, service4); return this; } public ISereinIoc Run(Action action) { var service1 = GetOrInstantiate(); var service2 = GetOrInstantiate(); var service3 = GetOrInstantiate(); var service4 = GetOrInstantiate(); var service5 = GetOrInstantiate(); action(service1, service2, service3, service4, service5); return this; } public ISereinIoc Run(Action action) { var service1 = GetOrInstantiate(); var service2 = GetOrInstantiate(); var service3 = GetOrInstantiate(); var service4 = GetOrInstantiate(); var service5 = GetOrInstantiate(); var service6 = GetOrInstantiate(); action(service1, service2, service3, service4, service5, service6); return this; } public ISereinIoc Run(Action action) { var service1 = GetOrInstantiate(); var service2 = GetOrInstantiate(); var service3 = GetOrInstantiate(); var service4 = GetOrInstantiate(); var service5 = GetOrInstantiate(); var service6 = GetOrInstantiate(); var service7 = GetOrInstantiate(); action(service1, service2, service3, service4, service5, service6, service7); return this; } public ISereinIoc Run(Action action) { var service1 = GetOrInstantiate(); var service2 = GetOrInstantiate(); var service3 = GetOrInstantiate(); var service4 = GetOrInstantiate(); var service5 = GetOrInstantiate(); var service6 = GetOrInstantiate(); var service7 = GetOrInstantiate(); var service8 = GetOrInstantiate(); action(service1, service2, service3, service4, service5, service6, service7, service8); return this; } #endregion } /* public interface IServiceContainer { ServiceContainer Register(params object[] parameters); ServiceContainer Register(params object[] parameters) where TImplementation : TService; TService Resolve(); void Get(Action action); object Instantiate(Type type, params object[] parameters); } public class ServiceContainer : IServiceContainer { private readonly Dictionary _dependencies; public ServiceContainer() { _dependencies = new Dictionary { [typeof(IServiceContainer)] = this }; } public void Get(Action action) { var service = Resolve(); action(service); } public ServiceContainer Register(params object[] parameters) { var instance = Instantiate(typeof(T), parameters); _dependencies[typeof(T)] = instance; return this; } public ServiceContainer Register(params object[] parameters) where TImplementation : TService { _dependencies[typeof(TService)] = Instantiate(typeof(TImplementation), parameters); return this; } public TService Resolve() { return (TService)_dependencies[typeof(TService)]; } public object Instantiate(Type controllerType, params object[] parameters) { var constructors = controllerType.GetConstructors(); // 获取控制器的所有构造函数 // 查找具有最多参数的构造函数 var constructor = constructors.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault(); if (constructor != null) { if (parameters.Length > 0) { return Activator.CreateInstance(controllerType, parameters); } else { var tmpParameters = constructor.GetParameters(); var dependencyInstances = new List(); foreach (var parameter in tmpParameters) { var parameterType = parameter.ParameterType; _dependencies.TryGetValue(parameterType, out var dependencyInstance); dependencyInstances.Add(dependencyInstance); if (dependencyInstance == null) { return null; } } // 用解析的依赖项实例化目标类型 return Activator.CreateInstance(controllerType, dependencyInstances.ToArray()); } } else { return Activator.CreateInstance(controllerType); } } }*/ }