修改了IOC容器的实现,使其更加轻量

This commit is contained in:
fengjiayi
2025-06-02 15:16:23 +08:00
parent e9832c0dbd
commit a43c611d72
10 changed files with 317 additions and 362 deletions

View File

@@ -5,106 +5,85 @@ using System.Text;
namespace Serein.Library.Api namespace Serein.Library.Api
{ {
/// <summary> /// <summary>
/// <para>单例模式IOC容器内部维护了一个实例字典默认使用类型的FullName作为Key如果以“接口-实现类”的方式注册那么将使用接口类型的FullName作为Key。</para> /// <para>单例模式IOC容器内部维护了一个实例字典默认使用类型的FullName作为Key</para>
/// <para>如果以“接口-实现类”的方式注册那么将使用接口类型的FullName作为Key。</para>
/// <para>当某个类型注册绑定成功后,将不会因为其它地方尝试注册相同类型的行为导致类型被重新创建。</para> /// <para>当某个类型注册绑定成功后,将不会因为其它地方尝试注册相同类型的行为导致类型被重新创建。</para>
/// </summary> /// </summary>
public interface ISereinIOC public interface ISereinIOC
{ {
/// <summary> /// <summary>
/// 慎用重置IOC容器除非再次注册绑定否则将导致不能创建注入依赖类的临时对象。 /// 慎用重置IOC容器除非再次注册绑定否则将导致不能创建注入依赖类的临时对象。
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
ISereinIOC Reset(); ISereinIOC Reset();
/// <summary> /// <summary>
/// 注册实例如果确定了params那么将使用params入参构建实例对象。 /// 通过指定类型的方式注册实例
/// </summary> /// </summary>
ISereinIOC Register(Type type, params object[] parameters); /// <param name="type">实例类型</param>
/// <summary>
/// 通过泛型的方式注册实例如果确定了params那么将使用params入参构建实例对象。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="parameters"></param>
/// <returns></returns> /// <returns></returns>
ISereinIOC Register<T>(params object[] parameters); ISereinIOC Register(Type type);
/// <summary>
/// 通过指定类型的方式注册实例
/// </summary>
/// <param name="type">实例类型</param>
/// <param name="getInstance">获取实例的回调函数</param>
/// <returns></returns>
ISereinIOC Register(Type type, Func<object> getInstance);
/// <summary>
/// 通过泛型的方式注册实例
/// </summary>
/// <typeparam name="T">实例类型</typeparam>
/// <param name="getInstance">获取实例的回调函数</param>
/// <returns></returns>
ISereinIOC Register<T>(Func<T> getInstance);
/// <summary> /// <summary>
/// 注册接口的实例 /// 注册接口的实例
/// </summary> /// </summary>
/// <typeparam name="TService">接口类型</typeparam> /// <typeparam name="TService">接口类型</typeparam>
/// <typeparam name="TImplementation">实例类型</typeparam> /// <typeparam name="TImplementation">实例类型</typeparam>
/// <param name="parameters"></param> /// <param name="getInstance">获取实例的回调函数</param>
/// <returns></returns> /// <returns></returns>
ISereinIOC Register<TService, TImplementation>(params object[] parameters) where TImplementation : TService; ISereinIOC Register<TService, TImplementation>(Func<TService> getInstance) where TImplementation : TService;
/// <summary> /// <summary>
/// 指定一个Key登记一个持久化的实例。 /// 注册接口的实现类
/// </summary> /// </summary>
/// <param name="key">登记使用的名称</param> /// <typeparam name="TService">接口类型</typeparam>
/// <param name="instance">实例对象</param> /// <typeparam name="TImplementation">实例类型</typeparam>
/// <returns>是否注册成功</returns> /// <returns></returns>
bool RegisterPersistennceInstance(string key, object instance); ISereinIOC Register<TService, TImplementation>() where TImplementation : TService;
/// <summary>
/// 指定一个Key登记一个实例。
/// </summary>
/// <param name="key">登记使用的名称</param>
/// <param name="instance">实例对象</param>
/// <returns>是否注册成功</returns>
/// bool RegisterInstance(string key, object instance);
/// <summary> /// <summary>
/// 获取类型的实例。如果需要获取的类型以“接口-实现类”的方式注册,请使用接口的类型。 /// 获取类型的实例。如果需要获取的类型以“接口-实现类”的方式注册,请使用接口的类型。
/// </summary> /// </summary>
object Get(Type type); object Get(Type type);
/// <summary> /// <summary>
/// 获取类型的实例。如果需要获取的类型以“接口-实现类”的方式注册,请使用接口的类型。 /// 获取类型的实例。如果需要获取的类型以“接口-实现类”的方式注册,请使用接口的类型。
/// </summary> /// </summary>
T Get<T>(); T Get<T>();
/// <summary> /// <summary>
/// <para>获取指定名称的实例。</para> /// <para>给定一个类型由IOC容器负责创建实例如果存在多个构造函数将由参数最多的构造函数开始尝试创建。</para>
/// <para>正常情况下应该使用 Get(Type type) / T Get&lt;T&gt;() 进行获取但如果需要的实例是以CustomRegisterInstance()进行的登记,则需要通过这种方法进行获取。</para>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key">登记实例时使用的Key</param>
/// <returns></returns>
/// T Get<T>(string key);
/// <summary>
/// <para>创建实例并注入依赖项不会注册到IOC容器中。</para>
/// <para>使用场景:例如 View 的构造函数中需要创建 ViewModel而 ViewModel 存在注册过的依赖项,可以通过该接口进行创建</para>
/// <para></para> /// <para></para>
/// </summary> /// </summary>
object Instantiate(Type type); object CreateTempObject(Type type);
/// <summary> /// <summary>
/// <para>创建实例并注入依赖项不会注册到IOC容器中。</para> /// <para>给定一个类型由IOC容器负责创建实例如果存在多个构造函数将由参数最多的构造函数开始尝试创建。</para>
/// <para>使用场景:例如 View 的构造函数中需要创建 ViewModel而 ViewModel 存在注册过的依赖项,可以通过该接口进行创建</para>
/// <para></para> /// <para></para>
/// </summary> /// </summary>
T Instantiate<T>(); T CreateTempObject<T>();
/// <summary> /// <summary>
/// 通过已注册的类型生成依赖关系,然后依次实例化并注入依赖项,最后登记到容器中 /// 搜寻已注册的类型生成依赖关系,依次实例化并注入依赖项,缓存在由IOC容器维护的Map中直到手动调用Reset()方法
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
ISereinIOC Build(); ISereinIOC Build();
/// <summary>
/// 从容器中获取某个类型的实例进行运行
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="action"></param>
/// <returns></returns>
ISereinIOC Run<T>(Action<T> action);
ISereinIOC Run<T1, T2>(Action<T1, T2> action);
ISereinIOC Run<T1, T2, T3>(Action<T1, T2, T3> action);
ISereinIOC Run<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action);
ISereinIOC Run<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> action);
ISereinIOC Run<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> action);
ISereinIOC Run<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> action);
ISereinIOC Run<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> action);
} }
} }

