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(); } #region 类型的注册 /// /// 注册类型 /// /// 目标类型 /// 参数 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; } #endregion /// /// 尝试从容器中获取对象,如果不存在目标类型的对象,则将类型信息登记到容器,并实例化注入依赖项。 /// public object GetOrInstantiate(Type type) { // 尝试从容器中获取对象 if (!_dependencies.TryGetValue(type.FullName, out object value)) { Register(type);// 注册类型信息 value = Instantiate(type); // 创建实例对象,并注入依赖 _dependencies.TryAdd(type.FullName, value); // 登记到IOC容器中 } return value; } /// /// 尝试从容器中获取对象,如果不存在目标类型的对象,则将类型信息登记到容器,并实例化注入依赖项。 /// public T GetOrInstantiate() { var value = Instantiate(typeof(T)); return (T)value; } /// /// 根据类型生成对应的实例,并注入其中的依赖项(类型信息不登记到IOC容器中) /// /// /// /// public object Instantiate(Type controllerType, params object[] parameters) { var instance = CreateInstance(controllerType, parameters); // 创建目标类型的实例 if(instance != null) { InjectDependencies(instance); // 完成创建后注入实例需要的依赖项 } return instance; } #region 容器管理(清空,绑定) /// /// 清空容器对象 /// /// public ISereinIOC Reset() { // 检查是否存在非托管资源 foreach (var instancei in _dependencies.Values) { if (typeof(IDisposable).IsAssignableFrom(instancei.GetType()) && instancei is IDisposable disposable) { disposable?.Dispose(); } } _unfinishedDependencies?.Clear(); _typeMappings?.Clear(); _dependencies?.Clear(); _waitingForInstantiation?.Clear(); return this; } /// /// 实例化所有已注册的类型,并尝试绑定 /// /// 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; } #endregion #region 私有方法 /// /// 注册类型 /// /// /// 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); } } } } #endregion #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); } } }*/ }