Files
serein-flow/Library/NodeAttribute.cs

198 lines
6.2 KiB
C#
Raw Normal View History

using System;
namespace Serein.Library
{
/// <summary>
2024-10-10 20:52:19 +08:00
/// <para>表示该属性为自动注入依赖项。</para>
/// <para>使用场景:构造函数中存在互相依赖的情况</para>
/// <para>例如ServiceA类构造函数中需要传入ServiceBServiceB类构造函数中也需要传入ServiceA</para>
/// <para>这种情况会导致流程启动时IOC容器无法注入构造函数并创建类型导致启动失败。</para>
/// <para>解决方法从ServiceA类的构造函数中移除ServiceB类型的入参将该类型更改为公开可见的可写属性成员ServiceB serviceB{get;set;},并在该属性上标记[AutoInjection]特性</para>
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public sealed class AutoInjectionAttribute : Attribute
{
}
2024-09-28 23:55:19 +08:00
/// <summary>
/// 注册顺序
/// </summary>
public enum RegisterSequence
{ /// <summary>
/// 不自动初始化
/// </summary>
Node,
/// <summary>
/// 初始化后
/// </summary>
FlowInit,
/// <summary>
/// 加载后
/// </summary>
FlowLoading,
}
2024-10-10 20:52:19 +08:00
2024-09-28 23:55:19 +08:00
/// <summary>
2024-10-10 20:52:19 +08:00
/// <para>启动流程时会将标记了该特性的类自动注册到IOC容器中从而无需手动进行注册绑定。</para>
/// <para>流程启动后IOC容器会进行5次注册绑定。</para>
/// <para>第1次注册绑定初始化所有节点所属的类[DynamicFlow]标记的类)。</para>
/// <para>第2次注册绑定※初始化所有[AutoRegister(Class=FlowInit)]的类。</para>
/// <para>第3次注册绑定调用所有Init节点后进行注册绑定。</para>
/// <para>第4次注册绑定※初始化所有[AutoRegister(Class=FlowLoading)]的类</para>
/// <para>第5次注册绑定调用所有Load节点后进行注册绑定。</para>
/// <para>需要注意的是在第1次进行注册绑定的过程中如果类的构造函数存在入参那么也会将入参自动创建实例并托管到IOC容器中。</para>
2024-09-28 23:55:19 +08:00
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class AutoRegisterAttribute : Attribute
{
public AutoRegisterAttribute(RegisterSequence Class = RegisterSequence.FlowInit)
{
this.Class = Class;
}
public RegisterSequence Class ;
}
/// <summary>
2024-10-10 20:52:19 +08:00
/// <para>表示该类中存在节点信息</para>
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class DynamicFlowAttribute : Attribute
{
2024-10-07 15:15:18 +08:00
public DynamicFlowAttribute(string name = "",bool scan = true)
{
2024-10-07 15:15:18 +08:00
Name = name;
Scan = scan;
}
2024-10-10 20:52:19 +08:00
/// <summary>
/// 补充名称,不影响运行流程
/// </summary>
2024-10-07 15:15:18 +08:00
public string Name { get; set; }
2024-10-10 20:52:19 +08:00
/// <summary>
/// 如果设置为false将忽略该类
/// </summary>
public bool Scan { get; set; } = true;
}
/// <summary>
2024-10-10 20:52:19 +08:00
/// <para>表示该方法将会生成节点,或是加入到流程运行中</para>
/// <para>如果是Task类型的返回值将会自动进行等待</para>
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NodeActionAttribute : Attribute
{
public NodeActionAttribute(NodeType methodDynamicType,
string methodTips = "",
bool scan = true,
string lockName = "")
{
Scan = scan;
MethodDynamicType = methodDynamicType;
2024-10-28 15:21:08 +08:00
AnotherName = methodTips;
LockName = lockName;
}
2024-10-10 20:52:19 +08:00
/// <summary>
/// 如果设置为false时将不会生成节点信息
/// </summary>
public bool Scan;
2024-10-10 20:52:19 +08:00
/// <summary>
/// 类似于注释的效果
/// </summary>
2024-10-28 15:21:08 +08:00
public string AnotherName;
2024-10-10 20:52:19 +08:00
/// <summary>
/// 标记节点行为
/// </summary>
public NodeType MethodDynamicType;
2024-10-10 20:52:19 +08:00
/// <summary>
/// 暂无意义
/// </summary>
public string LockName;
}
2024-09-25 22:20:23 +08:00
/// <summary>
/// 节点参数设置
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class NodeParamAttribute : Attribute
{
/// <summary>
/// 显示名称
/// </summary>
public string Name;
2024-09-25 22:20:23 +08:00
/// <summary>
/// 是否显式设置(此设置对于有入参默认值的参数无效)
/// </summary>
public bool IsExplicit;
}
2024-09-25 22:20:23 +08:00
2024-10-07 15:15:18 +08:00
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
2024-09-25 22:20:23 +08:00
public class BindValueAttribute : Attribute
{
public object Value { get; }
public BindValueAttribute(object value)
{
Value = value;
}
}
2024-09-27 10:30:19 +08:00
/// <summary>
/// 枚举值转换器要求枚举项标记的BindValueAttribute特性与搭配的参数类型一致否则参数不会传入
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public class EnumTypeConvertorAttribute : Attribute
{
public Type EnumType { get; }
public EnumTypeConvertorAttribute(Type @enum)
{
if (@enum.IsEnum)
{
EnumType = @enum;
}
else
{
throw new ArgumentException("需要枚举类型");
}
}
}
2024-09-28 23:55:19 +08:00
/// <summary>
/// 绑定转换器
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public class BindConvertorAttribute : Attribute
2024-09-25 22:20:23 +08:00
{
2024-09-28 23:55:19 +08:00
public Type EnumType { get; }
public Type ConvertorType { get; }
2024-09-25 22:20:23 +08:00
2024-09-28 23:55:19 +08:00
public BindConvertorAttribute(Type @enum, Type convertor)
2024-09-25 22:20:23 +08:00
{
2024-09-28 23:55:19 +08:00
this.EnumType = @enum;
this.ConvertorType = convertor;
2024-09-25 22:20:23 +08:00
}
}
2024-09-28 23:55:19 +08:00
/// <summary>
/// 枚举转换器接口
/// </summary>
/// <typeparam name="TEnum"></typeparam>
/// <typeparam name="TValue"></typeparam>
public interface IEnumConvertor<TEnum, TValue>
{
TValue Convertor(TEnum e);
}
}