feat(cordis): 接入上下文组合与模组事务热替换
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ShrinkCommand
|
||||
{
|
||||
public static class ShrinkCommandRegHelper
|
||||
{
|
||||
public static void RegisterStaticCommands(ShrinkCommandService service)
|
||||
{
|
||||
if (service == null)
|
||||
throw new ArgumentNullException(nameof(service));
|
||||
|
||||
RegisterStaticCommandSubscriberTypes(service, ShrinkCommandGeneratedRegistry.GetStaticSubscriberTypes());
|
||||
}
|
||||
|
||||
public static void RegisterCommands(ShrinkCommandService service, object? target)
|
||||
{
|
||||
if (service == null)
|
||||
throw new ArgumentNullException(nameof(service));
|
||||
|
||||
RegisterCommandsInternal(service, target);
|
||||
}
|
||||
|
||||
public static void RegisterStaticCommandSubscriberTypes(
|
||||
ShrinkCommandService service,
|
||||
IEnumerable<Type> subscriberTypes)
|
||||
{
|
||||
if (service == null)
|
||||
throw new ArgumentNullException(nameof(service));
|
||||
if (subscriberTypes == null)
|
||||
throw new ArgumentNullException(nameof(subscriberTypes));
|
||||
|
||||
foreach (var type in subscriberTypes)
|
||||
{
|
||||
if (type == null || type.GetCustomAttribute<ShrinkCommandSubscriberAttribute>(false) == null)
|
||||
continue;
|
||||
|
||||
ScanMethodsAndRegister(service, null, type,
|
||||
type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegisterCommandsInternal(ShrinkCommandService service, object? target)
|
||||
{
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
var ownerType = target.GetType();
|
||||
if (ownerType.GetCustomAttribute<ShrinkCommandSubscriberAttribute>(false) == null)
|
||||
return;
|
||||
|
||||
ScanMethodsAndRegister(service, target, ownerType,
|
||||
ownerType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
|
||||
}
|
||||
|
||||
private static void ScanMethodsAndRegister(
|
||||
ShrinkCommandService service,
|
||||
object? target,
|
||||
Type ownerType,
|
||||
MethodInfo[] methods)
|
||||
{
|
||||
foreach (var method in methods)
|
||||
{
|
||||
if (target != null && method.IsStatic)
|
||||
continue;
|
||||
|
||||
var attributes = method.GetCustomAttributes(typeof(ShrinkCommandAttribute), false)
|
||||
.Cast<ShrinkCommandAttribute>()
|
||||
.ToArray();
|
||||
if (attributes.Length == 0)
|
||||
continue;
|
||||
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
try
|
||||
{
|
||||
service.RegisterCommand(new ShrinkCommandRegistration
|
||||
{
|
||||
Path = attribute.Path,
|
||||
Aliases = attribute.Aliases ?? Array.Empty<string>(),
|
||||
Description = attribute.Description,
|
||||
Permission = attribute.Permission,
|
||||
SourceKind = attribute.SourceKind,
|
||||
Hidden = attribute.Hidden,
|
||||
Handler = ShrinkCommandMethodAdapter.BuildHandler(target, method,
|
||||
ParseArgumentNames(attribute.Path))
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ShrinkCommandLogger.Warn(
|
||||
$"[ShrinkCommand] Failed to register {ownerType.FullName}.{method.Name}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string[] ParseArgumentNames(string path)
|
||||
{
|
||||
return path.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Where(token => token.Length >= 3 && token[0] == '<' && token[token.Length - 1] == '>')
|
||||
.Select(token =>
|
||||
{
|
||||
var name = token.Substring(1, token.Length - 2).Trim();
|
||||
if (name.EndsWith("...", StringComparison.Ordinal))
|
||||
name = name.Substring(0, name.Length - 3).Trim();
|
||||
return name;
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user