Files
serein-flow/Library/Utils/SereinIoc.cs

490 lines
17 KiB
C#
Raw Normal View History

using Serein.Library.Api;
using Serein.Library.Attributes;
using System;
2024-08-06 15:41:14 +08:00
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
2024-08-06 15:41:14 +08:00
using System.Reflection;
namespace Serein.Library.Utils
2024-08-06 15:41:14 +08:00
{
/// <summary>
/// IOC管理容器
/// </summary>
public class SereinIoc : ISereinIoc
2024-08-06 15:41:14 +08:00
{
/// <summary>
/// 实例集合
/// </summary>
2024-08-06 15:41:14 +08:00
private readonly ConcurrentDictionary<string, object> _dependencies;
/// <summary>
/// 未完成注入的实例集合。
/// 键:需要的类型名称
/// 值:对象实例(存储对象)
/// </summary>
private readonly ConcurrentDictionary<string, List<(object,PropertyInfo)>> _unfinishedDependencies;
/// <summary>
/// 类型集合
/// </summary>
2024-08-06 15:41:14 +08:00
private readonly ConcurrentDictionary<string, Type> _typeMappings;
/// <summary>
/// 待实例化的类型
/// </summary>
2024-08-06 15:41:14 +08:00
private readonly List<Type> _waitingForInstantiation;
public SereinIoc()
2024-08-06 15:41:14 +08:00
{
// 首先注册自己
2024-08-06 15:41:14 +08:00
_dependencies = new ConcurrentDictionary<string, object>
{
[typeof(ISereinIoc).FullName] = this
2024-08-06 15:41:14 +08:00
};
_typeMappings = new ConcurrentDictionary<string, Type>
{
[typeof(ISereinIoc).FullName] = typeof(ISereinIoc)
};
_unfinishedDependencies = new ConcurrentDictionary<string, List<(object, PropertyInfo)>>();
_waitingForInstantiation = new List<Type>();
2024-08-06 15:41:14 +08:00
}
/// <summary>
/// 获取或创建实例对象(不注入对象的依赖项)
/// </summary>
/// <param name="type">目标类型</param>
/// <param name="parameters">构造函数的参数</param>
/// <returns></returns>
2024-08-06 15:41:14 +08:00
public object GetOrCreateServiceInstance(Type type, params object[] parameters)
{
if (_dependencies.ContainsKey(type.FullName))
{
return _dependencies[type.FullName];
2024-08-06 15:41:14 +08:00
}
else
{
var instance = Activator.CreateInstance(type); // 创建目标类型的实例对象
InjectDependencies(instance);// 注入目标对象的依赖项
_dependencies[type.FullName] = instance; // 记录实例
return instance;
2024-08-06 15:41:14 +08:00
}
}
/// <summary>
/// 泛型方法, 获取或创建实例对象(不注入对象的依赖项)
/// </summary>
/// <typeparam name="T">目标类型</typeparam>
/// <param name="parameters">构造函数的参数</param>
/// <returns></returns>
public T GetOrCreateServiceInstance<T>(params object[] parameters)
2024-08-06 15:41:14 +08:00
{
return (T)GetOrCreateServiceInstance(typeof(T), parameters);
}
/// <summary>
/// 清空容器对象
/// </summary>
/// <returns></returns>
public ISereinIoc Reset()
2024-08-06 15:41:14 +08:00
{
// 检查是否存在非托管资源
2024-08-06 15:41:14 +08:00
foreach(var instancei in _dependencies.Values)
{
if (typeof(IDisposable).IsAssignableFrom(instancei.GetType()) && instancei is IDisposable disposable)
{
disposable.Dispose();
}
}
_typeMappings.Clear();
2024-08-06 15:41:14 +08:00
_dependencies.Clear();
_waitingForInstantiation.Clear();
return this;
}
/// <summary>
/// 注册类型
/// </summary>
/// <param name="type">目标类型</param>
/// <param name="parameters">参数</param>
public ISereinIoc Register(Type type, params object[] parameters)
2024-08-06 15:41:14 +08:00
{
RegisterType(type.FullName, type);
2024-08-06 15:41:14 +08:00
return this;
}
/// <summary>
/// 注册类型
/// </summary>
/// <param name="type">目标类型</param>
/// <param name="parameters">参数</param>
public ISereinIoc Register<T>(params object[] parameters)
2024-08-06 15:41:14 +08:00
{
var type = typeof(T);
RegisterType(type.FullName, type);
2024-08-06 15:41:14 +08:00
return this;
}
public ISereinIoc Register<TService, TImplementation>(params object[] parameters)
2024-08-06 15:41:14 +08:00
where TImplementation : TService
{
var typeFullName = typeof(TService).FullName;
RegisterType(typeFullName, typeof(TImplementation));
2024-08-06 15:41:14 +08:00
return this;
}
/// <summary>
/// 注册
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public object GetOrInstantiate(Type type)
{
2024-08-06 15:41:14 +08:00
if (!_dependencies.TryGetValue(type.FullName, out object value))
{
Register(type);
value = Instantiate(type);
InjectDependencies(type);
}
return value;
}
public T GetOrInstantiate<T>()
2024-08-06 15:41:14 +08:00
{
if(!_dependencies.TryGetValue(typeof(T).FullName, out object value))
{
Register(typeof(T));
2024-08-06 15:41:14 +08:00
value = Instantiate(typeof(T));
}
return (T)value;
//throw new InvalidOperationException("目标类型未创建实例");
}
/// <summary>
/// 实例化所有已注册的类型,并尝试绑定
/// </summary>
/// <returns></returns>
public ISereinIoc Build()
2024-08-06 15:41:14 +08:00
{
// 遍历已注册类型
foreach (var type in _typeMappings.Values.ToArray())
2024-08-06 15:41:14 +08:00
{
if(_dependencies.ContainsKey(type.FullName))
{
// 已经存在实例,不用管
}
else
2024-08-06 15:41:14 +08:00
{
// 如果没有创建实例,则创建对应的实例
_dependencies[type.FullName] = CreateInstance(type);
2024-08-06 15:41:14 +08:00
}
// 移除类型的注册记录
_typeMappings.TryRemove(type.FullName,out _);
2024-08-06 15:41:14 +08:00
}
// 注入实例的依赖项
2024-08-06 15:41:14 +08:00
foreach (var instance in _dependencies.Values)
{
InjectDependencies(instance);
2024-08-06 15:41:14 +08:00
}
//var instance = Instantiate(item.Value);
// TryInstantiateWaitingDependencies();
2024-08-06 15:41:14 +08:00
return this;
}
public object Instantiate(Type controllerType, params object[] parameters)
2024-08-06 15:41:14 +08:00
{
var instance = CreateInstance(controllerType, parameters);
2024-08-06 15:41:14 +08:00
if(instance != null)
{
2024-08-06 15:41:14 +08:00
InjectDependencies(instance);
}
return instance;
}
/// <summary>
/// 注册类型
/// </summary>
/// <param name="typeFull"></param>
/// <param name="type"></param>
private void RegisterType(string typeFull, Type type)
2024-08-06 15:41:14 +08:00
{
if (!_typeMappings.ContainsKey(typeFull))
{
_typeMappings[typeFull] = type;
}
}
2024-08-06 15:41:14 +08:00
/// <summary>
/// 创建实例时尝试注入到由ioc容器管理、并需要此实例的对象。
/// </summary>
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;
}
/// <summary>
/// 注入目标实例的依赖项
/// </summary>
/// <param name="instance"></param>
private bool InjectDependencies(object instance)
{
var properties = instance.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToArray()
.Where(p => p.CanWrite // 可写属性
&& p.GetCustomAttribute<AutoInjectionAttribute>() != null // 有特性标注需要注入
&& p.GetValue(instance) == null); // 属性为空
var isPass = true;
2024-08-06 15:41:14 +08:00
foreach (var property in properties)
{
var propertyType = property.PropertyType;
// 通过属性类型名称从ioc容器中获取对应的实例
2024-08-06 15:41:14 +08:00
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;
2024-08-06 15:41:14 +08:00
}
}
return isPass;
2024-08-06 15:41:14 +08:00
}
/// <summary>
/// 再次尝试注入目标实例的依赖项
/// </summary>
2024-08-06 15:41:14 +08:00
private void TryInstantiateWaitingDependencies()
{
foreach (var waitingType in _waitingForInstantiation.ToList())
{
if (_typeMappings.TryGetValue(waitingType.FullName, out var implementationType))
2024-08-06 15:41:14 +08:00
{
var instance = Instantiate(implementationType);
if (instance != null)
{
_dependencies[waitingType.FullName] = instance;
_waitingForInstantiation.Remove(waitingType);
}
}
}
}
#region run()
public ISereinIoc Run<T>(Action<T> action)
2024-08-06 15:41:14 +08:00
{
var service = GetOrInstantiate<T>();
2024-08-06 15:41:14 +08:00
if (service != null)
{
action(service);
}
return this;
}
public ISereinIoc Run<T1, T2>(Action<T1, T2> action)
2024-08-06 15:41:14 +08:00
{
var service1 = GetOrInstantiate<T1>();
var service2 = GetOrInstantiate<T2>();
2024-08-06 15:41:14 +08:00
action(service1, service2);
return this;
}
public ISereinIoc Run<T1, T2, T3>(Action<T1, T2, T3> action)
2024-08-06 15:41:14 +08:00
{
var service1 = GetOrInstantiate<T1>();
var service2 = GetOrInstantiate<T2>();
var service3 = GetOrInstantiate<T3>();
2024-08-06 15:41:14 +08:00
action(service1, service2, service3);
return this;
}
public ISereinIoc Run<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action)
2024-08-06 15:41:14 +08:00
{
var service1 = GetOrInstantiate<T1>();
var service2 = GetOrInstantiate<T2>();
var service3 = GetOrInstantiate<T3>();
var service4 = GetOrInstantiate<T4>();
2024-08-06 15:41:14 +08:00
action(service1, service2, service3, service4);
return this;
}
public ISereinIoc Run<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> action)
2024-08-06 15:41:14 +08:00
{
var service1 = GetOrInstantiate<T1>();
var service2 = GetOrInstantiate<T2>();
var service3 = GetOrInstantiate<T3>();
var service4 = GetOrInstantiate<T4>();
var service5 = GetOrInstantiate<T5>();
2024-08-06 15:41:14 +08:00
action(service1, service2, service3, service4, service5);
return this;
}
public ISereinIoc Run<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> action)
2024-08-06 15:41:14 +08:00
{
var service1 = GetOrInstantiate<T1>();
var service2 = GetOrInstantiate<T2>();
var service3 = GetOrInstantiate<T3>();
var service4 = GetOrInstantiate<T4>();
var service5 = GetOrInstantiate<T5>();
var service6 = GetOrInstantiate<T6>();
2024-08-06 15:41:14 +08:00
action(service1, service2, service3, service4, service5, service6);
return this;
}
public ISereinIoc Run<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> action)
2024-08-06 15:41:14 +08:00
{
var service1 = GetOrInstantiate<T1>();
var service2 = GetOrInstantiate<T2>();
var service3 = GetOrInstantiate<T3>();
var service4 = GetOrInstantiate<T4>();
var service5 = GetOrInstantiate<T5>();
var service6 = GetOrInstantiate<T6>();
var service7 = GetOrInstantiate<T7>();
2024-08-06 15:41:14 +08:00
action(service1, service2, service3, service4, service5, service6, service7);
return this;
}
public ISereinIoc Run<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
2024-08-06 15:41:14 +08:00
{
var service1 = GetOrInstantiate<T1>();
var service2 = GetOrInstantiate<T2>();
var service3 = GetOrInstantiate<T3>();
var service4 = GetOrInstantiate<T4>();
var service5 = GetOrInstantiate<T5>();
var service6 = GetOrInstantiate<T6>();
var service7 = GetOrInstantiate<T7>();
var service8 = GetOrInstantiate<T8>();
2024-08-06 15:41:14 +08:00
action(service1, service2, service3, service4, service5, service6, service7, service8);
return this;
}
2024-08-06 15:41:14 +08:00
#endregion
}
/* public interface IServiceContainer
{
ServiceContainer Register<T>(params object[] parameters);
ServiceContainer Register<TService, TImplementation>(params object[] parameters) where TImplementation : TService;
TService Resolve<TService>();
void Get<T>(Action<T> action);
object Instantiate(Type type, params object[] parameters);
}
public class ServiceContainer : IServiceContainer
{
private readonly Dictionary<Type, object> _dependencies;
public ServiceContainer()
{
_dependencies = new Dictionary<Type, object>
{
[typeof(IServiceContainer)] = this
};
}
public void Get<T>(Action<T> action)
{
var service = Resolve<T>();
action(service);
}
public ServiceContainer Register<T>(params object[] parameters)
{
var instance = Instantiate(typeof(T), parameters);
_dependencies[typeof(T)] = instance;
return this;
}
public ServiceContainer Register<TService, TImplementation>(params object[] parameters)
where TImplementation : TService
{
_dependencies[typeof(TService)] = Instantiate(typeof(TImplementation), parameters);
return this;
}
public TService Resolve<TService>()
{
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<object>();
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);
}
}
}*/
}