import{_ as o,c as r,a as s,e as d,d as n,b as e,w as a,r as p,o as g}from"./app-DlzW8FTI.js";const k="/assets/image-Cu9tLdqI.png",h={},u={class:"hint-container note"};function m(y,i){const t=p("RouteLink"),l=p("Mermaid");return g(),r("div",null,[i[22]||(i[22]=s("h1",{id:"插件依赖",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#插件依赖"},[s("span",null,"插件依赖")])],-1)),s("div",u,[i[3]||(i[3]=s("p",{class:"hint-container-title"},"注",-1)),s("p",null,[i[1]||(i[1]=e("在阅读本文前,建议先了解")),n(t,{to:"/dev/plugins/basics.html#%E7%A8%8B%E5%BA%8F%E9%9B%86%E9%9A%94%E7%A6%BB"},{default:a(()=>i[0]||(i[0]=[e("插件的程序集加载上下文隔离机制")])),_:1}),i[2]||(i[2]=e("。"))])]),i[23]||(i[23]=d('

在开发 ClassIsland 插件时,有时我们想要调用其它插件里的功能,或者与其它插件联动。这时我们可以通过在插件清单声明插件依赖,允许插件加载指定插件程序集上下文里的类型,实现调用其它插件的功能和插件间联动。被依赖的插件会先于依赖它的插件加载,以确保被依赖的插件已经初始化完成。
添加插件依赖需要在清单文件的 dependencies 列表中添加依赖的插件信息,例如:
manifest.yml
#...
dependencies:
- id: a.plugin
默认情况下,添加的依赖项是必须的。如果您希望依赖项可选,可在对应的插件信息中设置 isRequired 为 false:
manifest.yml
#...
dependencies:
- id: a.plugin
isRequired: false
ClassIsland 将在插件加载时验证依赖关系。如果某个插件依赖关系不满足,那么这个插件将不会被加载。
此时我们已经成功声明了插件的依赖,并且也可以访问被依赖的插件的类型了。但被依赖的插件还没有共享任何接口,我们需要先在被依赖的插件定义并共享相应的接口给其它插件,这样其它插件才能顺利访问并调用相应的接口。
一般情况下,我们可以采取如下图所示的,将被依赖的插件中的服务和共享接口拆分到一个单独的项目中,然后再在被依赖的插件和依赖此插件的插件中引用此项目的方式来共享接口:
`,11)),n(l,{id:"mermaid-38",code:"eJxLy8kvT85ILCpR8AniUgCC4tKk9KLEggyF4NIkR4VopUS9gpzS9My893s6Xixa/WTf3Bdbpz2f1fKsf9KT3dve7+lUigVrAwHHaCVHvQCwaiRRJ4SonnN+USpUKjUvBcM+J6B9SQj7IJY9W7sEYhkOW52jlZxQbQUZDWY4Kujq2tUoPd0z9fmUFUo1Ck5gUWcMUQCcFmLT"}),s("p",null,[i[5]||(i[5]=e("其中 ")),i[6]||(i[6]=s("code",null,"A.Plugin.Core",-1)),i[7]||(i[7]=e(" 项目包含了被依赖的插件 ")),i[8]||(i[8]=s("code",null,"A.Plugin",-1)),i[9]||(i[9]=e(" 中服务的抽象接口。")),i[10]||(i[10]=s("code",null,"B.Plugin",-1)),i[11]||(i[11]=e(" 项目引用了 ")),i[12]||(i[12]=s("code",null,"A.Plugin.Core",-1)),i[13]||(i[13]=e(" 项目,从而可以访问并调用 ")),i[14]||(i[14]=s("code",null,"A.Plugin",-1)),i[15]||(i[15]=e(" 中实现的服务。关于如何暴露服务的详细内容,请见")),n(t,{to:"/dev/basics/dependency-injection.html#%E6%9A%B4%E9%9C%B2%E6%9C%8D%E5%8A%A1"},{default:a(()=>i[4]||(i[4]=[e("依赖注入中的暴露服务章节")])),_:1}),i[16]||(i[16]=e("。"))]),i[24]||(i[24]=d('为了能让其它插件调用 A.Plugin.Core 中定义的服务和接口,我们可以将这个项目打包并发布到 nuget.org 上,让其它插件引用并使用。
在声明插件依赖并引用了这个插件提供的共享库后,我们就可以在依赖此插件的插件中引用并调用 A.Plugin.Core 中定义的服务和各种接口了。
',3)),s("p",null,[i[18]||(i[18]=e("如果插件依赖是可选的,那么依赖的插件所提供的服务可能存在不存在的情况,这时我们需要考虑妥善处理这种情况。如果您通过")),n(t,{to:"/dev/basics/dependency-injection.html"},{default:a(()=>i[17]||(i[17]=[e("依赖注入")])),_:1}),i[19]||(i[19]=e("调用了依赖插件的服务或功能,可能需要考虑将这个服务声明为可选的,或者通过 ")),i[20]||(i[20]=s("code",null,"IAppHost.TryGetService()",-1)),i[21]||(i[21]=e(" 方法来获取服务,避免在服务不存在时抛出异常。"))]),i[25]||(i[25]=s("h2",{id:"插件依赖是如何工作的",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#插件依赖是如何工作的"},[s("span",null,"插件依赖是如何工作的")])],-1)),i[26]||(i[26]=s("p",null,"在声明插件依赖后,查找程序集时会优先从依赖的插件的插件程序集加载上下文中查找,以保证插件和被依赖的插件所调用的类型是一致的,如图所示:",-1)),n(l,{id:"mermaid-60",code:"eJxLy8kvT85ILCpR8AniUiguTUovSizIUCg2jFZK0ivIKU3PzFN4PqvlWf+kJ7u3PV/R/XRX/8vZbU+7FrzYu/fJjq4nO7qfTWtXiuVSgII8oEYnvQCwRmRho2glR6iwnnN+USpYLjUvBdlOoJpEsuw0RhiOLGxChJ1ArS93z3ixbgkx9phGKznnJBYXexbnJOalIMyESptFK+np6WGzBeiSZLJ8Zg60EYvPLHD6DBwFCrp6unZA/yuoAd0METPGIgZSp/Bobs+THb1P9syCuEJBT7cCGFsQBSZQTRD1xYYKtrZ2wGgCGlFsDFFhjtMIC4QCsBEge00g5phgmANkg4WMuaAuc6hWKM5ILEi1UihKTS6phYgaYRU1xipqglXUFKuoGVZRc6yiFuiiAJzwIi8="}),i[27]||(i[27]=s("p",null,"如果插件依赖是必选的,那么 ClassIsland 会保证依赖插件的程序集一定存在,此时各个依赖了此插件的插件加载的共享库的程序集也一定是相同的。然而如果插件依赖是可选的,那么就可能会出现依赖的插件不存在的情况。此时依赖此插件的插件就会加载自身携带的共享库程序集,而不是依赖插件的共享库程序集,且共享库中类型的状态就不是跨插件共享的。如图:",-1)),n(l,{id:"mermaid-64",code:"eJxLy8kvT85ILCpR8AniUiguTUovSizIUCg2jFZK0ivIKU3PzFN4PqvlWf+kJ7u3PV/R/XRX/8vZbU+7FrzYu/fJjq4nO7qfTWtXiuVSgII8oEYnvQCwRmRho2glR6iwnnN+USpYLjUvBdlO42ill7tnvFi3hBh7TKOVnHMSi4s9i3MS81IQZkKlzaKV9PT0sNliEq2UTJbPzIE2YvGZBU6fgYNDQVdP1w7oXARXwSapyE4BLGoEFi02VLC1tQP6H6LGHFWNBUIUYVCxCUwL1FyHaoXijMSCVCuFotTkklqIqBFWUVOsomZYRc2xilqgiwIAJLHFcQ=="})])}const A=o(h,[["render",m]]),B=JSON.parse('{"path":"/dev/plugins/dependency.html","title":"插件依赖","lang":"zh-CN","frontmatter":{"description":"插件依赖 注 在阅读本文前,建议先了解。 一个具有依赖的插件 在开发 ClassIsland 插件时,有时我们想要调用其它插件里的功能,或者与其它插件联动。这时我们可以通过在插件清单声明插件依赖,允许插件加载指定插件程序集上下文里的类型,实现调用其它插件的功能和插件间联动。被依赖的插件会先于依赖它的插件加载,以确保被依赖的插件已经初始化完成。 添加插件...","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/dependency.html"}],["meta",{"property":"og:site_name","content":"ClassIsland 文档"}],["meta",{"property":"og:title","content":"插件依赖"}],["meta",{"property":"og:description","content":"插件依赖 注 在阅读本文前,建议先了解。 一个具有依赖的插件 在开发 ClassIsland 插件时,有时我们想要调用其它插件里的功能,或者与其它插件联动。这时我们可以通过在插件清单声明插件依赖,允许插件加载指定插件程序集上下文里的类型,实现调用其它插件的功能和插件间联动。被依赖的插件会先于依赖它的插件加载,以确保被依赖的插件已经初始化完成。 添加插件..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2026-01-17T09:27:32.000Z"}],["meta",{"property":"article:modified_time","content":"2026-01-17T09:27:32.000Z"}]]},"git":{"createdTime":1768642052000,"updatedTime":1768642052000,"contributors":[{"name":"WRC","username":"WRC","email":"hello_wrc@outlook.com","commits":1,"url":"https://github.com/WRC"}]},"readingTime":{"minutes":4.3,"words":1289},"filePathRelative":"dev/plugins/dependency.md","autoDesc":true}');export{A as comp,B as data};