brainstorming
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or planning anything new, in software or out of it (a talk, a business, a renovation).
furionUse when building .NET Web API applications with minimal boilerplate — dynamic controllers, automatic dependency injection, JWT authentication, Swagger, event bus. Furion: lightweight convention-over-configuration .NET enterprise web framework.
Independent GitHub snapshot · Automated classification · Original documentation governs
name: furion description: "Use when building .NET Web API applications with minimal boilerplate — dynamic controllers, automatic dependency injection, JWT authentication, Swagger, event bus. Furion: lightweight convention-over-configuration .NET enterprise web framework." tags:
项目地址: https://gitee.com/dotnetchina/Furion
GitHub 镜像: https://github.com/MonkSoul/Furion
官方文档: https://furion.net/
NuGet:
Furion、Furion.Pure最新版本:
Furion4.9.9.95 /Furion.Pure4.9.9.10(截至2026-09,NuGet)许可证: MIT + Apache-2.0
Furion 主要特性:
Inject() + AddInject() 自动激活IDynamicApiController → 自动暴露 RESTful 接口RESTfulResult<T> 响应ITransient/IScoped/ISingleton 标记接口自动注册[Authorize] + JWT + 策略IHttpRemote + [HttpRequest] 配置式Furion.Schedule(基于 Quartz 类似的语法)App.GetConfig、Config<TOptions>Furion 适合 Admin.NET、企业内部系统、微服务后端。
dotnet add package Furion
# 或基础版(不含全部子包)
dotnet add package Furion.Pure
// Program.cs
var builder = WebApplication.CreateBuilder(args).Inject(); // 关键
builder.Services.AddControllers().AddInject(); // 关键
var app = builder.Build();
app.UseInject(); // 关键
app.MapControllers();
app.Run();
Inject() 会扫描程序集自动加载 Furion 的「应用启动模块」(AppStartup)。
public class HelloService : IDynamicApiController
{
public string Get() => "Hello Furion";
public int Add(int a, int b) => a + b;
public Task<List<User>> List() => /* ... */;
}
启动后自动暴露:
GET /api/hello/getPOST /api/hello/addGET /api/hello/list可用 [ApiDescriptionSettings]、[HttpGet] 等控制路由。
默认所有接口返回:
{
"statusCode": 200,
"succeeded": true,
"data": { ... },
"errors": null,
"extras": null,
"timestamp": 1700000000
}
异常自动包装为:
{ "statusCode": 500, "succeeded": false, "errors": "ex.Message" }
可通过 App.Configuration["SpecificationDocumentSettings:..."] 关闭或自定义。
public interface IUserService { User GetById(int id); }
public class UserService : IUserService, ITransient
{
public User GetById(int id) => /* ... */;
}
// 直接构造函数注入即可,无需 services.AddTransient<...>()
public class HelloService(IUserService userSvc) : IDynamicApiController { ... }
ITransient / IScoped / ISingleton 三选一作为标记接口。
dotnet add package Furion.Extras.DatabaseAccessor.SqlSugar
{
"DbConnectionString": "server=.;database=demo;uid=sa;pwd=...;TrustServerCertificate=true"
}
builder.Services.AddSqlSugar(new ConnectionConfig {
ConnectionString = App.Configuration["DbConnectionString"],
DbType = DbType.SqlServer,
IsAutoCloseConnection = true
});
public class UserService(ISqlSugarClient db) : IDynamicApiController
{
public List<User> List() => db.Queryable<User>().ToList();
}
EF Core 走 Furion.DatabaseAccessor:
public class MyDbContext : AppDbContext<MyDbContext> { ... }
builder.Services.AddDatabaseAccessor(opt => {
opt.AddDbPool<MyDbContext>(DbProvider.SqlServer);
}, "Furion.Database.Migrations");
"JWTSettings": {
"ValidateIssuer": true,
"ValidateAudience": true,
"ValidateLifetime": true,
"ValidIssuer": "Furion",
"ValidAudience": "Furion",
"IssuerSigningKey": "Wts3hE2mp..."
}
builder.Services.AddJwt<JwtHandler>(); // 自定义 IAuthorizationHandler
[Authorize]
public class OrderService : IDynamicApiController { ... }
登录返回:
var token = JWTEncryption.Encrypt(new Dictionary<string, object> {
{ "UserId", 1 }, { "Account", "admin" }
});
public interface IGithub : IHttpDispatchProxy
{
[Get("https://api.github.com/users/{user}")]
Task<GithubUser> GetUserAsync([Path] string user);
}
builder.Services.AddRemoteRequest(opt => opt.AddHttpProxy<IGithub>());
// 注入即用
public class HelloService(IGithub gh) : IDynamicApiController
{
public Task<GithubUser> User(string user) => gh.GetUserAsync(user);
}
[JobDetail("job1", Description = "每分钟一次")]
[PeriodSeconds(60, TriggerId = "trigger1")]
public class HelloJob : IJob
{
public Task ExecuteAsync(JobExecutingContext context, CancellationToken ct)
=> Console.Out.WriteLineAsync("hello " + DateTime.Now);
}
builder.Services.AddSchedule(opt => opt.AddJob<HelloJob>());
public class OrderCreatedEventSubscriber : IEventSubscriber
{
[EventSubscribe("order:created")]
public Task OnOrderCreated(EventHandlerExecutingContext ctx)
{
var order = ctx.Source.Payload as Order;
return Task.CompletedTask;
}
}
builder.Services.AddEventBus(opt =>
opt.AddSubscriber<OrderCreatedEventSubscriber>());
// 触发
await eventPublisher.PublishAsync("order:created", new Order { Id = 1 });
var dbCs = App.Configuration["DbConnectionString"];
[Configuration]
public class JwtSettings { public string ValidIssuer { get; set; } = ""; }
var jwt = App.GetConfig<JwtSettings>("JWTSettings");
dotnet new webapi → 添加 Furion 包 → builder.Services.AddControllers().AddInject() → app.UseInject()IDynamicApiController + 标记接口(ITransient/IScoped/ISingleton)→ 接口自动暴露AddSqlSugar)或 EF Core(AddDatabaseAccessor)JWTSettings + AddJwt<JwtHandler>() + [Authorize]IHttpDispatchProxy,定时任务用 IJob,事件总线用 IEventSubscriberInject() 三步走:builder.Inject() → builder.Services.AddControllers().AddInject() → app.UseInject(),缺一不可Get/Post/Add/Update/Delete/Page),不匹配时用 [HttpPost] 覆盖ITransient/IScoped/ISingleton 三选一,Abstract 类不生效{statusCode, succeeded, data, errors},可通过配置关闭app.UseInject() 是否正确调用,以及 SpecificationDocumentSettings 分组配置| 场景 | 推荐方案 |
|---|---|
| 快速构建单体 API | Furion 动态 API |
| 已有大型项目渐进迁移 | 仅用 Furion 的 DI/配置/事件总线 |
| 微服务架构 | Furion + 自建网关 |
| 前后端分离后台 | Furion(后端)+ Admin.NET 前端模板 |
| 问题 | 解决 |
|---|---|
| 接口未暴露 | 服务实现 IDynamicApiController 并 AddInject() |
| Swagger 不显示 | 启用 app.UseInject();检查 SpecificationDocumentSettings.GroupOpenApiInfos |
| DI 不生效 | 实现类需带 ITransient/IScoped/ISingleton 之一 |
| 单元测试 | 使用 Furion.UnitTesting 包,或调用 App.Initialize() |
App 未初始化 | 异步入口需 Inject() 完成后 |