using Serein.Library.Api; using Serein.Library.Attributes; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace Serein.Library.Utils { /// /// IOC管理容器 /// public class SereinIoc : ISereinIoc { /// /// 实例集合 /// private readonly ConcurrentDictionary _dependencies; /// /// 未完成注入的实例集合。 /// 键:需要的类型名称 /// 值:对象实例(存储对象) /// private readonly ConcurrentDictionary> _unfinishedDependencies; /// /// 类型集合 /// private readonly ConcurrentDictionary _typeMappings; /// /// 待实例化的类型 /// private readonly List _waitingForInstantiation; public SereinIoc() { // 首先注册自己 _dependencies = new ConcurrentDictionary { [typeof(ISereinIoc).FullName] = this }; _typeMappings = new ConcurrentDictionary { [typeof(ISereinIoc).FullName] = typeof(ISereinIoc) }; _unfinishedDependencies = new ConcurrentDictionary>(); _waitingForInstantiation = new List(); } /// /// 获取或创建实例对象(不注入对象的依赖项) /// /// 目标类型 /// 构造函数的参数 /// public object GetOrCreateServiceInstance(Type type, params object[] parameters) { if (_dependencies.ContainsKey(type.FullName)) { return _dependencies[type.FullName]; } else { var instance = Activator.CreateInstance(type); // 创建目标类型的实例对象 InjectDependencies(instance);// 注入目标对象的依赖项 _dependencies[type.FullName] = instance; // 记录实例 return instance; } } /// /// 泛型方法, 获取或创建实例对象(不注入对象的依赖项) /// /// 目标类型 /// 构造函数的参数 /// public T GetOrCreateServiceInstance(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(); } } _typeMappings.Clear(); _dependencies.Clear(); _waitingForInstantiation.Clear(); return this; } /// /// 注册类型 /// /// 目标类型 /// 参数 public ISereinIoc Register(Type type, params object[] parameters) { RegisterType(type.FullName, type); return this; } /// /// 注册类型 /// /// 目标类型 /// 参数 public ISereinIoc Register(params object[] parameters) { var type = typeof(T); RegisterType(type.FullName, type); return this; } public ISereinIoc Register(params object[] parameters) where TImplementation : TService { var typeFullName = typeof(TService).FullName; RegisterType(typeFullName, 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(typeof(T)); value = Instantiate(typeof(T)); } return (T)value; //throw new InvalidOperationException("目标类型未创建实例"); } /// /// 实例化所有已注册的类型,并尝试绑定 /// /// public ISereinIoc Build() { // 遍历已注册类型 foreach (var type in _typeMappings.Values.ToArray()) { if(_dependencies.ContainsKey(type.FullName)) { // 已经存在实例,不用管 } else { // 如果没有创建实例,则创建对应的实例 _dependencies[type.FullName] = CreateInstance(type); } // 移除类型的注册记录 _typeMappings.TryRemove(type.FullName,out _); } // 注入实例的依赖项 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 = CreateInstance(controllerType, parameters); if(instance != null) { InjectDependencies(instance); } return instance; } /// /// 注册类型 /// /// /// private void RegisterType(string typeFull, Type type) { if (!_typeMappings.ContainsKey(typeFull)) { _typeMappings[typeFull] = type; } } /// /// 创建实例时,尝试注入到由ioc容器管理、并需要此实例的对象。 /// private object CreateInstance(Type type, params object[] parameters) { var instance = Activator.CreateInstance(type); if(_unfinishedDependencies.TryGetValue(type.FullName, out var unfinishedPropertyList)) { foreach ((object obj, PropertyInfo property) in unfinishedPropertyList) { property.SetValue(obj, instance); //注入依赖项 } if(_unfinishedDependencies.TryRemove(type.FullName, out unfinishedPropertyList)) { unfinishedPropertyList.Clear(); } } return instance; } /// /// 注入目标实例的依赖项 /// /// private bool InjectDependencies(object instance) { var properties = instance.GetType() .GetProperties(BindingFlags.Instance | BindingFlags.Public).ToArray() .Where(p => p.CanWrite // 可写属性 && p.GetCustomAttribute() != null // 有特性标注需要注入 && p.GetValue(instance) == null); // 属性为空 var isPass = true; foreach (var property in properties) { var propertyType = property.PropertyType; // 通过属性类型名称从ioc容器中获取对应的实例 if (_dependencies.TryGetValue(propertyType.FullName, out var dependencyInstance)) { property.SetValue(instance, dependencyInstance); // 尝试写入到目标实例的属性中 } else { // 存在依赖项,但目标类型的实例暂未加载,需要等待需要实例完成注册 var unfinishedDependenciesList = _unfinishedDependencies.GetOrAdd(propertyType.FullName, _ = new List<(object, PropertyInfo)>()); var data = (instance, property); if (!unfinishedDependenciesList.Contains(data)) { unfinishedDependenciesList.Add(data); } isPass = false; } } return isPass; } /// /// 再次尝试注入目标实例的依赖项 /// 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); } } }*/ }