View File

@@ -246,7 +246,7 @@ namespace Serein.Library
var type = EnumHelper.GetBoundValue(ExplicitType, resultEnum, attr => attr.Value); var type = EnumHelper.GetBoundValue(ExplicitType, resultEnum, attr => attr.Value);
if (type is Type enumBindType && !(enumBindType is null)) if (type is Type enumBindType && !(enumBindType is null))
{ {
var value = nodeModel.Env.IOC.Instantiate(enumBindType); var value = nodeModel.Env.IOC.CreateTempObject(enumBindType);
return value; return value;
} }
} }

View File

@@ -145,7 +145,7 @@ namespace Serein.Library.Web
return false; // 没有对应的处理配置 return false; // 没有对应的处理配置
} }
ControllerBase controllerInstance = (ControllerBase)SereinIOC.Instantiate(controllerType); ControllerBase controllerInstance = (ControllerBase)SereinIOC.CreateTempObject(controllerType);
if (controllerInstance is null) if (controllerInstance is null)
{ {

View File

@@ -15,56 +15,6 @@ namespace Serein.Library.Network.WebSocketCommunication.Handle
{ {
} }
/// <summary>
/// 消息ID生成器
/// </summary>
public class MsgIdHelper
{
private static readonly long _epoch = new DateTime(2023, 1, 1).Ticks; // 自定义起始时间
private static long _lastTimestamp = -1L; // 上一次生成 ID 的时间戳
private static long _sequence = 0L; // 序列号
/// <summary>
/// 获取新的ID
/// </summary>
public static long NewId => GenerateId();
/// <summary>
/// 生成消息ID
/// </summary>
/// <returns></returns>
public static long GenerateId()
{
long timestamp = DateTime.UtcNow.Ticks;
// 如果时间戳是一样的,递增序列号
if (timestamp == _lastTimestamp)
{
// 使用原子操作增加序列号
_sequence = Interlocked.Increment(ref _sequence);
if (_sequence > 999999) // 序列号最大值6位
{
// 等待下一毫秒
while (timestamp <= _lastTimestamp)
{
timestamp = DateTime.UtcNow.Ticks;
}
}
}
else
{
_sequence = 0; // 重置序列号
}
_lastTimestamp = timestamp;
// 生成 ID时间戳和序列号拼接
return (timestamp - _epoch) * 1000 + _sequence; // 返回 ID
}
}
} }

