import{_ as h,c as p,a,e,b as i,d as l,w as t,r as k,o as d}from"./app-DlzW8FTI.js";const r={};function B(g,s){const n=k("RouteLink");return d(),p("div",null,[s[33]||(s[33]=a("h1",{id:"插件基础知识",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#插件基础知识"},[a("span",null,"插件基础知识")])],-1)),a("p",null,[s[1]||(s[1]=i("这里是在 ")),l(n,{to:"/dev/basics/"},{default:t(()=>s[0]||(s[0]=[i("ClassIsland 开发基础")])),_:1}),s[2]||(s[2]=i("的基础上,开发插件时还需要注意的事项。"))]),s[34]||(s[34]=a("h2",{id:"程序集隔离",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#程序集隔离"},[a("span",null,"程序集隔离")])],-1)),s[35]||(s[35]=a("p",null,[i("默认情况下,不同的插件会被加载到不同的程序集加载上下文("),a("a",{href:"https://learn.microsoft.com/zh-cn/dotnet/core/dependency-loading/understanding-assemblyloadcontext",target:"_blank",rel:"noopener noreferrer"},"AssemblyLoadContext"),i(")中。因此,不同插件间可以引入相同依赖库的不同版本,而不会产生冲突。")],-1)),a("p",null,[s[4]||(s[4]=i("如果要调用其它插件的类型,则需要将此插件")),l(n,{to:"/dev/plugins/dependency.html"},{default:t(()=>s[3]||(s[3]=[i("声明为依赖")])),_:1}),s[5]||(s[5]=i("。"))]),s[36]||(s[36]=e(`

注意

由于这个特性,当两个插件间包含具有相同名称的类型定义时,它们不是同一类型。当且仅当它们来自同一个 Assembly 实例时,它们的类型相同。详细请见此文章

资源引用

在插件中引用插件程序集内的资源时,需要使用绝对路径,例如:

avares://程序集名称/资源路径
avares://ExamplePlugin/Assets/Image.png

依赖注入

`,5)),a("p",null,[s[7]||(s[7]=i("在 ")),l(n,{to:"/dev/basics/dependency-injection.html#%E6%B3%A8%E5%86%8C%E6%9C%8D%E5%8A%A1"},{default:t(()=>s[6]||(s[6]=[i("依赖注入中的“注册服务”章节")])),_:1}),s[8]||(s[8]=i(" 所描述的基础上,插件需要在入口点的 ")),s[9]||(s[9]=a("code",null,"Initialize",-1)),s[10]||(s[10]=i(" 方法内完成相关注册操作。例如:"))]),s[37]||(s[37]=e(`
// ...
namespace ClassIsland.ExamplePlugin;

[PluginEntrance]
public class Plugin : PluginBase
{
    public override void Initialize(HostBuilderContext context, IServiceCollection services)
    {
        services.AddSettingsPage<HelloSettingsPage>();
        services.AddSingleton<MyService>();
    }
    // ...
}

访问 Application 对象

`,2)),a("p",null,[s[12]||(s[12]=i("ClassIsland 的应用程序类(App)基于封装后的 ")),s[13]||(s[13]=a("code",null,"Avalonia.Application",-1)),s[14]||(s[14]=i(" 类 ")),s[15]||(s[15]=a("code",null,"ClassIsland.Core.AppBase",-1)),s[16]||(s[16]=i("。AppBase 类在源 Application 的基础上,向插件暴露了一些")),l(n,{to:"/dev/events.html#%E5%BA%94%E7%94%A8%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E4%BA%8B%E4%BB%B6"},{default:t(()=>s[11]||(s[11]=[i("生命周期事件")])),_:1}),s[17]||(s[17]=i("和控制生命周期状态的方法。"))]),s[38]||(s[38]=a("p",null,[i("您可以通过 "),a("code",null,"ClassIsland.Core.AppBase"),i(" 的 "),a("code",null,"Current"),i(" 属性获取当前 Application 实例。")],-1)),a("p",null,[s[19]||(s[19]=i("下面的示例代码获取了应用程序对象,并订阅了 ")),l(n,{to:"/dev/events.html#%E5%BA%94%E7%94%A8%E5%90%AF%E5%8A%A8%E5%AE%8C%E6%88%90-appstarted"},{default:t(()=>s[18]||(s[18]=[i("AppStarted")])),_:1}),s[20]||(s[20]=i(" 事件,以在应用启动完成时在终端输出“App started!”。"))]),s[39]||(s[39]=e(`
var app = AppBase.Current;

app.AppStarted += (o, args) => Console.WriteLine("App started!");

您可以通过 AppBase.StopAppBase.Restart 方法停止或重启应用。下面的代码演示了如何重启 ClassIsland。

var app = AppBase.Current;

app.Restart();

保存插件配置

`,4)),a("p",null,[s[22]||(s[22]=i("ClassIsland 为每个插件创建了单独的配置目录,您可以将插件的各种配置文件和数据库等信息保存到插件的配置目录下。您可以通过访问")),l(n,{to:"/dev/plugins/plugin-base.html"},{default:t(()=>s[21]||(s[21]=[i("插件入口类")])),_:1}),s[23]||(s[23]=i("的")),s[24]||(s[24]=a("code",null,"PluginConfigFolder",-1)),s[25]||(s[25]=i("属性来获取插件配置目录的绝对路径。"))]),s[40]||(s[40]=e(`

您可以使用ClassIsland.Shared.Helpers.ConfigureFileHelper类中封装的方法便捷地读取和保存 JSON 格式的配置文件。例如:

Plugin.cs
using System.IO;
using ClassIsland.Core.Abstractions;
using ClassIsland.Core.Attributes;
using ClassIsland.Core.Extensions.Registry;
using ClassIsland.Shared.Helpers;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using PluginWithSettingsPage.Models;
using PluginWithSettingsPage.Views.SettingsPages;

namespace PluginWithSettingsPage;

[PluginEntrance]
public class Plugin : PluginBase
{
    public Settings Settings { get; set; } = new();

    public override void Initialize(HostBuilderContext context, IServiceCollection services)
    {
        Settings = ConfigureFileHelper.LoadConfig<Settings>(Path.Combine(PluginConfigFolder, "Settings.json"));  // 加载配置文件
        Settings.PropertyChanged += (sender, args) =>
        {
            ConfigureFileHelper.SaveConfig<Settings>(Path.Combine(PluginConfigFolder, "Settings.json"), Settings);  // 保存配置文件
        };
    }

    public override void OnShutdown()
    {
    }
}
`,2)),a("p",null,[s[28]||(s[28]=i("上面的的示例代码在")),l(n,{to:"/dev/plugins/plugin-base.html"},{default:t(()=>s[26]||(s[26]=[i("插件入口类")])),_:1}),s[29]||(s[29]=i("的")),l(n,{to:"/dev/plugins/plugin-base.html#%E5%88%9D%E5%A7%8B%E5%8C%96%E6%96%B9%E6%B3%95"},{default:t(()=>s[27]||(s[27]=[i("初始化方法")])),_:1}),s[30]||(s[30]=i("中获取了插件配置目录,然后读取插件配置,并订阅了配置对象的")),s[31]||(s[31]=a("code",null,"PropertyChanged",-1)),s[32]||(s[32]=i("属性,以在配置属性更改时保存配置文件。"))]),s[41]||(s[41]=a("div",{class:"hint-container warning"},[a("p",{class:"hint-container-title"},"注意"),a("p",null,[a("strong",null,"不要"),i("将配置文件保存在插件安装目录下,保存在插件安装目录下的配置文件不会被自动备份,并且可能会在插件更新时被删除。")])],-1))])}const y=h(r,[["render",B]]),o=JSON.parse('{"path":"/dev/plugins/basics.html","title":"插件基础知识","lang":"zh-CN","frontmatter":{"description":"插件基础知识 这里是在 的基础上,开发插件时还需要注意的事项。 程序集隔离 默认情况下,不同的插件会被加载到不同的程序集加载上下文(AssemblyLoadContext)中。因此,不同插件间可以引入相同依赖库的不同版本,而不会产生冲突。 如果要调用其它插件的类型,则需要将此插件。 注意 由于这个特性,当两个插件间包含具有相同名称的类型定义时,它们不是...","head":[["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"插件基础知识\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2026-01-17T09:27:32.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"ClassIsland 社区\\",\\"url\\":\\"https://classisland.tech\\"}]}"],["meta",{"property":"og:url","content":"https://docs.classisland.tech/dev/plugins/basics.html"}],["meta",{"property":"og:site_name","content":"ClassIsland 文档"}],["meta",{"property":"og:title","content":"插件基础知识"}],["meta",{"property":"og:description","content":"插件基础知识 这里是在 的基础上,开发插件时还需要注意的事项。 程序集隔离 默认情况下,不同的插件会被加载到不同的程序集加载上下文(AssemblyLoadContext)中。因此,不同插件间可以引入相同依赖库的不同版本,而不会产生冲突。 如果要调用其它插件的类型,则需要将此插件。 注意 由于这个特性,当两个插件间包含具有相同名称的类型定义时,它们不是..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2026-01-17T09:27:32.000Z"}],["meta",{"property":"article:modified_time","content":"2026-01-17T09:27:32.000Z"}],["link",{"rel":"alternate","hreflang":"en-us","href":"https://docs.classisland.tech/en-us/dev/plugins/basics.html"}]]},"git":{"createdTime":1721914539000,"updatedTime":1768642052000,"contributors":[{"name":"WRC","username":"WRC","email":"hello_wrc@outlook.com","commits":5,"url":"https://github.com/WRC"}]},"readingTime":{"minutes":2.71,"words":812},"filePathRelative":"dev/plugins/basics.md","autoDesc":true}');export{y as comp,o as data};