mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-03 00:00:49 +08:00
792 lines
28 KiB
C#
792 lines
28 KiB
C#
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||
using Serein.Library.Api;
|
||
using System;
|
||
using System.Collections.Concurrent;
|
||
using System.Collections.Generic;
|
||
using System.Diagnostics;
|
||
using System.Linq;
|
||
using System.Reflection;
|
||
using System.Text;
|
||
|
||
namespace Serein.Library.Utils
|
||
{
|
||
|
||
/// <summary>
|
||
/// 一个轻量级的IOC容器
|
||
/// </summary>
|
||
public class SereinIOC : ISereinIOC
|
||
{
|
||
/// <summary>
|
||
/// 类型集合,暂放待实例化的类型,完成实例化之后移除
|
||
/// </summary>
|
||
private readonly ConcurrentDictionary<string, Type> _typeMappings;
|
||
|
||
/// <summary>
|
||
/// 已完成注入的实例集合
|
||
/// </summary>
|
||
private readonly ConcurrentDictionary<string, object> _dependencies;
|
||
|
||
/// <summary>
|
||
/// 能够获取类型实例的闭包
|
||
/// </summary>
|
||
private readonly ConcurrentDictionary<string, Func<object>> _registerCallback;
|
||
|
||
|
||
/// <summary>
|
||
/// 未完成注入的实例集合。
|
||
/// 键:需要的类型名称
|
||
/// 值:元组(对象实例,对象的属性)
|
||
/// </summary>
|
||
private readonly ConcurrentDictionary<string, List<(object,PropertyInfo)>> _unfinishedDependencies;
|
||
|
||
/// <summary>
|
||
/// IOC容器成功创建了类型
|
||
/// </summary>
|
||
public event IOCMembersChangedHandler OnIOCMembersChanged;
|
||
|
||
/// <summary>
|
||
/// 一个轻量级的IOC容器
|
||
/// </summary>
|
||
public SereinIOC()
|
||
{
|
||
_dependencies = new ConcurrentDictionary<string, object>();
|
||
_registerCallback = new ConcurrentDictionary<string, Func<object>>();
|
||
_typeMappings = new ConcurrentDictionary<string, Type>();
|
||
_unfinishedDependencies = new ConcurrentDictionary<string, List<(object, PropertyInfo)>>();
|
||
}
|
||
|
||
#region 类型的注册
|
||
/// <summary>
|
||
/// 向容器注册类型
|
||
/// </summary>
|
||
/// <param name="type">需要注册的类型</param>
|
||
/// <returns></returns>
|
||
public ISereinIOC Register(Type type)
|
||
{
|
||
RegisterType(type.FullName, type);
|
||
return this;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 向容器注册类型,并指定其实例成员
|
||
/// </summary>
|
||
/// <param name="type">需要注册的类型</param>
|
||
/// <param name="getInstance">获取实例的回调函数</param>
|
||
/// <returns></returns>
|
||
public ISereinIOC Register(Type type, Func<object> getInstance)
|
||
{
|
||
RegisterType(type.FullName, type, getInstance);
|
||
return this;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 向容器注册类型,并指定其实例成员
|
||
/// </summary>
|
||
/// <typeparam name="T">需要注册的类型</typeparam>
|
||
/// <returns></returns>
|
||
public ISereinIOC Register<T>()
|
||
{
|
||
var type = typeof(T);
|
||
RegisterType(type.FullName, type);
|
||
return this;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 向容器注册类型,并指定其实例成员
|
||
/// </summary>
|
||
/// <typeparam name="T">需要注册的类型</typeparam>
|
||
/// <param name="getInstance">获取实例的回调函数</param>
|
||
/// <returns></returns>
|
||
public ISereinIOC Register<T>(Func<T> getInstance)
|
||
{
|
||
var type = typeof(T);
|
||
RegisterType(type.FullName, type, () => getInstance.Invoke());
|
||
return this;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 向容器注册接口类型,并指定其实例成员
|
||
/// </summary>
|
||
/// <typeparam name="TService">接口类型</typeparam>
|
||
/// <typeparam name="TImplementation">实现类类型</typeparam>
|
||
/// <param name="getInstance">获取实例的方法</param>
|
||
/// <returns></returns>
|
||
public ISereinIOC Register<TService, TImplementation>(Func<TService> getInstance)
|
||
where TImplementation : TService
|
||
{
|
||
|
||
RegisterType(typeof(TService).FullName, typeof(TImplementation), () => getInstance.Invoke());
|
||
return this;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 向容器注册接口类型,其实例成员由容器自动创建
|
||
/// </summary>
|
||
/// <typeparam name="TService">接口类型</typeparam>
|
||
/// <typeparam name="TImplementation">实现类类型</typeparam>
|
||
/// <returns></returns>
|
||
public ISereinIOC Register<TService, TImplementation>()
|
||
where TImplementation : TService
|
||
{
|
||
|
||
RegisterType(typeof(TService).FullName, typeof(TImplementation));
|
||
return this;
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
#region 实例的创建
|
||
/// <summary>
|
||
/// 用于临时实例的创建,不登记到IOC容器中,依赖项注入失败时也不记录。
|
||
/// </summary>
|
||
/// <param name="type"></param>
|
||
/// <returns></returns>
|
||
public object CreateObject(Type type)
|
||
{
|
||
var ctors = GetConstructor(type); // 获取构造函数
|
||
object instance = null;
|
||
// 从入参最多的构造函数开始构建对象
|
||
foreach (var ctor in ctors)
|
||
{
|
||
|
||
var parameters = ctor.GetParameters(); // 获取构造函数参数列表
|
||
var parametersNames = parameters.Select(p => $"{p.ParameterType} {p.Name}");
|
||
var parametersName = string.Join(", ", parametersNames);
|
||
try
|
||
{
|
||
var parameterValues = parameters.Select(param => Get(param.ParameterType)).ToArray(); // 生成创建类型的入参参数
|
||
instance = Activator.CreateInstance(type, parameterValues); // 创建实例
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine(ex);
|
||
SereinEnv.WriteLine(InfoType.INFO, $"在【{type}】类型上使用ctor({parametersName})构造函数时创建对象失败。错误信息:{ex.Message}");
|
||
continue;
|
||
}
|
||
InjectDependencies(instance, false); // 完成创建后注入实例需要的特性依赖项
|
||
break;
|
||
}
|
||
if (instance == null)
|
||
{
|
||
throw new Exception($"无法为【{type}】类型创建实例");
|
||
}
|
||
return instance;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 用于临时实例的创建,不登记到IOC容器中,依赖项注入失败时也不记录。
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <returns></returns>
|
||
public T CreateObject<T>()
|
||
{
|
||
return (T)CreateObject(typeof(T));
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 给定一个实例,尽可能地在该实例中具有[AutoInjection]特性的属性/字段上,设置为IOC容器中已有的对应类型的对象。
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="instance"></param>
|
||
/// <returns></returns>
|
||
public T InjectDependenciesProperty<T>(T instance)
|
||
{
|
||
var type = instance.GetType();
|
||
var properties = type.GetType()
|
||
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).ToArray()
|
||
.Where(p => p.CanWrite // 可写属性
|
||
&& p.GetCustomAttribute<AutoInjectionAttribute>() != null // 有特性标注需要注入
|
||
&& p.GetValue(instance) == null); // 属性为空
|
||
|
||
// 属性注入
|
||
foreach (var property in properties)
|
||
{
|
||
var propertyType = property.PropertyType;
|
||
if (_dependencies.TryGetValue(propertyType.FullName, out var dependencyInstance))
|
||
{
|
||
property.SetValue(instance, dependencyInstance); // 尝试写入到目标实例的属性中
|
||
}
|
||
}
|
||
|
||
|
||
// 字段注入
|
||
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic )
|
||
.Where(f => f.GetCustomAttribute<AutoInjectionAttribute>() != null
|
||
&& f.GetValue(instance) == null);
|
||
|
||
foreach (var field in fields)
|
||
{
|
||
var fieldType = field.FieldType;
|
||
if (_dependencies.TryGetValue(fieldType.FullName, out var dependencyInstance))
|
||
{
|
||
field.SetValue(instance, dependencyInstance);
|
||
}
|
||
}
|
||
|
||
return instance;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 通过名称记录或获取一个实例
|
||
|
||
/// <summary>
|
||
/// 尝试获取指定类型的示例
|
||
/// </summary>
|
||
/// <param name="type"></param>
|
||
/// <returns></returns>
|
||
public object Get(Type type)
|
||
{
|
||
var instance = Get(type.FullName);
|
||
if(instance is null)
|
||
{
|
||
SereinEnv.WriteLine(InfoType.INFO, "类型没有注册:" + type.FullName);
|
||
}
|
||
|
||
return Get(type.FullName);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 尝试获取指定类型的示例
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <returns></returns>
|
||
public T Get<T>()
|
||
{
|
||
return (T)Get(typeof(T).FullName);
|
||
}
|
||
private object Get(string name)
|
||
{
|
||
if (!_dependencies.TryGetValue(name, out object value))
|
||
{
|
||
value = null;
|
||
}
|
||
return value;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 容器管理(清空,绑定)
|
||
|
||
/// <summary>
|
||
/// 清空容器对象
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public ISereinIOC Reset()
|
||
{
|
||
// 检查是否存在非托管资源
|
||
foreach (var instancei in _dependencies.Values)
|
||
{
|
||
if (typeof(IDisposable).IsAssignableFrom(instancei.GetType()) && instancei is IDisposable disposable)
|
||
{
|
||
disposable?.Dispose();
|
||
}
|
||
}
|
||
_registerCallback?.Clear();
|
||
_unfinishedDependencies?.Clear();
|
||
_typeMappings?.Clear();
|
||
_dependencies?.Clear();
|
||
return this;
|
||
}
|
||
|
||
class TypeKeyValue
|
||
{
|
||
public TypeKeyValue(string name, Type type)
|
||
{
|
||
this.Type = type;
|
||
this.Name = name;
|
||
}
|
||
public string Name { get; set; }
|
||
public Type Type { get; set; }
|
||
}
|
||
|
||
|
||
private const string IOC_MAIN = "*Priority Instantiation*";
|
||
|
||
/// <summary>
|
||
/// <para>遍历所有需要注册的类型,获取到它们所有构造函数,并统计每个构造函数的入参类型,构建依赖关系树</para>
|
||
/// </summary>
|
||
/// <returns>“ID-PID”关系的树形结构</returns>
|
||
private Dictionary<string, List<string>> BuildDependencyTree()
|
||
{
|
||
var dependencyMap = new Dictionary<string, HashSet<string>>();
|
||
dependencyMap[IOC_MAIN] = new HashSet<string>(); // 优先实例化
|
||
foreach (var typeMapping in _typeMappings)
|
||
{
|
||
var typeFullName = typeMapping.Key; // 注册的类型 FullName
|
||
var type = typeMapping.Value; // 对应的Type。如果是以接口形式注册,typeFullName将是接口类的FullName,而type将是接口实现类。
|
||
var constructors = GetConstructor(type); // 获取构造函数
|
||
|
||
foreach (var constructor in constructors)
|
||
{
|
||
if (constructor is null)
|
||
{
|
||
continue;
|
||
}
|
||
var parameters = constructor.GetParameters().Select(p => p.ParameterType);
|
||
var ctorCount = constructors.Length;
|
||
var ctorParamCount = parameters.Count();
|
||
|
||
// 类型仅有一个构造函数,并且无参,将优先实例化
|
||
if (ctorCount == 1 && ctorParamCount == 0)
|
||
{
|
||
if (!dependencyMap[IOC_MAIN].Contains(type.FullName))
|
||
{
|
||
//dependencyMap[IOC_MAIN].Add(type.FullName);
|
||
dependencyMap[IOC_MAIN].Add(typeFullName);
|
||
}
|
||
continue;
|
||
}
|
||
|
||
// 从类型的有参构造函数中提取类型
|
||
foreach (var param in parameters)
|
||
{
|
||
if (!dependencyMap.TryGetValue(param.FullName, out var hashSet))
|
||
{
|
||
hashSet = new HashSet<string>();
|
||
hashSet.Add(typeMapping.Key);
|
||
dependencyMap.Add(param.FullName, hashSet);
|
||
}
|
||
else
|
||
{
|
||
if (!hashSet.Contains(typeMapping.Key))
|
||
{
|
||
hashSet.Add(typeMapping.Key);
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
var tmp = dependencyMap.ToDictionary(key => key.Key, value => value.Value.ToList());
|
||
return tmp;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取类型的所有构造函数,根据入参数量,由多到少排列
|
||
/// </summary>
|
||
/// <param name="type"></param>
|
||
/// <returns></returns>
|
||
private ConstructorInfo[] GetConstructor(Type type)
|
||
{
|
||
return type.GetConstructors().OrderByDescending(ctor => ctor.GetParameters().Length).ToArray();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建实例的生成顺序
|
||
/// </summary>
|
||
/// <param name="dependencyMap">依赖关系树</param>
|
||
/// <returns></returns>
|
||
public List<string> GetCreationOrder(Dictionary<string, List<string>> dependencyMap)
|
||
{
|
||
var graph = new Dictionary<string, List<string>>(); // 另一种依赖关系树
|
||
var indegree = new Dictionary<string, int>(); // 表示出现次数
|
||
|
||
foreach (var entry in dependencyMap)
|
||
{
|
||
|
||
// “rootNode”是注册类的类型FullName属性
|
||
var rootNode = entry.Key; // 根节点
|
||
|
||
if (!graph.ContainsKey(rootNode))
|
||
{
|
||
graph[rootNode] = new List<string>();
|
||
}
|
||
|
||
// “childNode”是注册类构造函数中出现过的参数的类型FullName属性
|
||
foreach (var childNode in entry.Value)
|
||
{
|
||
if (!graph.ContainsKey(childNode))
|
||
{
|
||
graph[childNode] = new List<string>();
|
||
}
|
||
graph[rootNode].Add(childNode);
|
||
|
||
// 更新入度
|
||
if (!indegree.ContainsKey(childNode))
|
||
{
|
||
indegree[childNode] = 0;
|
||
}
|
||
indegree[childNode]++;
|
||
}
|
||
|
||
if (!indegree.ContainsKey(rootNode))
|
||
{
|
||
indegree[rootNode] = 0;
|
||
}
|
||
}
|
||
|
||
// 拓扑排序
|
||
var creationOrder = new List<string>();
|
||
var queue = new Queue<string>(indegree.Where(x => x.Value == 0).Select(x => x.Key));
|
||
|
||
while (queue.Count > 0)
|
||
{
|
||
var current = queue.Dequeue();
|
||
creationOrder.Add(current);
|
||
foreach (var neighbor in graph[current])
|
||
{
|
||
indegree[neighbor]--;
|
||
if (indegree[neighbor] == 0)
|
||
{
|
||
queue.Enqueue(neighbor);
|
||
}
|
||
}
|
||
}
|
||
|
||
var tmpList = indegree.Where(kv => kv.Value > 0).Select(kv => kv.Key).ToList();
|
||
if (tmpList.Count > 0)
|
||
{
|
||
StringBuilder sb = new StringBuilder();
|
||
sb.Append("以下类型存在循环依赖,请避免循环依赖,如果确实需要循环引用,请使用 [AutoInjection] 特性注入属性");
|
||
foreach (var kv in tmpList)
|
||
{
|
||
sb.AppendLine($"类名 : {kv}");
|
||
}
|
||
SereinEnv.WriteLine(InfoType.ERROR, sb.ToString());
|
||
}
|
||
|
||
return creationOrder;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建实例对象
|
||
/// </summary>
|
||
/// <param name="typeName"></param>
|
||
/// <returns></returns>
|
||
private object CreateInstance(string typeName)
|
||
{
|
||
|
||
if (!_typeMappings.TryGetValue(typeName, out var type)) // 获取类型
|
||
{
|
||
return null;
|
||
}
|
||
if (_dependencies.TryGetValue(typeName, out var instance)) // 获取实例
|
||
{
|
||
return instance;
|
||
}
|
||
if (_registerCallback.TryGetValue(typeName,out var getInstance))
|
||
{
|
||
return getInstance.Invoke();
|
||
}
|
||
|
||
// 字符串、值类型,抽象类型,暂时不支持自动创建
|
||
if (type == typeof(string) || type.IsValueType || type.IsAbstract)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
else
|
||
{
|
||
// 没有显示指定构造函数入参,选择参数最多的构造函数
|
||
//var constructor = GetConstructorWithMostParameters(type);
|
||
var constructors = GetConstructor(type); // 获取构造函数
|
||
|
||
foreach(var constructor in constructors)
|
||
{
|
||
var parameters = constructor.GetParameters();
|
||
var args = new object[parameters.Length];
|
||
for (int i = 0; i < parameters.Length; i++)
|
||
{
|
||
var argType = parameters[i].ParameterType;
|
||
var fullName = parameters[i].ParameterType.FullName;
|
||
if (!_dependencies.TryGetValue(fullName, out var argObj))
|
||
{
|
||
if (!_typeMappings.ContainsKey(fullName))
|
||
{
|
||
_typeMappings.TryAdd(fullName, argType);
|
||
}
|
||
argObj = CreateInstance(fullName);
|
||
if (argObj is null)
|
||
{
|
||
SereinEnv.WriteLine(InfoType.WARN, "构造参数创建失败");
|
||
continue;
|
||
}
|
||
}
|
||
args[i] = argObj;
|
||
}
|
||
try
|
||
{
|
||
instance = Activator.CreateInstance(type, args);
|
||
if(instance != null)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
catch (Exception)
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
InjectDependencies(instance); // 完成创建后注入实例需要的特性依赖项
|
||
_dependencies[typeName] = instance;
|
||
return instance;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 绑定所有类型,生成示例
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public ISereinIOC Build()
|
||
{
|
||
Dictionary<string, List<string>> dependencyTree = BuildDependencyTree(); // 生成类型依赖关系
|
||
List<string> creationOrder = GetCreationOrder(dependencyTree); // 生成创建顺序
|
||
|
||
// 输出创建顺序
|
||
Debug.WriteLine("创建顺序: " + string.Join($"{Environment.NewLine}↓ {Environment.NewLine}", creationOrder));
|
||
|
||
// 创建对象
|
||
foreach (var typeName in creationOrder)
|
||
{
|
||
if (typeName.Equals("Serein.Library.LightweightFlowEnvironment"))
|
||
{
|
||
|
||
}
|
||
if (_dependencies.ContainsKey(typeName))
|
||
{
|
||
continue;
|
||
}
|
||
if(typeName == IOC_MAIN)
|
||
{
|
||
continue;
|
||
}
|
||
var value = CreateInstance(typeName);
|
||
|
||
if (value is null)
|
||
{
|
||
SereinEnv.WriteLine(InfoType.ERROR, $"IOC容器无法创建对象:{typeName}");
|
||
continue;
|
||
}
|
||
_dependencies[typeName] = value;
|
||
OnIOCMembersChanged?.Invoke(new IOCMembersChangedEventArgs(typeName, value));
|
||
|
||
}
|
||
_typeMappings.Clear();
|
||
return this;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 私有方法
|
||
|
||
/// <summary>
|
||
/// 注册类型
|
||
/// </summary>
|
||
/// <param name="typeFull">类型名称</param>
|
||
/// <param name="type">要注册的类型</param>
|
||
/// <param name="getInstance">获取实例的闭包</param>
|
||
private bool RegisterType(string typeFull, Type type, Func<object> getInstance = null)
|
||
{
|
||
if (!_typeMappings.ContainsKey(typeFull))
|
||
{
|
||
_typeMappings[typeFull] = type;
|
||
if(getInstance != null)
|
||
{
|
||
_registerCallback[typeFull] = getInstance;
|
||
}
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 如果其它实例想要该对象时,注入过去
|
||
/// </summary>
|
||
private void InjectUnfinishedDependencies(string key, object instance)
|
||
{
|
||
if (_unfinishedDependencies.TryGetValue(key, out var unfinishedPropertyList))
|
||
{
|
||
foreach ((object obj, PropertyInfo property) in unfinishedPropertyList)
|
||
{
|
||
property.SetValue(obj, instance); //注入依赖项
|
||
}
|
||
|
||
if (_unfinishedDependencies.TryRemove(key, out unfinishedPropertyList))
|
||
{
|
||
unfinishedPropertyList.Clear();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 注入目标实例的依赖项
|
||
/// </summary>
|
||
/// <param name="instance">实例</param>
|
||
/// <param name="isRecord">未完成依赖项注入时是否记录</param>
|
||
private bool InjectDependencies(object instance,bool isRecord = true)
|
||
{
|
||
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;
|
||
foreach (var property in properties)
|
||
{
|
||
var propertyType = property.PropertyType;
|
||
// 通过属性类型名称从ioc容器中获取对应的实例
|
||
if (_dependencies.TryGetValue(propertyType.FullName, out var dependencyInstance))
|
||
{
|
||
property.SetValue(instance, dependencyInstance); // 尝试写入到目标实例的属性中
|
||
}
|
||
else if( isRecord )
|
||
{
|
||
// 存在依赖项,但目标类型的实例暂未加载,需要等待需要实例完成注册
|
||
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;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 运行
|
||
|
||
public ISereinIOC Run<T>(Action<T> action)
|
||
{
|
||
var service = Get<T>();
|
||
action(service);
|
||
return this;
|
||
}
|
||
|
||
public ISereinIOC Run<T1, T2>(Action<T1, T2> action)
|
||
{
|
||
var service1 = Get<T1>();
|
||
var service2 = Get<T2>();
|
||
|
||
action(service1, service2);
|
||
return this;
|
||
}
|
||
|
||
public ISereinIOC Run<T1, T2, T3>(Action<T1, T2, T3> action)
|
||
{
|
||
var service1 = Get<T1>();
|
||
var service2 = Get<T2>();
|
||
var service3 = Get<T3>();
|
||
action(service1, service2, service3);
|
||
return this;
|
||
}
|
||
|
||
public ISereinIOC Run<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action)
|
||
{
|
||
var service1 = Get<T1>();
|
||
var service2 = Get<T2>();
|
||
var service3 = Get<T3>();
|
||
var service4 = Get<T4>();
|
||
action(service1, service2, service3, service4);
|
||
return this;
|
||
}
|
||
|
||
#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);
|
||
}
|
||
}
|
||
}*/
|
||
|
||
|
||
|
||
}
|