View File

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Serein.Library.Utils
{
/// <summary>
/// 消息ID生成器
/// </summary>
public class MsgIdHelper
{
private static readonly long _epoch = new DateTime(2023, 1, 1).Ticks; // 自定义起始时间
private static long _lastTimestamp = -1L; // 上一次生成 ID 的时间戳
private static long _sequence = 0L; // 序列号
/// <summary>
/// 获取新的ID
/// </summary>
public static long NewId => GenerateId();
/// <summary>
/// 生成消息ID
/// </summary>
/// <returns></returns>
public static long GenerateId()
{
long timestamp = DateTime.UtcNow.Ticks;
// 如果时间戳是一样的,递增序列号
if (timestamp == _lastTimestamp)
{
// 使用原子操作增加序列号
_sequence = Interlocked.Increment(ref _sequence);
if (_sequence > 999999) // 序列号最大值6位
{
// 等待下一毫秒
while (timestamp <= _lastTimestamp)
{
timestamp = DateTime.UtcNow.Ticks;
}
}
}
else
{
_sequence = 0; // 重置序列号
}
_lastTimestamp = timestamp;
// 生成 ID时间戳和序列号拼接
return (timestamp - _epoch) * 1000 + _sequence; // 返回 ID
}
}
}

View File

@@ -1,4 +1,5 @@
using Serein.Library.Api; using Microsoft.CodeAnalysis.CSharp.Syntax;
using Serein.Library.Api;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
@@ -13,10 +14,8 @@ namespace Serein.Library.Utils
/// <summary> /// <summary>
/// IOC管理容器 /// IOC管理容器
/// </summary> /// </summary>
public class SereinIOC/* : ISereinIOC*/ public class SereinIOC : ISereinIOC
{ {
/// <summary> /// <summary>
/// 类型集合,暂放待实例化的类型,完成实例化之后移除 /// 类型集合,暂放待实例化的类型,完成实例化之后移除
/// </summary> /// </summary>
@@ -26,7 +25,11 @@ namespace Serein.Library.Utils
/// 已完成注入的实例集合 /// 已完成注入的实例集合
/// </summary> /// </summary>
private readonly ConcurrentDictionary<string, object> _dependencies; private readonly ConcurrentDictionary<string, object> _dependencies;
private readonly ConcurrentDictionary<string, object[]> _registerParameterss;
/// <summary>
/// 能够获取类型实例的闭包
/// </summary>
private readonly ConcurrentDictionary<string, Func<object>> _registerCallback;
/// <summary> /// <summary>
/// 未完成注入的实例集合。 /// 未完成注入的实例集合。
@@ -35,107 +38,147 @@ namespace Serein.Library.Utils
/// </summary> /// </summary>
private readonly ConcurrentDictionary<string, List<(object,PropertyInfo)>> _unfinishedDependencies; private readonly ConcurrentDictionary<string, List<(object,PropertyInfo)>> _unfinishedDependencies;
/// <summary>
/// IOC容器成功创建了类型
/// </summary>
public event IOCMembersChangedHandler OnIOCMembersChanged; public event IOCMembersChangedHandler OnIOCMembersChanged;
/// <summary>
/// 一个轻量级的IOC容器
/// </summary>
public SereinIOC() public SereinIOC()
{ {
_dependencies = new ConcurrentDictionary<string, object>(); _dependencies = new ConcurrentDictionary<string, object>();
_registerParameterss = new ConcurrentDictionary<string, object[]>(); _registerCallback = new ConcurrentDictionary<string, Func<object>>();
_typeMappings = new ConcurrentDictionary<string, Type>(); _typeMappings = new ConcurrentDictionary<string, Type>();
_unfinishedDependencies = new ConcurrentDictionary<string, List<(object, PropertyInfo)>>(); _unfinishedDependencies = new ConcurrentDictionary<string, List<(object, PropertyInfo)>>();
} }
#region #region
/// <summary>
/// 向容器注册类型
/// </summary>
/// <param name="type">需要注册的类型</param>
/// <returns></returns>
public ISereinIOC Register(Type type)
{
RegisterType(type.FullName, type);
return this;
}
/// <summary> /// <summary>
/// 注册类型 /// 向容器注册类型,并指定其实例成员
/// </summary> /// </summary>
/// <param name="type">目标类型</param> /// <param name="type">需要注册的类型</param>
/// <param name="parameters">参数</param> /// <param name="getInstance">获取实例的回调函数</param>
public bool Register(Type type, params object[] parameters) /// <returns></returns>
public ISereinIOC Register(Type type, Func<object> getInstance)
{ {
return RegisterType(type?.FullName, type, parameters); RegisterType(type.FullName, type, getInstance);
return this;
} }
/// <summary> /// <summary>
/// 注册类型 /// 向容器注册类型,并指定其实例成员
/// </summary> /// </summary>
/// <param name="type">目标类型</param> /// <typeparam name="T">需要注册的类型</typeparam>
/// <param name="parameters">参数</param> /// <param name="getInstance">获取实例的回调函数</param>
public bool Register<T>(params object[] parameters) /// <returns></returns>
public ISereinIOC Register<T>(Func<T> getInstance)
{ {
var type = typeof(T); var type = typeof(T);
return RegisterType(type.FullName, type, parameters); 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>
/// 注册接口类型 /// 向容器注册接口类型,其实例成员由容器自动创建
/// </summary> /// </summary>
/// <param name="type">目标类型</param> /// <typeparam name="TService">接口类型</typeparam>
/// <param name="parameters">参数</param> /// <typeparam name="TImplementation">实现类类型</typeparam>
public bool Register<TService, TImplementation>(params object[] parameters) /// <returns></returns>
public ISereinIOC Register<TService, TImplementation>()
where TImplementation : TService where TImplementation : TService
{ {
return RegisterType(typeof(TService).FullName, typeof(TImplementation), parameters); RegisterType(typeof(TService).FullName, typeof(TImplementation));
return this;
} }
#endregion #endregion
#region
/// <summary> /// <summary>
/// 用于临时实例的创建不登记到IOC容器中依赖项注入失败时也不记录。 /// 用于临时实例的创建不登记到IOC容器中依赖项注入失败时也不记录。
/// </summary> /// </summary>
/// <param name="type"></param> /// <param name="type"></param>
/// <returns></returns> /// <returns></returns>
public object Instantiate(Type type) public object CreateTempObject(Type type)
{ {
var constructor = type.GetConstructors().First(); // 获取第一个构造函数 var ctors = GetConstructor(type); // 获取构造函数
var parameters = constructor.GetParameters(); // 获取参数列表 object instance = null;
var parameterValues = parameters.Select(param => ResolveDependency(param.ParameterType)).ToArray(); // 生成创建类型的入参参数 // 从入参最多的构造函数开始构建对象
var instance = Activator.CreateInstance(type, parameterValues); // 创建实例 foreach (var ctor in ctors)
if (instance != null)
{ {
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); // 完成创建后注入实例需要的特性依赖项 InjectDependencies(instance, false); // 完成创建后注入实例需要的特性依赖项
break;
}
if (instance == null)
{
throw new Exception($"无法为【{type}】类型创建实例");
} }
return instance; return instance;
} }
public T Instantiate<T>() /// <summary>
/// 用于临时实例的创建不登记到IOC容器中依赖项注入失败时也不记录。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T CreateTempObject<T>()
{ {
return (T)Instantiate(typeof(T)); return (T)CreateTempObject(typeof(T));
} }
#endregion
#region #region
/// <summary> /// <summary>
/// 指定key值注册一个已经实例化的实例对象并持久化储存 /// 尝试获取指定类型的示例
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="type"></param>
/// <param name="instance"></param> /// <returns></returns>
public bool RegisterInstance(string key, object instance)
{
return RegisterPersistennceInstance(key, instance);
}
/// <summary>
/// 指定key值注册一个已经实例化的实例对象并持久化储存
/// </summary>
/// <param name="key"></param>
/// <param name="instance"></param>
public bool RegisterPersistennceInstance(string key, object instance)
{
// 不存在时才允许创建
if (_dependencies.ContainsKey(key))
{
return false;
}
_dependencies.TryAdd(key, instance);
//if (needInjectProperty)
//{
// InjectDependencies(instance); // 注入实例需要的依赖项
//}
//InjectUnfinishedDependencies(key, instance); // 检查是否存在其它实例需要该类型
OnIOCMembersChanged?.Invoke(new IOCMembersChangedEventArgs(key, instance));
return true;
}
public object Get(Type type) public object Get(Type type)
{ {
var instance = Get(type.FullName); var instance = Get(type.FullName);
@@ -147,14 +190,15 @@ namespace Serein.Library.Utils
return Get(type.FullName); return Get(type.FullName);
} }
/// <summary>
/// 尝试获取指定类型的示例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Get<T>() public T Get<T>()
{ {
return (T)Get(typeof(T).FullName); return (T)Get(typeof(T).FullName);
} }
public T Get<T>(string name)
{
return (T)Get(name);
}
private object Get(string name) private object Get(string name)
{ {
if (!_dependencies.TryGetValue(name, out object value)) if (!_dependencies.TryGetValue(name, out object value))
@@ -172,7 +216,7 @@ namespace Serein.Library.Utils
/// 清空容器对象 /// 清空容器对象
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public bool Reset() public ISereinIOC Reset()
{ {
// 检查是否存在非托管资源 // 检查是否存在非托管资源
foreach (var instancei in _dependencies.Values) foreach (var instancei in _dependencies.Values)
@@ -182,13 +226,14 @@ namespace Serein.Library.Utils
disposable?.Dispose(); disposable?.Dispose();
} }
} }
_registerParameterss?.Clear(); _registerCallback?.Clear();
_unfinishedDependencies?.Clear(); _unfinishedDependencies?.Clear();
_typeMappings?.Clear(); _typeMappings?.Clear();
_dependencies?.Clear(); _dependencies?.Clear();
return true; return this;
} }
public class TypeKeyValue
class TypeKeyValue
{ {
public TypeKeyValue(string name, Type type) public TypeKeyValue(string name, Type type)
{ {
@@ -198,19 +243,19 @@ namespace Serein.Library.Utils
public string Name { get; set; } public string Name { get; set; }
public Type Type { get; set; } public Type Type { get; set; }
} }
private const string FlowBaseClassName = "@FlowBaseClass"; private const string FlowBaseClassName = "@LibraryRootNode";
/// <summary>
public Dictionary<string, List<string>> BuildDependencyTree() /// 构建依赖关系树
/// </summary>
/// <returns></returns>
private Dictionary<string, List<string>> BuildDependencyTree()
{ {
var dependencyMap = new Dictionary<string, HashSet<string>>(); var dependencyMap = new Dictionary<string, HashSet<string>>();
dependencyMap[FlowBaseClassName] = new HashSet<string>(); dependencyMap[FlowBaseClassName] = new HashSet<string>();
foreach (var typeMapping in _typeMappings) foreach (var typeMapping in _typeMappings)
{ {
//var constructor = GetConstructorWithMostParameters(typeMapping.Value); // 获取参数最多的构造函数 var constructors = GetConstructor(typeMapping.Value); // 获取构造函数
var constructors = GetConstructor(typeMapping.Value); // 获取参数最多的构造函数
foreach (var constructor in constructors) foreach (var constructor in constructors)
{ {
if (constructor != null) if (constructor != null)
@@ -254,22 +299,22 @@ namespace Serein.Library.Utils
var tmp = dependencyMap.ToDictionary(key => key.Key, value => value.Value.ToList()); var tmp = dependencyMap.ToDictionary(key => key.Key, value => value.Value.ToList());
return tmp; return tmp;
} }
// 获取参数最多的构造函数
private ConstructorInfo GetConstructorWithMostParameters(Type type) /// <summary>
{ /// 获取类型的获取所有构造函数
return type.GetConstructors() /// </summary>
.OrderByDescending(c => c.GetParameters().Length) /// <param name="type"></param>
.FirstOrDefault(); /// <returns></returns>
}
// 获取所有构造函数
private ConstructorInfo[] GetConstructor(Type type) private ConstructorInfo[] GetConstructor(Type type)
{ {
return type.GetConstructors() return type.GetConstructors().OrderByDescending(ctor => ctor.GetParameters().Length).ToArray();
//.OrderByDescending(c => c.GetParameters().Length)
.OrderByDescending(ctor => ctor.GetParameters().Length).ToArray();
} }
// 生成顺序 /// <summary>
/// 创建示例的生成顺序
/// </summary>
/// <param name="dependencyMap"></param>
/// <returns></returns>
public List<string> GetCreationOrder(Dictionary<string, List<string>> dependencyMap) public List<string> GetCreationOrder(Dictionary<string, List<string>> dependencyMap)
{ {
var graph = new Dictionary<string, List<string>>(); var graph = new Dictionary<string, List<string>>();
@@ -338,19 +383,24 @@ namespace Serein.Library.Utils
return creationOrder; return creationOrder;
} }
public object CreateInstance(string typeName) /// <summary>
/// 创建实例对象
/// </summary>
/// <param name="typeName"></param>
/// <returns></returns>
private object CreateInstance(string typeName)
{ {
if (!_typeMappings.TryGetValue(typeName, out var type)) if (!_typeMappings.TryGetValue(typeName, out var type)) // 获取类型
{ {
return null; return null;
} }
if (_dependencies.TryGetValue(typeName, out var instance)) if (_dependencies.TryGetValue(typeName, out var instance)) // 获取实例
{ {
return instance; return instance;
} }
if (_registerParameterss.TryGetValue(typeName,out var @params)) if (_registerCallback.TryGetValue(typeName,out var obj))
{ {
instance = Activator.CreateInstance(type, @params); instance = obj;
} }
// 字符串、值类型,抽象类型,暂时不支持自动创建 // 字符串、值类型,抽象类型,暂时不支持自动创建
@@ -410,8 +460,11 @@ namespace Serein.Library.Utils
return instance; return instance;
} }
/// <summary>
public bool Build() /// 绑定所有类型,生成示例
/// </summary>
/// <returns></returns>
public ISereinIOC Build()
{ {
var dependencyTree = BuildDependencyTree(); var dependencyTree = BuildDependencyTree();
var creationOrder = GetCreationOrder(dependencyTree); var creationOrder = GetCreationOrder(dependencyTree);
@@ -435,29 +488,29 @@ namespace Serein.Library.Utils
OnIOCMembersChanged.Invoke(new IOCMembersChangedEventArgs(typeName, value)); OnIOCMembersChanged.Invoke(new IOCMembersChangedEventArgs(typeName, value));
} }
_typeMappings.Clear(); _typeMappings.Clear();
return true; return this;
} }
#endregion #endregion
#region #region
/// <summary> /// <summary>
/// 注册类型 /// 注册类型
/// </summary> /// </summary>
/// <param name="typeFull"></param> /// <param name="typeFull">类型名称</param>
/// <param name="type"></param> /// <param name="type">要注册的类型</param>
private bool RegisterType(string typeFull, Type type, params object[] parameters) /// <param name="getInstance">获取实例的闭包</param>
private bool RegisterType(string typeFull, Type type, Func<object> getInstance = null)
{ {
if (!_typeMappings.ContainsKey(typeFull)) if (!_typeMappings.ContainsKey(typeFull))
{ {
_typeMappings[typeFull] = type; _typeMappings[typeFull] = type;
if(parameters.Length > 0) if(getInstance != null)
{ {
_registerParameterss[typeFull] = parameters; _registerCallback[typeFull] = getInstance;
} }
return true; return true;
} }
@@ -467,20 +520,11 @@ namespace Serein.Library.Utils
} }
} }
private object ResolveDependency(Type parameterType)
{
var obj = Get(parameterType);
if (obj is null)
{
throw new InvalidOperationException($"构造函数注入时类型[{parameterType}]不存在实例");
}
return obj;
}
/// <summary> /// <summary>
/// 如果其它实例想要该对象时,注入过去 /// 如果其它实例想要该对象时,注入过去
/// </summary> /// </summary>
private void InjectUnfinishedDependencies(string key,object instance) private void InjectUnfinishedDependencies(string key, object instance)
{ {
if (_unfinishedDependencies.TryGetValue(key, out var unfinishedPropertyList)) if (_unfinishedDependencies.TryGetValue(key, out var unfinishedPropertyList))
{ {
@@ -534,14 +578,13 @@ namespace Serein.Library.Utils
} }
public void Run<T>(Action<T> action) private void Run<T>(Action<T> action)
{ {
var service = Get<T>(); var service = Get<T>();
action(service); action(service);
} }
public void Run<T1, T2>(Action<T1, T2> action) private void Run<T1, T2>(Action<T1, T2> action)
{ {
var service1 = Get<T1>(); var service1 = Get<T1>();
var service2 = Get<T2>(); var service2 = Get<T2>();
@@ -549,7 +592,7 @@ namespace Serein.Library.Utils
action(service1, service2); action(service1, service2);
} }
public void Run<T1, T2, T3>(Action<T1, T2, T3> action) private void Run<T1, T2, T3>(Action<T1, T2, T3> action)
{ {
var service1 = Get<T1>(); var service1 = Get<T1>();
var service2 = Get<T2>(); var service2 = Get<T2>();
@@ -557,7 +600,7 @@ namespace Serein.Library.Utils
action(service1, service2, service3); action(service1, service2, service3);
} }
public void Run<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action) private void Run<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action)
{ {
var service1 = Get<T1>(); var service1 = Get<T1>();
var service2 = Get<T2>(); var service2 = Get<T2>();
@@ -566,7 +609,7 @@ namespace Serein.Library.Utils
action(service1, service2, service3, service4); action(service1, service2, service3, service4);
} }
public void Run<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> action) private void Run<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> action)
{ {
var service1 = Get<T1>(); var service1 = Get<T1>();
var service2 = Get<T2>(); var service2 = Get<T2>();
@@ -576,7 +619,7 @@ namespace Serein.Library.Utils
action(service1, service2, service3, service4, service5); action(service1, service2, service3, service4, service5);
} }
public void Run<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> action) private void Run<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> action)
{ {
var service1 = Get<T1>(); var service1 = Get<T1>();
var service2 = Get<T2>(); var service2 = Get<T2>();
@@ -587,7 +630,7 @@ namespace Serein.Library.Utils
action(service1, service2, service3, service4, service5, service6); action(service1, service2, service3, service4, service5, service6);
} }
public void Run<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> action) private void Run<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> action)
{ {
var service1 = Get<T1>(); var service1 = Get<T1>();
var service2 = Get<T2>(); var service2 = Get<T2>();
@@ -599,7 +642,7 @@ namespace Serein.Library.Utils
action(service1, service2, service3, service4, service5, service6, service7); action(service1, service2, service3, service4, service5, service6, service7);
} }
public void Run<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> action) private void Run<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
{ {
var service1 = Get<T1>(); var service1 = Get<T1>();
var service2 = Get<T2>(); var service2 = Get<T2>();

View File

@@ -21,7 +21,7 @@ namespace Net462DllTest
if (ViewModel is null) if (ViewModel is null)
{ {
SereinEnv.WriteLine(InfoType.INFO, "创建对象并注入依赖项"); SereinEnv.WriteLine(InfoType.INFO, "创建对象并注入依赖项");
ViewModel = env.IOC.Instantiate<FromWorkBenchViewModel>(); ViewModel = env.IOC.CreateTempObject<FromWorkBenchViewModel>();
} }
BindData(); BindData();
} }

