创建第一个插件
本指南将带你创建第一个 Fastdotnet 插件,了解完整的插件开发流程。
⚠️ 重要提示:Fastdotnet 采用插件化架构,所有功能都应该以插件形式开发,非特殊情况不修改框架底座。
📋 学习目标
完成本教程后,你将学会:
- ✅ 使用 CLI 工具创建插件项目
- ✅ 理解插件项目结构
- ✅ 开发后端 API
- ✅ 开发前端页面
- ✅ 调试和测试插件
🎯 项目场景
我们将创建一个简单的任务管理插件:
- 创建任务
- 查看任务列表
- 更新任务状态
- 删除任务
🔧 第一步:安装 CLI 工具
1. 安装 Fastdotnet.Plugin.CLI
bash
dotnet tool install -g Fastdotnet.Plugin.CLI2. 验证安装
bash
fd-plugin --version应该输出版本号,例如:1.0.0
3. 更新到最新版本(推荐)
bash
dotnet tool update -g Fastdotnet.Plugin.CLI💡 提示:确保使用最新版本的 CLI 工具,以保证生成的插件与当前框架兼容。
🚀 第二步:创建插件项目
方式一:交互式模式(推荐新手)
bash
fd-plugin按照提示输入:
插件名称(英文,用于命名空间,例如:MyPlugin): TaskManager
插件显示名称(中文,例如:我的插件): 任务管理
官网申请的 PluginId: 你的PluginId
插件描述: 一个简单的任务管理插件
输出目录: .
是否包含前端项目? Yes
是否生成 .sln 解决方案文件? No方式二:命令行模式
bash
fd-plugin create \
--name TaskManager \
--plugin-id YOUR_PLUGIN_ID \
--display-name "任务管理" \
--description "一个简单的任务管理插件" \
--output ./plugins \
--include-frontend⚠️ 注意:你需要从 Fastdotnet 官网 申请唯一的 PluginId。
📁 第三步:了解项目结构
生成的项目结构如下:
TaskManager/
├── Backend/ # 后端项目 (.NET 10)
│ ├── TaskManager.csproj
│ ├── TaskManagerPlugin.cs # 插件入口类
│ ├── plugin.json # 插件元数据
│ ├── Controllers/ # API 控制器
│ ├── Services/ # 业务服务
│ ├── Dto/ # 数据传输对象
│ ├── Entities/ # 数据实体
│ └── Initializers/ # 初始化器
│
└── Frontend/ # 前端项目 (Vue 3)
├── TaskManager.Admin/ # 管理端
│ ├── src/
│ ├── vite.config.ts
│ └── package.json
│
└── TaskManager.App/ # 应用端
├── src/
├── vite.config.ts
└── package.json💻 第四步:开发后端 API
1. 打开后端项目
bash
cd TaskManager/Backend
code .2. 创建任务实体
在 Entities/ 目录下创建 TaskItem.cs:
csharp
using SqlSugar;
namespace TaskManager.Entities
{
/// <summary>
/// 任务实体
/// </summary>
[SugarTable("task_manager_tasks")]
public class TaskItem : BaseEntity
{
/// <summary>
/// 任务标题
/// </summary>
[SugarColumn(Length = 200, IsNullable = false)]
public string Title { get; set; }
/// <summary>
/// 任务描述
/// </summary>
[SugarColumn(Length = 1000, IsNullable = true)]
public string? Description { get; set; }
/// <summary>
/// 任务状态:0-待办,1-进行中,2-已完成
/// </summary>
public int Status { get; set; } = 0;
/// <summary>
/// 优先级:1-低,2-中,3-高
/// </summary>
public int Priority { get; set; } = 2;
/// <summary>
/// 截止日期
/// </summary>
public DateTime? DueDate { get; set; }
}
}3. 创建控制器
在 Controllers/ 目录下创建 TaskController.cs:
csharp
using Microsoft.AspNetCore.Mvc;
using TaskManager.Entities;
using Fastdotnet.Core.Controllers;
using Fastdotnet.Core.IService;
namespace TaskManager.Controllers
{
/// <summary>
/// 任务管理控制器
/// </summary>
[Route("api/task-manager/[controller]")]
public class TaskController : GenericControllerBase<TaskItem>
{
public TaskController(IRepository<TaskItem> repository)
: base(repository)
{
}
// 自动继承标准 CRUD API:
// GET /api/task-manager/task - 获取列表
// GET /api/task-manager/task/{id} - 获取详情
// POST /api/task-manager/task - 创建任务
// PUT /api/task-manager/task/{id} - 更新任务
// DELETE /api/task-manager/task/{id} - 删除任务
}
}4. 配置菜单
在 Initializers/ 目录下创建 TaskMenuInitializer.cs:
csharp
using Fastdotnet.Core.Initializers;
using Fastdotnet.Core.Entities;
namespace TaskManager.Initializers
{
public class TaskMenuInitializer : IApplicationInitializer
{
public async Task InitializeAsync()
{
var menus = new List<FdMenu>
{
new FdMenu
{
Title = "任务管理",
Code = "MENU_CODE_TASK_MANAGER",
Path = "/micro/{PluginId}/admin/tasks",
Icon = "ele-List",
Type = MenuType.Menu,
Belong = SystemCategory.Admin,
IsFdMicroApp = true,
Sort = 100
},
};
// TODO: 添加菜单插入逻辑
}
}
}🎨 第五步:开发前端页面
1. 安装依赖
bash
cd ../Frontend/TaskManager.Admin
pnpm install2. 启动开发服务器
bash
pnpm dev访问 http://localhost:8099 预览。
3. 创建任务列表页面
在 src/views/ 目录下创建 Tasks.vue:
vue
<template>
<div class="tasks-page">
<el-card>
<template #header>
<div class="card-header">
<span>任务列表</span>
<el-button type="primary" @click="handleCreate">
新建任务
</el-button>
</div>
</template>
<el-table :data="tasks" style="width: 100%">
<el-table-column prop="title" label="标题" />
<el-table-column prop="status" label="状态">
<template #default="{ row }">
<el-tag :type="getStatusType(row.status)">
{{ getStatusText(row.status) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="priority" label="优先级" />
<el-table-column label="操作">
<template #default="{ row }">
<el-button size="small" @click="handleEdit(row)">
编辑
</el-button>
<el-button size="small" type="danger" @click="handleDelete(row)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import axios from 'axios'
const tasks = ref([])
// 获取任务列表
const fetchTasks = async () => {
try {
const response = await axios.get('/api/task-manager/task')
tasks.value = response.data.data
} catch (error) {
ElMessage.error('获取任务列表失败')
}
}
// 状态映射
const getStatusType = (status: number) => {
const types = ['info', 'warning', 'success']
return types[status] || 'info'
}
const getStatusText = (status: number) => {
const texts = ['待办', '进行中', '已完成']
return texts[status] || '未知'
}
// 操作方法
const handleCreate = () => {
ElMessage.info('新建任务功能待实现')
}
const handleEdit = (row: any) => {
ElMessage.info('编辑任务功能待实现')
}
const handleDelete = async (row: any) => {
try {
await axios.delete(`/api/task-manager/task/${row.id}`)
ElMessage.success('删除成功')
fetchTasks()
} catch (error) {
ElMessage.error('删除失败')
}
}
onMounted(() => {
fetchTasks()
})
</script>
<style scoped>
.tasks-page {
padding: 20px;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>4. 配置路由
编辑 src/router/index.ts:
typescript
import { createRouter, createWebHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
const routes: RouteRecordRaw[] = [
{
path: '/tasks',
name: 'Tasks',
component: () => import('../views/Tasks.vue')
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router🧪 第六步:调试和测试
1. 构建后端
bash
cd ../../Backend
dotnet build -c Debug2. 复制到宿主应用
bash
# Windows PowerShell
copy bin\Debug\net10.0\*.dll D:\Fastdotnet\Backend\Fastdotnet.WebApi\bin\Debug\net10.0\Plugins\YOUR_PLUGIN_ID\dependencies\
# Linux/Mac
cp bin/Debug/net10.0/*.dll /path/to/Fastdotnet/WebApi/bin/Debug/net10.0/Plugins/YOUR_PLUGIN_ID/dependencies/3. 启动宿主应用
bash
cd D:\Fastdotnet\Backend\Fastdotnet.WebApi
dotnet run4. 测试 API
访问 http://localhost:18889/swagger,查找 TaskManager 相关的接口进行测试。
5. 测试前端
确保主应用已启动并配置了 qiankun 微前端容器,然后访问对应的路由查看页面。
📦 第七步:打包发布
1. 构建后端
bash
cd Backend
dotnet publish -c Release -o ../publish/{PluginId}/dependencies2. 构建前端
bash
cd ../Frontend/TaskManager.Admin
pnpm build
cd ../TaskManager.App
pnpm build3. 打包插件
bash
cd ../publish/{PluginId}
zip -r ../../TaskManager.zip .4. 上传到插件市场
登录 Fastdotnet 插件市场,上传 ZIP 文件。
📚 学习资源
- PluginA 演示插件 ⭐ - 官方完整示例,强烈推荐学习
- 插件概述 - 了解插件系统架构
- 后端开发 - 深入学习后端开发
- 前端开发 - 深入学习前端开发
💡 常见问题
Q: 为什么不能直接修改框架底座?
A: Fastdotnet 采用插件化架构的优势:
- ✅ 框架稳定性 - 底座不改动,保证系统稳定
- ✅ 功能隔离 - 插件独立,互不影响
- ✅ 热插拔 - 可以动态加载和卸载
- ✅ 易于维护 - 每个插件独立开发和测试
- ✅ 团队协作 - 不同团队可以并行开发不同插件
Q: 如何获取 PluginId?
A: 访问 Fastdotnet 官网,在开发者中心申请唯一的 PluginId。
Q: 插件开发有什么最佳实践?
A:
- 参考 PluginA 演示插件的代码结构
- 遵循命名规范
- 编写清晰的注释
- 做好错误处理
- 及时更新文档
Q: 如何调试插件?
A:
- 将编译后的 DLL 复制到宿主应用的 Plugins 目录
- 启动宿主应用
- 使用 Visual Studio 附加到进程调试
- 查看日志文件排查问题
🎉 恭喜!
你已经完成了第一个 Fastdotnet 插件的开发!
下一步:
- 📖 深入学习 PluginA 演示插件
- 🔧 完善你的插件功能
- 📦 发布到插件市场
- 🤝 与其他开发者分享经验
祝你开发愉快!🚀