2025-06-02 15:16:23 +08:00
|
|
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
|
|
|
|
using Serein.Library.Api;
|
2024-09-12 20:32:54 +08:00
|
|
|
|
using System;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
using System.Collections.Concurrent;
|
2024-09-12 20:32:54 +08:00
|
|
|
|
using System.Collections.Generic;
|
2024-09-30 16:36:55 +08:00
|
|
|
|
using System.Diagnostics;
|
2024-09-12 20:32:54 +08:00
|
|
|
|
using System.Linq;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
using System.Reflection;
|
2024-11-08 17:30:51 +08:00
|
|
|
|
using System.Text;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
|
2024-09-12 20:32:54 +08:00
|
|
|
|
namespace Serein.Library.Utils
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-10-20 12:10:57 +08:00
|
|
|
|
|
2024-09-16 19:53:36 +08:00
|
|
|
|
/// <summary>
|
2025-06-02 16:38:37 +08:00
|
|
|
|
/// 一个轻量级的IOC容器
|
2024-09-16 19:53:36 +08:00
|
|
|
|
/// </summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
public class SereinIOC : ISereinIOC
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-16 19:53:36 +08:00
|
|
|
|
/// <summary>
|
2024-09-17 14:20:27 +08:00
|
|
|
|
/// 类型集合,暂放待实例化的类型,完成实例化之后移除
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private readonly ConcurrentDictionary<string, Type> _typeMappings;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-09-24 22:39:43 +08:00
|
|
|
|
/// 已完成注入的实例集合
|
2024-09-16 19:53:36 +08:00
|
|
|
|
/// </summary>
|
2024-08-06 15:41:14 +08:00
|
|
|
|
private readonly ConcurrentDictionary<string, object> _dependencies;
|
2025-06-02 15:16:23 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 能够获取类型实例的闭包
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private readonly ConcurrentDictionary<string, Func<object>> _registerCallback;
|
2024-09-17 14:20:27 +08:00
|
|
|
|
|
2025-07-07 20:40:24 +08:00
|
|
|
|
|
2024-09-16 19:53:36 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 未完成注入的实例集合。
|
|
|
|
|
|
/// 键:需要的类型名称
|
2024-09-17 14:20:27 +08:00
|
|
|
|
/// 值:元组(对象实例,对象的属性)
|
2024-09-16 19:53:36 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
private readonly ConcurrentDictionary<string, List<(object,PropertyInfo)>> _unfinishedDependencies;
|
|
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// IOC容器成功创建了类型
|
|
|
|
|
|
/// </summary>
|
2024-09-26 21:00:17 +08:00
|
|
|
|
public event IOCMembersChangedHandler OnIOCMembersChanged;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 一个轻量级的IOC容器
|
|
|
|
|
|
/// </summary>
|
2024-09-16 21:38:34 +08:00
|
|
|
|
public SereinIOC()
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-17 14:20:27 +08:00
|
|
|
|
_dependencies = new ConcurrentDictionary<string, object>();
|
2025-06-02 15:16:23 +08:00
|
|
|
|
_registerCallback = new ConcurrentDictionary<string, Func<object>>();
|
2024-09-17 14:20:27 +08:00
|
|
|
|
_typeMappings = new ConcurrentDictionary<string, Type>();
|
2024-09-16 19:53:36 +08:00
|
|
|
|
_unfinishedDependencies = new ConcurrentDictionary<string, List<(object, PropertyInfo)>>();
|
2024-08-06 15:41:14 +08:00
|
|
|
|
}
|
2024-09-16 19:53:36 +08:00
|
|
|
|
|
2024-09-16 21:38:34 +08:00
|
|
|
|
#region 类型的注册
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 向容器注册类型
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="type">需要注册的类型</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public ISereinIOC Register(Type type)
|
|
|
|
|
|
{
|
|
|
|
|
|
RegisterType(type.FullName, type);
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
2024-08-06 15:41:14 +08:00
|
|
|
|
|
2024-09-16 19:53:36 +08:00
|
|
|
|
/// <summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// 向容器注册类型,并指定其实例成员
|
2024-09-16 19:53:36 +08:00
|
|
|
|
/// </summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <param name="type">需要注册的类型</param>
|
|
|
|
|
|
/// <param name="getInstance">获取实例的回调函数</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public ISereinIOC Register(Type type, Func<object> getInstance)
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2025-06-02 15:16:23 +08:00
|
|
|
|
RegisterType(type.FullName, type, getInstance);
|
|
|
|
|
|
return this;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
}
|
2025-06-02 15:16:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-06-02 16:38:37 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 向容器注册类型,并指定其实例成员
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T">需要注册的类型</typeparam>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public ISereinIOC Register<T>()
|
|
|
|
|
|
{
|
|
|
|
|
|
var type = typeof(T);
|
|
|
|
|
|
RegisterType(type.FullName, type);
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-09-16 19:53:36 +08:00
|
|
|
|
/// <summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// 向容器注册类型,并指定其实例成员
|
2024-09-16 19:53:36 +08:00
|
|
|
|
/// </summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <typeparam name="T">需要注册的类型</typeparam>
|
|
|
|
|
|
/// <param name="getInstance">获取实例的回调函数</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public ISereinIOC Register<T>(Func<T> getInstance)
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-16 19:53:36 +08:00
|
|
|
|
var type = typeof(T);
|
2025-06-02 15:16:23 +08:00
|
|
|
|
RegisterType(type.FullName, type, () => getInstance.Invoke());
|
|
|
|
|
|
return this;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
|
2024-09-17 14:20:27 +08:00
|
|
|
|
/// <summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// 向容器注册接口类型,并指定其实例成员
|
2024-09-17 14:20:27 +08:00
|
|
|
|
/// </summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <typeparam name="TService">接口类型</typeparam>
|
|
|
|
|
|
/// <typeparam name="TImplementation">实现类类型</typeparam>
|
|
|
|
|
|
/// <param name="getInstance">获取实例的方法</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public ISereinIOC Register<TService, TImplementation>(Func<TService> getInstance)
|
2024-08-06 15:41:14 +08:00
|
|
|
|
where TImplementation : TService
|
|
|
|
|
|
{
|
2025-07-07 20:40:24 +08:00
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
RegisterType(typeof(TService).FullName, typeof(TImplementation), () => getInstance.Invoke());
|
|
|
|
|
|
return this;
|
2024-09-17 15:58:37 +08:00
|
|
|
|
}
|
2025-06-02 15:16:23 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 向容器注册接口类型,其实例成员由容器自动创建
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="TService">接口类型</typeparam>
|
|
|
|
|
|
/// <typeparam name="TImplementation">实现类类型</typeparam>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public ISereinIOC Register<TService, TImplementation>()
|
|
|
|
|
|
where TImplementation : TService
|
|
|
|
|
|
{
|
2025-07-07 20:40:24 +08:00
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
RegisterType(typeof(TService).FullName, typeof(TImplementation));
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-09-16 21:38:34 +08:00
|
|
|
|
#endregion
|
2024-08-06 15:41:14 +08:00
|
|
|
|
|
2025-07-07 20:40:24 +08:00
|
|
|
|
#region 实例的创建
|
2024-09-16 21:38:34 +08:00
|
|
|
|
/// <summary>
|
2024-09-24 22:39:43 +08:00
|
|
|
|
/// 用于临时实例的创建,不登记到IOC容器中,依赖项注入失败时也不记录。
|
2024-09-16 21:38:34 +08:00
|
|
|
|
/// </summary>
|
2024-10-15 10:55:41 +08:00
|
|
|
|
/// <param name="type"></param>
|
2024-09-24 22:39:43 +08:00
|
|
|
|
/// <returns></returns>
|
2025-06-22 21:53:37 +08:00
|
|
|
|
public object CreateObject(Type type)
|
2024-09-16 21:38:34 +08:00
|
|
|
|
{
|
2025-06-02 15:16:23 +08:00
|
|
|
|
var ctors = GetConstructor(type); // 获取构造函数
|
|
|
|
|
|
object instance = null;
|
|
|
|
|
|
// 从入参最多的构造函数开始构建对象
|
|
|
|
|
|
foreach (var ctor in ctors)
|
2024-09-24 22:39:43 +08:00
|
|
|
|
{
|
2025-06-02 15:16:23 +08:00
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2024-09-30 02:45:49 +08:00
|
|
|
|
InjectDependencies(instance, false); // 完成创建后注入实例需要的特性依赖项
|
2025-06-02 15:16:23 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (instance == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception($"无法为【{type}】类型创建实例");
|
2024-09-24 22:39:43 +08:00
|
|
|
|
}
|
|
|
|
|
|
return instance;
|
2024-09-16 21:38:34 +08:00
|
|
|
|
}
|
2024-08-06 15:41:14 +08:00
|
|
|
|
|
2024-09-26 21:00:17 +08:00
|
|
|
|
/// <summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// 用于临时实例的创建,不登记到IOC容器中,依赖项注入失败时也不记录。
|
2024-09-26 21:00:17 +08:00
|
|
|
|
/// </summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
|
|
/// <returns></returns>
|
2025-06-22 21:53:37 +08:00
|
|
|
|
public T CreateObject<T>()
|
2024-12-26 22:24:44 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 通过名称记录或获取一个实例
|
|
|
|
|
|
|
2024-12-26 22:24:44 +08:00
|
|
|
|
/// <summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// 尝试获取指定类型的示例
|
2024-12-26 22:24:44 +08:00
|
|
|
|
/// </summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <param name="type"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2024-09-21 10:06:44 +08:00
|
|
|
|
public object Get(Type type)
|
|
|
|
|
|
{
|
2024-10-10 10:45:53 +08:00
|
|
|
|
var instance = Get(type.FullName);
|
|
|
|
|
|
if(instance is null)
|
|
|
|
|
|
{
|
2024-11-08 17:30:51 +08:00
|
|
|
|
SereinEnv.WriteLine(InfoType.INFO, "类型没有注册:" + type.FullName);
|
2024-10-10 10:45:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-21 10:06:44 +08:00
|
|
|
|
return Get(type.FullName);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 尝试获取指定类型的示例
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
|
|
/// <returns></returns>
|
2024-09-30 02:45:49 +08:00
|
|
|
|
public T Get<T>()
|
|
|
|
|
|
{
|
|
|
|
|
|
return (T)Get(typeof(T).FullName);
|
|
|
|
|
|
}
|
2024-09-24 22:39:43 +08:00
|
|
|
|
private object Get(string name)
|
2024-09-21 10:06:44 +08:00
|
|
|
|
{
|
2024-09-30 02:45:49 +08:00
|
|
|
|
if (!_dependencies.TryGetValue(name, out object value))
|
2024-09-21 10:06:44 +08:00
|
|
|
|
{
|
|
|
|
|
|
value = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-24 22:39:43 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
2024-09-16 21:38:34 +08:00
|
|
|
|
#region 容器管理(清空,绑定)
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 清空容器对象
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
public ISereinIOC Reset()
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-16 21:38:34 +08:00
|
|
|
|
// 检查是否存在非托管资源
|
|
|
|
|
|
foreach (var instancei in _dependencies.Values)
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-16 21:38:34 +08:00
|
|
|
|
if (typeof(IDisposable).IsAssignableFrom(instancei.GetType()) && instancei is IDisposable disposable)
|
|
|
|
|
|
{
|
|
|
|
|
|
disposable?.Dispose();
|
|
|
|
|
|
}
|
2024-08-06 15:41:14 +08:00
|
|
|
|
}
|
2025-06-02 15:16:23 +08:00
|
|
|
|
_registerCallback?.Clear();
|
2024-09-16 21:38:34 +08:00
|
|
|
|
_unfinishedDependencies?.Clear();
|
|
|
|
|
|
_typeMappings?.Clear();
|
|
|
|
|
|
_dependencies?.Clear();
|
2025-06-02 15:16:23 +08:00
|
|
|
|
return this;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
}
|
2025-06-02 15:16:23 +08:00
|
|
|
|
|
|
|
|
|
|
class TypeKeyValue
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-30 16:36:55 +08:00
|
|
|
|
public TypeKeyValue(string name, Type type)
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-30 16:36:55 +08:00
|
|
|
|
this.Type = type;
|
|
|
|
|
|
this.Name = name;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
}
|
2024-09-30 16:36:55 +08:00
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
|
public Type Type { get; set; }
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
2025-06-22 21:53:37 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private const string IOC_MAIN = "*Priority Instantiation*";
|
2024-10-20 12:10:57 +08:00
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <summary>
|
2025-06-22 21:53:37 +08:00
|
|
|
|
/// <para>遍历所有需要注册的类型,获取到它们所有构造函数,并统计每个构造函数的入参类型,构建依赖关系树</para>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// </summary>
|
2025-06-22 21:53:37 +08:00
|
|
|
|
/// <returns>“ID-PID”关系的树形结构</returns>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
private Dictionary<string, List<string>> BuildDependencyTree()
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2024-10-20 12:10:57 +08:00
|
|
|
|
var dependencyMap = new Dictionary<string, HashSet<string>>();
|
2025-06-22 21:53:37 +08:00
|
|
|
|
dependencyMap[IOC_MAIN] = new HashSet<string>(); // 优先实例化
|
2024-09-30 16:36:55 +08:00
|
|
|
|
foreach (var typeMapping in _typeMappings)
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
var typeFullName = typeMapping.Key; // 注册的类型 FullName
|
|
|
|
|
|
var type = typeMapping.Value; // 对应的Type。如果是以接口形式注册,typeFullName将是接口类的FullName,而type将是接口实现类。
|
|
|
|
|
|
var constructors = GetConstructor(type); // 获取构造函数
|
2025-07-08 14:22:41 +08:00
|
|
|
|
if(constructors .Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!dependencyMap[IOC_MAIN].Contains(type.FullName))
|
|
|
|
|
|
{
|
|
|
|
|
|
//dependencyMap[IOC_MAIN].Add(type.FullName);
|
|
|
|
|
|
dependencyMap[IOC_MAIN].Add(typeFullName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-10-20 12:10:57 +08:00
|
|
|
|
foreach (var constructor in constructors)
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
if (constructor is null)
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
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))
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2025-07-07 20:40:24 +08:00
|
|
|
|
//dependencyMap[IOC_MAIN].Add(type.FullName);
|
|
|
|
|
|
dependencyMap[IOC_MAIN].Add(typeFullName);
|
2025-06-22 21:53:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
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);
|
2024-10-20 12:10:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
if (!hashSet.Contains(typeMapping.Key))
|
2024-10-20 12:10:57 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
hashSet.Add(typeMapping.Key);
|
2024-10-10 10:45:53 +08:00
|
|
|
|
}
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-06-22 21:53:37 +08:00
|
|
|
|
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
2024-10-20 12:10:57 +08:00
|
|
|
|
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
2024-10-20 12:10:57 +08:00
|
|
|
|
var tmp = dependencyMap.ToDictionary(key => key.Key, value => value.Value.ToList());
|
|
|
|
|
|
return tmp;
|
2024-09-30 16:36:55 +08:00
|
|
|
|
}
|
2025-06-02 15:16:23 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-06-22 21:53:37 +08:00
|
|
|
|
/// 获取类型的所有构造函数,根据入参数量,由多到少排列
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="type"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2024-10-20 12:10:57 +08:00
|
|
|
|
private ConstructorInfo[] GetConstructor(Type type)
|
|
|
|
|
|
{
|
2025-06-02 15:16:23 +08:00
|
|
|
|
return type.GetConstructors().OrderByDescending(ctor => ctor.GetParameters().Length).ToArray();
|
2024-10-20 12:10:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <summary>
|
2025-06-22 21:53:37 +08:00
|
|
|
|
/// 创建实例的生成顺序
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// </summary>
|
2025-06-22 21:53:37 +08:00
|
|
|
|
/// <param name="dependencyMap">依赖关系树</param>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <returns></returns>
|
2024-09-30 16:36:55 +08:00
|
|
|
|
public List<string> GetCreationOrder(Dictionary<string, List<string>> dependencyMap)
|
|
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
var graph = new Dictionary<string, List<string>>(); // 另一种依赖关系树
|
|
|
|
|
|
var indegree = new Dictionary<string, int>(); // 表示出现次数
|
2024-09-30 02:45:49 +08:00
|
|
|
|
|
2024-09-30 16:36:55 +08:00
|
|
|
|
foreach (var entry in dependencyMap)
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
|
|
|
|
|
|
// “rootNode”是注册类的类型FullName属性
|
|
|
|
|
|
var rootNode = entry.Key; // 根节点
|
|
|
|
|
|
|
|
|
|
|
|
if (!graph.ContainsKey(rootNode))
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
graph[rootNode] = new List<string>();
|
2024-09-30 16:36:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-22 21:53:37 +08:00
|
|
|
|
// “childNode”是注册类构造函数中出现过的参数的类型FullName属性
|
|
|
|
|
|
foreach (var childNode in entry.Value)
|
2024-09-30 16:36:55 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
if (!graph.ContainsKey(childNode))
|
2024-09-30 16:36:55 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
graph[childNode] = new List<string>();
|
2024-09-30 16:36:55 +08:00
|
|
|
|
}
|
2025-06-22 21:53:37 +08:00
|
|
|
|
graph[rootNode].Add(childNode);
|
2024-09-30 16:36:55 +08:00
|
|
|
|
|
|
|
|
|
|
// 更新入度
|
2025-06-22 21:53:37 +08:00
|
|
|
|
if (!indegree.ContainsKey(childNode))
|
2024-09-30 16:36:55 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
indegree[childNode] = 0;
|
2024-09-30 16:36:55 +08:00
|
|
|
|
}
|
2025-06-22 21:53:37 +08:00
|
|
|
|
indegree[childNode]++;
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
2024-09-30 16:36:55 +08:00
|
|
|
|
|
2025-06-22 21:53:37 +08:00
|
|
|
|
if (!indegree.ContainsKey(rootNode))
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
indegree[rootNode] = 0;
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-30 16:36:55 +08:00
|
|
|
|
// 拓扑排序
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-10-08 11:25:51 +08:00
|
|
|
|
|
|
|
|
|
|
var tmpList = indegree.Where(kv => kv.Value > 0).Select(kv => kv.Key).ToList();
|
|
|
|
|
|
if (tmpList.Count > 0)
|
|
|
|
|
|
{
|
2024-11-08 17:30:51 +08:00
|
|
|
|
StringBuilder sb = new StringBuilder();
|
2025-06-22 21:53:37 +08:00
|
|
|
|
sb.Append("以下类型存在循环依赖,请避免循环依赖,如果确实需要循环引用,请使用 [AutoInjection] 特性注入属性");
|
2024-10-08 11:25:51 +08:00
|
|
|
|
foreach (var kv in tmpList)
|
|
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
sb.AppendLine($"类名 : {kv}");
|
2024-10-08 11:25:51 +08:00
|
|
|
|
}
|
2024-11-08 17:30:51 +08:00
|
|
|
|
SereinEnv.WriteLine(InfoType.ERROR, sb.ToString());
|
2024-10-08 11:25:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-30 16:36:55 +08:00
|
|
|
|
return creationOrder;
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 创建实例对象
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="typeName"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
private object CreateInstance(string typeName)
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2025-07-07 20:40:24 +08:00
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
if (!_typeMappings.TryGetValue(typeName, out var type)) // 获取类型
|
2024-10-10 10:45:53 +08:00
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2025-06-02 15:16:23 +08:00
|
|
|
|
if (_dependencies.TryGetValue(typeName, out var instance)) // 获取实例
|
2024-10-10 10:45:53 +08:00
|
|
|
|
{
|
|
|
|
|
|
return instance;
|
|
|
|
|
|
}
|
2025-06-22 21:53:37 +08:00
|
|
|
|
if (_registerCallback.TryGetValue(typeName,out var getInstance))
|
2024-10-10 10:45:53 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
return getInstance.Invoke();
|
2024-10-10 10:45:53 +08:00
|
|
|
|
}
|
2024-10-20 12:10:57 +08:00
|
|
|
|
|
|
|
|
|
|
// 字符串、值类型,抽象类型,暂时不支持自动创建
|
|
|
|
|
|
if (type == typeof(string) || type.IsValueType || type.IsAbstract)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-10 10:45:53 +08:00
|
|
|
|
else
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2024-10-10 10:45:53 +08:00
|
|
|
|
// 没有显示指定构造函数入参,选择参数最多的构造函数
|
2024-10-20 12:10:57 +08:00
|
|
|
|
//var constructor = GetConstructorWithMostParameters(type);
|
2025-06-22 21:53:37 +08:00
|
|
|
|
var constructors = GetConstructor(type); // 获取构造函数
|
2024-10-20 12:10:57 +08:00
|
|
|
|
|
|
|
|
|
|
foreach(var constructor in constructors)
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2024-10-20 12:10:57 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
2024-11-08 17:30:51 +08:00
|
|
|
|
SereinEnv.WriteLine(InfoType.WARN, "构造参数创建失败");
|
2024-10-20 12:10:57 +08:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
args[i] = argObj;
|
|
|
|
|
|
}
|
|
|
|
|
|
try
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2024-10-20 12:10:57 +08:00
|
|
|
|
instance = Activator.CreateInstance(type, args);
|
|
|
|
|
|
if(instance != null)
|
2024-10-10 10:45:53 +08:00
|
|
|
|
{
|
2024-10-20 12:10:57 +08:00
|
|
|
|
break;
|
2024-10-10 10:45:53 +08:00
|
|
|
|
}
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
2024-10-20 12:10:57 +08:00
|
|
|
|
catch (Exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
2024-10-20 12:10:57 +08:00
|
|
|
|
|
|
|
|
|
|
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-10 10:45:53 +08:00
|
|
|
|
InjectDependencies(instance); // 完成创建后注入实例需要的特性依赖项
|
|
|
|
|
|
_dependencies[typeName] = instance;
|
|
|
|
|
|
return instance;
|
2024-09-30 16:36:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 绑定所有类型,生成示例
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public ISereinIOC Build()
|
2024-09-30 16:36:55 +08:00
|
|
|
|
{
|
2025-07-07 20:40:24 +08:00
|
|
|
|
Dictionary<string, List<string>> dependencyTree = BuildDependencyTree(); // 生成类型依赖关系
|
|
|
|
|
|
List<string> creationOrder = GetCreationOrder(dependencyTree); // 生成创建顺序
|
2024-09-30 16:36:55 +08:00
|
|
|
|
|
|
|
|
|
|
// 输出创建顺序
|
2025-06-22 21:53:37 +08:00
|
|
|
|
Debug.WriteLine("创建顺序: " + string.Join($"{Environment.NewLine}↓ {Environment.NewLine}", creationOrder));
|
2024-09-30 16:36:55 +08:00
|
|
|
|
|
|
|
|
|
|
// 创建对象
|
|
|
|
|
|
foreach (var typeName in creationOrder)
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2025-07-07 20:40:24 +08:00
|
|
|
|
if (typeName.Equals("Serein.Library.LightweightFlowEnvironment"))
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2024-09-30 16:36:55 +08:00
|
|
|
|
if (_dependencies.ContainsKey(typeName))
|
2024-09-30 02:45:49 +08:00
|
|
|
|
{
|
2024-09-30 16:36:55 +08:00
|
|
|
|
continue;
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
2025-07-04 15:46:29 +08:00
|
|
|
|
if(typeName == IOC_MAIN)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2024-09-30 16:36:55 +08:00
|
|
|
|
var value = CreateInstance(typeName);
|
2025-07-07 20:40:24 +08:00
|
|
|
|
|
|
|
|
|
|
if (value is null)
|
2024-10-10 10:45:53 +08:00
|
|
|
|
{
|
2025-06-22 21:53:37 +08:00
|
|
|
|
SereinEnv.WriteLine(InfoType.ERROR, $"IOC容器无法创建对象:{typeName}");
|
2024-10-10 10:45:53 +08:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2024-09-30 16:36:55 +08:00
|
|
|
|
_dependencies[typeName] = value;
|
2025-06-02 16:38:37 +08:00
|
|
|
|
OnIOCMembersChanged?.Invoke(new IOCMembersChangedEventArgs(typeName, value));
|
2025-07-07 20:40:24 +08:00
|
|
|
|
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
2024-09-30 16:36:55 +08:00
|
|
|
|
_typeMappings.Clear();
|
2025-06-02 15:16:23 +08:00
|
|
|
|
return this;
|
2024-09-30 02:45:49 +08:00
|
|
|
|
}
|
2024-09-30 16:36:55 +08:00
|
|
|
|
|
2024-09-16 21:38:34 +08:00
|
|
|
|
#endregion
|
2024-08-06 15:41:14 +08:00
|
|
|
|
|
2024-09-16 21:38:34 +08:00
|
|
|
|
#region 私有方法
|
2024-09-16 19:53:36 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 注册类型
|
|
|
|
|
|
/// </summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
/// <param name="typeFull">类型名称</param>
|
|
|
|
|
|
/// <param name="type">要注册的类型</param>
|
|
|
|
|
|
/// <param name="getInstance">获取实例的闭包</param>
|
|
|
|
|
|
private bool RegisterType(string typeFull, Type type, Func<object> getInstance = null)
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-16 19:53:36 +08:00
|
|
|
|
if (!_typeMappings.ContainsKey(typeFull))
|
|
|
|
|
|
{
|
|
|
|
|
|
_typeMappings[typeFull] = type;
|
2025-06-02 15:16:23 +08:00
|
|
|
|
if(getInstance != null)
|
2024-10-10 10:45:53 +08:00
|
|
|
|
{
|
2025-06-02 15:16:23 +08:00
|
|
|
|
_registerCallback[typeFull] = getInstance;
|
2024-10-10 10:45:53 +08:00
|
|
|
|
}
|
2024-09-24 22:39:43 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
2024-09-16 19:53:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-08-06 15:41:14 +08:00
|
|
|
|
|
2024-09-30 02:45:49 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 如果其它实例想要该对象时,注入过去
|
|
|
|
|
|
/// </summary>
|
2025-06-02 15:16:23 +08:00
|
|
|
|
private void InjectUnfinishedDependencies(string key, object instance)
|
2024-09-26 21:00:17 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (_unfinishedDependencies.TryGetValue(key, out var unfinishedPropertyList))
|
2024-09-16 19:53:36 +08:00
|
|
|
|
{
|
|
|
|
|
|
foreach ((object obj, PropertyInfo property) in unfinishedPropertyList)
|
|
|
|
|
|
{
|
|
|
|
|
|
property.SetValue(obj, instance); //注入依赖项
|
|
|
|
|
|
}
|
2024-09-16 21:38:34 +08:00
|
|
|
|
|
2024-09-26 21:00:17 +08:00
|
|
|
|
if (_unfinishedDependencies.TryRemove(key, out unfinishedPropertyList))
|
2024-09-16 19:53:36 +08:00
|
|
|
|
{
|
|
|
|
|
|
unfinishedPropertyList.Clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 注入目标实例的依赖项
|
|
|
|
|
|
/// </summary>
|
2024-09-24 22:39:43 +08:00
|
|
|
|
/// <param name="instance">实例</param>
|
|
|
|
|
|
/// <param name="isRecord">未完成依赖项注入时是否记录</param>
|
|
|
|
|
|
private bool InjectDependencies(object instance,bool isRecord = true)
|
2024-09-16 19:53:36 +08:00
|
|
|
|
{
|
|
|
|
|
|
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;
|
2024-09-16 19:53:36 +08:00
|
|
|
|
// 通过属性类型名称从ioc容器中获取对应的实例
|
2024-08-06 15:41:14 +08:00
|
|
|
|
if (_dependencies.TryGetValue(propertyType.FullName, out var dependencyInstance))
|
|
|
|
|
|
{
|
2024-09-16 19:53:36 +08:00
|
|
|
|
property.SetValue(instance, dependencyInstance); // 尝试写入到目标实例的属性中
|
|
|
|
|
|
}
|
2024-10-08 11:25:51 +08:00
|
|
|
|
else if( isRecord )
|
2024-09-16 19:53:36 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 存在依赖项,但目标类型的实例暂未加载,需要等待需要实例完成注册
|
2024-09-16 21:38:34 +08:00
|
|
|
|
var unfinishedDependenciesList = _unfinishedDependencies.GetOrAdd(propertyType.FullName, _ = new List<(object, PropertyInfo)>());
|
2024-09-16 19:53:36 +08:00
|
|
|
|
var data = (instance, property);
|
2024-09-16 21:38:34 +08:00
|
|
|
|
if (!unfinishedDependenciesList.Contains(data))
|
|
|
|
|
|
{
|
|
|
|
|
|
unfinishedDependenciesList.Add(data);
|
|
|
|
|
|
}
|
|
|
|
|
|
isPass = false;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-09-16 19:53:36 +08:00
|
|
|
|
return isPass;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-02 16:38:37 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region 运行
|
|
|
|
|
|
|
|
|
|
|
|
public ISereinIOC Run<T>(Action<T> action)
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-30 02:45:49 +08:00
|
|
|
|
var service = Get<T>();
|
2024-10-10 10:45:53 +08:00
|
|
|
|
action(service);
|
2025-06-02 16:38:37 +08:00
|
|
|
|
return this;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-02 16:38:37 +08:00
|
|
|
|
public ISereinIOC Run<T1, T2>(Action<T1, T2> action)
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-30 02:45:49 +08:00
|
|
|
|
var service1 = Get<T1>();
|
|
|
|
|
|
var service2 = Get<T2>();
|
2024-08-06 15:41:14 +08:00
|
|
|
|
|
2025-06-02 16:38:37 +08:00
|
|
|
|
action(service1, service2);
|
|
|
|
|
|
return this;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-02 16:38:37 +08:00
|
|
|
|
public ISereinIOC Run<T1, T2, T3>(Action<T1, T2, T3> action)
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-30 02:45:49 +08:00
|
|
|
|
var service1 = Get<T1>();
|
|
|
|
|
|
var service2 = Get<T2>();
|
|
|
|
|
|
var service3 = Get<T3>();
|
2024-08-06 15:41:14 +08:00
|
|
|
|
action(service1, service2, service3);
|
2025-06-02 16:38:37 +08:00
|
|
|
|
return this;
|
2024-08-06 15:41:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-02 16:38:37 +08:00
|
|
|
|
public ISereinIOC Run<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action)
|
2024-08-06 15:41:14 +08:00
|
|
|
|
{
|
2024-09-30 02:45:49 +08:00
|
|
|
|
var service1 = Get<T1>();
|
|
|
|
|
|
var service2 = Get<T2>();
|
|
|
|
|
|
var service3 = Get<T3>();
|
|
|
|
|
|
var service4 = Get<T4>();
|
2024-08-06 15:41:14 +08:00
|
|
|
|
action(service1, service2, service3, service4);
|
2025-06-02 16:38:37 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|