View File

@@ -64,9 +64,9 @@ namespace Serein.NodeFlow.Env
#endregion #endregion
#region #region
PersistennceInstance.Add(typeof(FlowInterruptTool).FullName, new FlowInterruptTool()); // 缓存流程实例 PersistennceInstance.Add(typeof(FlowInterruptTool), new FlowInterruptTool()); // 缓存流程实例
PersistennceInstance.Add(typeof(IFlowEnvironment).FullName, (FlowEnvironment)this); // 缓存流程实例 PersistennceInstance.Add(typeof(IFlowEnvironment), (FlowEnvironment)this); // 缓存流程实例
PersistennceInstance.Add(typeof(ISereinIOC).FullName, this); // 缓存容器服务 PersistennceInstance.Add(typeof(ISereinIOC), this); // 缓存容器服务
ReRegisterPersistennceInstance(); ReRegisterPersistennceInstance();
@@ -293,7 +293,7 @@ namespace Serein.NodeFlow.Env
/// <summary> /// <summary>
/// 本地运行环境缓存的持久化实例 /// 本地运行环境缓存的持久化实例
/// </summary> /// </summary>
private Dictionary<string, object> PersistennceInstance { get; } = new Dictionary<string, object>(); private Dictionary<Type, object> PersistennceInstance { get; } = new Dictionary<Type, object>();
/// <summary> /// <summary>
/// 环境加载的节点集合 /// 环境加载的节点集合
@@ -1428,13 +1428,13 @@ namespace Serein.NodeFlow.Env
/// <param name="uiContextOperation"></param> /// <param name="uiContextOperation"></param>
public void SetUIContextOperation(UIContextOperation uiContextOperation) public void SetUIContextOperation(UIContextOperation uiContextOperation)
{ {
this.UIContextOperation = uiContextOperation; if(uiContextOperation is not null)
var fullName = typeof(UIContextOperation).FullName;
if (!string.IsNullOrEmpty(fullName))
{ {
PersistennceInstance[fullName] = uiContextOperation; // 缓存封装好的UI线程上下文 this.UIContextOperation = uiContextOperation;
PersistennceInstance[typeof(UIContextOperation)] = uiContextOperation; // 缓存封装好的UI线程上下文
} }
} }
@@ -2150,7 +2150,7 @@ namespace Serein.NodeFlow.Env
{ {
foreach (var kvp in PersistennceInstance) foreach (var kvp in PersistennceInstance)
{ {
IOC.RegisterPersistennceInstance(kvp.Key, kvp.Value); IOC.Register(kvp.Key, () => kvp.Value);
} }
} }
} }
@@ -2182,21 +2182,32 @@ namespace Serein.NodeFlow.Env
return this; return this;
} }
ISereinIOC ISereinIOC.Register(Type type, params object[] parameters) ISereinIOC ISereinIOC.Register(Type type)
{ {
sereinIOC.Register(type, parameters); sereinIOC.Register(type);
return this;
}
ISereinIOC ISereinIOC.Register(Type type, Func<object> getInstance)
{
sereinIOC.Register(type, getInstance);
return this; return this;
} }
ISereinIOC ISereinIOC.Register<T>(params object[] parameters) ISereinIOC ISereinIOC.Register<T>(Func<T> getInstance)
{ {
sereinIOC.Register<T>(parameters); sereinIOC.Register<T>(getInstance);
return this; return this;
} }
ISereinIOC ISereinIOC.Register<TService, TImplementation>(params object[] parameters) ISereinIOC ISereinIOC.Register<TService, TImplementation>()
{ {
sereinIOC.Register<TService, TImplementation>(parameters); sereinIOC.Register<TService, TImplementation>();
return this;
}
ISereinIOC ISereinIOC.Register<TService, TImplementation>(Func<TService> getInstance)
{
sereinIOC.Register<TService, TImplementation>(getInstance);
return this; return this;
} }
@@ -2226,11 +2237,6 @@ namespace Serein.NodeFlow.Env
//} //}
bool ISereinIOC.RegisterPersistennceInstance(string key, object instance)
{
PersistennceInstance.TryAdd(key, instance); // 记录需要持久化的实例
return sereinIOC.RegisterPersistennceInstance(key, instance);
}
//bool ISereinIOC.RegisterInstance(string key, object instance) //bool ISereinIOC.RegisterInstance(string key, object instance)
//{ //{
@@ -2238,13 +2244,13 @@ namespace Serein.NodeFlow.Env
//} //}
object ISereinIOC.Instantiate(Type type) object ISereinIOC.CreateTempObject(Type type)
{ {
return sereinIOC.Instantiate(type); return sereinIOC.CreateTempObject(type);
} }
T ISereinIOC.Instantiate<T>() T ISereinIOC.CreateTempObject<T>()
{ {
return sereinIOC.Instantiate<T>(); return sereinIOC.CreateTempObject<T>();
} }
ISereinIOC ISereinIOC.Build() ISereinIOC ISereinIOC.Build()
{ {
@@ -2252,53 +2258,7 @@ namespace Serein.NodeFlow.Env
return this; return this;
} }
ISereinIOC ISereinIOC.Run<T>(Action<T> action)
{
sereinIOC.Run(action);
return this;
}
ISereinIOC ISereinIOC.Run<T1, T2>(Action<T1, T2> action)
{
sereinIOC.Run(action);
return this;
}
ISereinIOC ISereinIOC.Run<T1, T2, T3>(Action<T1, T2, T3> action)
{
sereinIOC.Run(action);
return this;
}
ISereinIOC ISereinIOC.Run<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action)
{
sereinIOC.Run(action);
return this;
}
ISereinIOC ISereinIOC.Run<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> action)
{
sereinIOC.Run(action);
return this;
}
ISereinIOC ISereinIOC.Run<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> action)
{
sereinIOC.Run(action);
return this;
}
ISereinIOC ISereinIOC.Run<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> action)
{
sereinIOC.Run(action);
return this;
}
ISereinIOC ISereinIOC.Run<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
{
sereinIOC.Run(action);
return this;
}
#endregion #endregion

