Files
LanMountainDesktop/docs/Plugins develop/01-快速开始/03-插件项目结构详解.md
2026-04-13 19:54:37 +08:00

351 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 03-插件项目结构详解
了解插件项目的每个文件和文件夹的作用,是开发高质量插件的基础。本文将详细解析插件项目的完整结构。
---
## 📂 项目结构概览
使用模板创建的插件项目结构如下:
```
MyPlugin/
├── plugin.json # 插件清单(必需)
├── MyPlugin.csproj # 项目文件(必需)
├── Plugin.cs # 入口类(必需)
├── README.md # 项目说明(推荐)
├── .gitignore # Git忽略文件可选
└── Localization/ # 本地化文件夹(可选)
├── zh-CN.json # 中文资源
└── en-US.json # 英文资源
```
---
## 📋 plugin.json - 插件清单
这是插件最重要的配置文件,定义了插件的元数据。
### 完整示例
```json
{
"id": "com.example.myplugin",
"name": "我的插件",
"description": "这是一个示例插件",
"author": "作者名称",
"version": "1.0.0",
"apiVersion": "4.0.1",
"entranceAssembly": "MyPlugin.dll",
"sharedContracts": [],
"website": "https://example.com",
"icon": "icon.png",
"tags": ["工具", "实用"]
}
```
### 字段详解
| 字段 | 必需 | 说明 | 示例 |
|-----|------|------|------|
| `id` | ✅ | 唯一标识符,反向域名格式 | `com.yourname.plugin` |
| `name` | ✅ | 显示名称 | `天气插件` |
| `description` | ✅ | 简短描述 | `显示实时天气信息` |
| `author` | ✅ | 作者名称 | `张三` |
| `version` | ✅ | 版本号(语义化版本) | `1.0.0` |
| `apiVersion` | ✅ | SDK API 版本 | `4.0.1` |
| `entranceAssembly` | ✅ | 入口程序集文件名 | `MyPlugin.dll` |
| `sharedContracts` | ✅ | 共享契约类型列表 | `[]` |
| `website` | ❌ | 项目网站 | `https://github.com/...` |
| `icon` | ❌ | 图标文件名 | `icon.png` |
| `tags` | ❌ | 标签数组 | `["天气", "工具"]` |
### 重要规则
⚠️ **id 字段规则:**
- 只能包含小写字母、数字、点号(`.`
- 必须全局唯一
- 建议使用反向域名格式:`com.yourname.pluginname`
- 一经发布不可更改
⚠️ **version 字段规则:**
- 使用语义化版本格式:`主版本.次版本.修订号`
- 示例:`1.0.0``2.1.3-beta`
⚠️ **apiVersion 字段规则:**
- 必须与引用的 SDK 版本兼容
- 当前最新版本:`4.0.1`
- 不兼容时宿主将拒绝加载插件
---
## 🔧 .csproj - 项目文件
定义了项目的构建配置和依赖项。
### 完整示例
```xml
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LanMountainDesktop.PluginSdk" Version="4.0.1" />
</ItemGroup>
<ItemGroup>
<None Update="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Localization\**\*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
```
### 关键配置项
| 配置项 | 说明 | 推荐值 |
|-------|------|--------|
| `TargetFramework` | 目标框架 | `net10.0` |
| `LangVersion` | C# 语言版本 | `latest` |
| `Nullable` | 可空引用类型 | `enable` |
### SDK 引用
```xml
<PackageReference Include="LanMountainDesktop.PluginSdk" Version="4.0.1" />
```
⚠️ **版本必须匹配:**
- SDK 版本必须与 `plugin.json` 中的 `apiVersion` 兼容
- 建议使用最新稳定版
### 资源文件配置
确保 `plugin.json` 和本地化文件被正确复制到输出目录:
```xml
<ItemGroup>
<None Update="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Localization\**\*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
```
---
## 🚪 Plugin.cs - 入口类
插件的入口点,负责初始化逻辑。
### 基本结构
```csharp
using LanMountainDesktop.PluginSdk;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace MyPlugin;
[PluginEntrance]
public sealed class Plugin : PluginBase
{
public override void Initialize(HostBuilderContext context, IServiceCollection services)
{
// 在这里注册组件、设置页面、服务等
// 示例:注册桌面组件
// services.AddPluginDesktopComponent<MyWidget>(...);
// 示例:注册设置页面
// services.AddPluginSettingsSection(...);
}
}
```
### 关键特性
| 特性/类 | 说明 |
|--------|------|
| `[PluginEntrance]` | 标记插件入口类,必须有且仅有一个 |
| `PluginBase` | 插件基类,提供基础功能和日志访问 |
| `Initialize` | 初始化方法,宿主启动时调用 |
### Initialize 方法参数
```csharp
public override void Initialize(HostBuilderContext context, IServiceCollection services)
```
| 参数 | 类型 | 说明 |
|-----|------|------|
| `context` | `HostBuilderContext` | 宿主构建上下文,可访问配置 |
| `services` | `IServiceCollection` | 依赖注入服务集合,用于注册组件和服务 |
---
## 🌍 Localization - 本地化文件夹
存放多语言资源文件,支持插件的国际化。
### 文件夹结构
```
Localization/
├── zh-CN.json # 简体中文
├── zh-TW.json # 繁体中文
├── en-US.json # 英文(美国)
├── ja-JP.json # 日文
└── ko-KR.json # 韩文
```
### 资源文件格式
```json
{
"PluginName": "我的插件",
"Settings": {
"Title": "设置",
"RefreshInterval": "刷新间隔"
},
"Messages": {
"Loading": "加载中...",
"Error": "出错了:{0}"
}
}
```
### 在代码中使用
```csharp
// 获取本地化字符串
var localizer = serviceProvider.GetRequiredService<IStringLocalizer<MyPlugin>>();
var pluginName = localizer["PluginName"];
var message = localizer["Messages.Error", errorDetails];
```
### 支持的语言代码
| 语言 | 代码 |
|-----|------|
| 简体中文 | `zh-CN` |
| 繁体中文 | `zh-TW` |
| 英文 | `en-US` |
| 日文 | `ja-JP` |
| 韩文 | `ko-KR` |
---
## 📦 构建输出结构
运行 `dotnet build` 后,生成的输出结构:
```
bin/Debug/net10.0/
├── MyPlugin.dll # 插件程序集
├── MyPlugin.pdb # 调试符号
├── plugin.json # 插件清单(复制)
├── Localization/ # 本地化文件夹(复制)
│ └── zh-CN.json
├── MyPlugin.laapp # 插件包(由 SDK 自动生成)
└── ...(依赖项 DLL
```
### .laapp 包结构
`.laapp` 文件本质是一个 ZIP 压缩包,包含:
```
MyPlugin.laapp
├── plugin.json # 清单文件
├── MyPlugin.dll # 主程序集
├── Localization/ # 本地化资源
└── ...(其他依赖 DLL
```
---
## 🔗 与其他 .NET 项目的区别
| 特性 | 普通 .NET 应用 | 阑山桌面插件 |
|-----|---------------|-------------|
| 入口点 | `Program.cs``Main` | `Plugin.cs``Initialize` |
| 运行方式 | 独立运行 | 由宿主加载运行 |
| 依赖注入 | 自行配置 | 使用宿主提供的 `IServiceCollection` |
| 输出格式 | `.exe``.dll` | `.laapp` 包 |
| 资源访问 | 直接访问 | 通过 SDK API 访问宿主资源 |
| 热重载 | 支持 | 不支持(需重启宿主) |
---
## 🎯 最佳实践
### 项目组织建议
```
MyPlugin/
├── plugin.json
├── MyPlugin.csproj
├── Plugin.cs # 入口类(保持简洁)
├── README.md
├── .gitignore
├── Localization/ # 本地化资源
├── Services/ # 服务类文件夹
│ ├── WeatherService.cs
│ └── DataService.cs
├── Views/ # 视图文件夹
│ ├── WeatherWidget.axaml
│ ├── WeatherWidget.axaml.cs
│ └── SettingsPage.axaml
└── ViewModels/ # 视图模型文件夹
├── WeatherViewModel.cs
└── SettingsViewModel.cs
```
### 文件命名规范
| 类型 | 命名约定 | 示例 |
|-----|---------|------|
| 入口类 | `Plugin` | `Plugin.cs` |
| 组件视图 | `{Name}Widget` | `WeatherWidget.axaml` |
| 设置页面 | `{Name}SettingsPage` | `WeatherSettingsPage.axaml` |
| 服务类 | `{Name}Service` | `WeatherService.cs` |
| 视图模型 | `{Name}ViewModel` | `WeatherViewModel.cs` |
---
## 📚 参考资源
- [Plugin SDK 源码](../../LanMountainDesktop.PluginSdk/)
- [插件模板](../../LanMountainDesktop.PluginTemplate/content/)
- [02-桌面组件系统](../02-核心概念与原理/02-桌面组件系统.md)
- [03-设置系统集成](../02-核心概念与原理/03-设置系统集成.md)
---
## 🎯 下一步
理解了项目结构后,接下来学习:
👉 **[04-调试运行指南](04-调试运行指南.md)** - 掌握调试技巧
或者深入了解核心概念:
👉 **[01-插件生命周期](../02-核心概念与原理/01-插件生命周期.md)** - 理解插件运行机制
---
*最后更新2026年4月*