-
Notifications
You must be signed in to change notification settings - Fork 1
CSharp Plugins
雪绫 edited this page Aug 25, 2026
·
4 revisions
当前插件只有 C#/.NET 程序集入口。入口不是某个实现接口的类,而是程序集中的 [Mixin] 类型集合。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
<AssemblyName>Example.Plugin</AssemblyName>
</PropertyGroup>
<ItemGroup>
<Reference Include="PCL.Core">
<HintPath>$(PclCorePath)</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
</Project>构建时传入明确路径:
dotnet build -c Release -p:PclCorePath=C:\PCL-Nex\PCL.Core.dll建议把 PclCorePath 作为 CI 参数,不要把某台开发机的绝对路径提交到公共项目。
可直接引用目标类型时使用 Type:
[Mixin(typeof(MyPublicTarget))]
internal static class MyTargetMixin
{
}目标是启动器内部类型或其他插件类型时使用完整名称:
[Mixin("PCL.FormMain", Priority = 1200)]
internal static class FormMainMixin
{
}Optional = true 表示该 Mixin 类型找不到目标或应用失败时记录警告并继续其他 Mixin:
[Mixin("Optional.Plugin.Type", Optional = true)]
internal static class OptionalIntegrationMixin
{
}操作 Attribute 的第一个参数是目标方法。只有一个同名重载时可只写名称:
[Inject("Run", At = MixinAt.Head)]
private static void BeforeRun()
{
}存在重载时,使用描述符或 ArgumentTypes:
[Inject("Run(System.Int32,System.String)", At = MixinAt.Return)]
private static void AfterRun(CallbackInfo<int> callback)
{
}[Inject("Run", ArgumentTypes = [typeof(int), typeof(string)], At = MixinAt.Return)]
private static void AfterRun(CallbackInfo<int> callback)
{
}构造函数使用 .ctor。开放泛型目标和 ref-return 边界注入当前不受支持。
推荐显式标注参数来源:
[Inject("Compute", At = MixinAt.Return, Cancellable = true)]
private static void AfterCompute(
[This] object instance,
[Arg(0)] int input,
[Return] ref int result,
MethodBase target,
CallbackInfo<int> callback)
{
if (input == 0)
callback.SetReturnValue(42);
}支持的绑定包括:
-
[This]:目标实例。 -
[Arg(index)]:目标方法参数;ref参数会尝试写回。 -
[Local(index)]:目标局部变量,需要同时设置LocalCapture.FailSoft或FailHard。 -
[Return]:当前返回值。 -
CallbackInfo/CallbackInfo<T>:取消方法或修改返回值。 -
MethodBase/MethodInfo:当前目标方法。 -
object[]:目标参数数组。
未标注参数还会尝试按目标参数名或实例类型绑定,但公共插件应优先使用显式标记,避免目标重构后产生歧义。
处理器可以是静态方法,也可以是实例方法。实例 Mixin 需要可由运行时创建的无参构造函数;运行时按目标实例维护 Mixin 实例。仅在确实需要 Shadow 字段或实例状态时使用实例 Mixin。
UI 类型和线程模型属于对应启动器平台的实现契约。插件可以在 Mixin 处理器中替换页面或修改启动器现有控件,但直接引用某个平台 UI 类型的程序集只能发布到该系统组;跨平台插件应把 UI 适配拆到平台专用程序集。处理器应在合适的目标方法和 UI 线程阶段操作真实对象。
需要注意:
- 在窗口构造前访问控件通常过早。
- 修改页面字段时应保持启动器后续代码期望的类型,或在原导航逻辑执行前恢复原对象。
- 事件处理器、计时器和资源由插件自己管理。
- 启用或禁用插件后应重启启动器。
完整 Attribute 和注入点见 Mixin API 参考 与 注入点与修改操作。