View File

@@ -642,11 +642,6 @@ namespace Serein.NodeFlow.Env
return IOC.Build(); return IOC.Build();
} }
public bool RegisterPersistennceInstance(string key, object instance)
{
return IOC.RegisterPersistennceInstance(key, instance);
}
//public bool RegisterInstance(string key, object instance) //public bool RegisterInstance(string key, object instance)
//{ //{
// return IOC.RegisterInstance(key, instance); // return IOC.RegisterInstance(key, instance);
@@ -667,29 +662,39 @@ namespace Serein.NodeFlow.Env
// return IOC.Get<T>(key); // return IOC.Get<T>(key);
//} //}
public object Instantiate(Type type) public object CreateTempObject(Type type)
{ {
return IOC.Instantiate(type); return IOC.CreateTempObject(type);
} }
public T Instantiate<T>() public T CreateTempObject<T>()
{ {
return IOC.Instantiate<T>(); return IOC.CreateTempObject<T>();
} }
public ISereinIOC Register(Type type, params object[] parameters) public ISereinIOC Register(Type type)
{ {
return IOC.Register(type, parameters); return IOC.Register(type);
} }
public ISereinIOC Register<T>(params object[] parameters) public ISereinIOC Register(Type type, Func<object> getInstance)
{ {
return IOC.Register<T>(parameters); return IOC.Register(type, getInstance);
} }
public ISereinIOC Register<TService, TImplementation>(params object[] parameters) where TImplementation : TService public ISereinIOC Register<T>(Func<T> getInstance)
{ {
return IOC.Register<TService, TImplementation>(parameters); return IOC.Register<T>(getInstance);
}
public ISereinIOC Register<TService, TImplementation>(Func<TService> getInstance) where TImplementation : TService
{
return IOC.Register<TService, TImplementation>(getInstance);
}
public ISereinIOC Register<TService, TImplementation>() where TImplementation : TService
{
return IOC.Register<TService, TImplementation>();
} }
public ISereinIOC Reset() public ISereinIOC Reset()
@@ -697,47 +702,6 @@ namespace Serein.NodeFlow.Env
return IOC.Reset(); return IOC.Reset();
} }
public ISereinIOC Run<T>(Action<T> action)
{
return IOC.Run(action);
}
public ISereinIOC Run<T1, T2>(Action<T1, T2> action)
{
return IOC.Run(action);
}
public ISereinIOC Run<T1, T2, T3>(Action<T1, T2, T3> action)
{
return IOC.Run(action);
}
public ISereinIOC Run<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action)
{
return IOC.Run(action);
}
public ISereinIOC Run<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> action)
{
return IOC.Run(action);
}
public ISereinIOC Run<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> action)
{
return IOC.Run(action);
}
public ISereinIOC Run<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> action)
{
return IOC.Run(action);
}
public ISereinIOC Run<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
{
return IOC.Run(action);
}
#endregion #endregion

View File

@@ -201,7 +201,8 @@ namespace Serein.NodeFlow
var pool = WorkOptions.FlowContextPool; var pool = WorkOptions.FlowContextPool;
var ioc = WorkOptions.Environment.IOC; var ioc = WorkOptions.Environment.IOC;
ioc.Run<FlowInterruptTool>(fit => fit.CancelAllTrigger());// 取消所有中断 var fit = ioc.Get<FlowInterruptTool>();
fit.CancelAllTrigger(); // 取消所有中断
foreach (var md in mds) // 结束时 foreach (var md in mds) // 结束时
{ {
if (!env.TryGetDelegateDetails(md.AssemblyName, md.MethodName, out var dd)) // 流程运行初始化 if (!env.TryGetDelegateDetails(md.AssemblyName, md.MethodName, out var dd)) // 流程运行初始化