Imizuki.UniversalApi 1.1.0
Imizuki.UniversalApi
面向 .NET 10 与 ASP.NET Core 的通用 API 组件。
- 包名:
Imizuki.UniversalApi - 版本:
1.1.0 - 作者:Imizuki
- Copyright © 2026 Imizuki
更新日志
1.1.0
- 将端点分组改为
EndpointGroup<TService>,通过接口注入调用实例方法。 - 新增
AddGeneratedEndpointServices(),按特性配置注册瞬态、作用域或单例服务,默认瞬态。 - HTTP 方法特性支持独立分组及方法优先的
NonUnify响应开关。 - 移除非泛型分组和两套独立的
NonUnify特性,属于破坏性 API 变更。 - 新增接口契约、方法签名及重复服务绑定的编译期诊断(
IUA001–IUA003)。 - 保留实现方法的参数顺序、绑定特性和默认值,支持重载、显式接口实现及异步返回值。
- 旧静态端点需迁移为接口实例方法,并调用
AddGeneratedEndpointServices();迁移步骤见下文。
1.0.2
- 修复代码源生成时二次生成造成引用不明的BUG。
功能与命名空间
| 命名空间 | 功能 |
|---|---|
Imizuki.UniversalApi.Attributes |
端点分组、HTTP 方法与跳过统一响应的特性 |
Imizuki.UniversalApi.Core |
应用配置与服务访问 |
Imizuki.UniversalApi.Unify |
统一响应、业务异常与 MVC / Minimal API 过滤器 |
Imizuki.UniversalApi.Utils |
JSON 配置、日期转换与 ID 工具 |
Imizuki.UniversalApi.Generator |
端点映射源生成器实现 |
生成器独立编译为 netstandard2.0 程序集,通过 NuGet 包的 analyzers/dotnet/cs 目录加载。运行时库不执行生成器,生成的扩展方法使用 Imizuki.UniversalApi.Generated 命名空间。
接口注入与自动注册
using Imizuki.UniversalApi.Attributes;
using Imizuki.UniversalApi.Generated;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGeneratedEndpointServices();
var app = builder.Build();
app.MapGeneratedEndpoints();
app.Run();
public interface ITestService
{
string Get(int id);
}
[EndpointGroup<ITestService>("/test", ServiceLifetime.Scoped, NonUnify = true)]
public class TestService : ITestService
{
[Get("/{id}", Group = "/other", NonUnify = false)]
public string Get(int id) => id.ToString();
}
上述声明生成 services.AddScoped<ITestService, TestService>(),并将端点映射为:
var group0 = endpoints.MapGroup("/other");
group0.MapGet(
"/{id}",
([Microsoft.AspNetCore.Mvc.FromServices] ITestService service, int id) => service.Get(id))
.WithMetadata(new Imizuki.UniversalApi.Unify.EndpointResponseMetadata(false))
.AddEndpointFilter<Imizuki.UniversalApi.Unify.UnifyEndpointFilter>();
EndpointGroup<TService>的泛型参数必须是标记类实现的接口;类须可访问、非抽象、非开放泛型并有公共构造函数。- 生命周期使用
ServiceLifetime:默认Transient,也支持Scoped和Singleton。每个标记类注册一次,同一接口不能绑定多个端点实现类。 - 标记的端点必须属于指定接口或其父接口契约。支持重载、显式接口实现及普通和异步返回值;不支持静态方法、泛型方法、
async void和按引用参数或返回值。 - Lambda 第一参数始终注入服务接口,其余参数按被标记实现方法的顺序保留名称、类型、可空性、默认值和参数绑定特性。绑定信息不从接口参数继承。
Get、Post、Put、Delete都支持Group:不设置或为null时继承类前缀,设置时完全替换前缀,空字符串表示根分组。- 类级
NonUnify默认false。方法未设置时继承类值,显式false可覆盖类上的true。独立分组只改变路由,不改变响应继承关系。 NonUnify仅跳过成功响应包装,异常处理保持启用。MVC 结果过滤器同样按方法配置优先、类配置次之读取这些特性。
迁移旧代码
将 [EndpointGroup("/test")] 改为 [EndpointGroup<ITestService>("/test")],让服务类实现接口,将静态端点改为接口实例方法,并在构建应用前调用 AddGeneratedEndpointServices()。
删除独立的 [NonUnify] / [NonUnifyAttribute],改为分组或 HTTP 方法特性上的 NonUnify = true。类上禁用后,方法可设置 NonUnify = false 恢复包装。
生成器会报告源码位置明确的错误:IUA001 表示分组或生命周期无效,IUA002 表示方法或参数无法映射,IUA003 表示服务接口绑定冲突。
MVC 配置示例
using Imizuki.UniversalApi.Core;
using Imizuki.UniversalApi.Unify;
using Imizuki.UniversalApi.Utils;
var builder = WebApplication.CreateBuilder(args);
builder.AddApplicationCore();
builder.Services.AddControllers()
.AddNewtonsoftJson(options => options.UseMvcJsonOptions())
.AddInjectWithUnifyResult();
var app = builder.Build();
app.UseApplicationCore();
app.MapControllers();
app.Run();
构建与打包
dotnet build Imizuki.UniversalApi.slnx -c Release
dotnet pack Imizuki.UniversalApi/Imizuki.UniversalApi.csproj -c Release -o artifacts
代码规范与验证
项目通过 .editorconfig 统一代码格式,类、方法和关键处理步骤使用中文注释。
dotnet format whitespace Imizuki.UniversalApi.slnx --verify-no-changes
dotnet format style Imizuki.UniversalApi.slnx --verify-no-changes
本次改造不新增测试用例或临时测试程序,使用 Release 构建、格式检查和生成逻辑静态核查验证。构建检查不会替代消费者端点的运行时验证。
尚未指定开源许可证、项目主页或源码仓库地址;发布前应按实际情况补充相应 NuGet 元数据。
No packages depend on Imizuki.UniversalApi.
新增泛型 EndpointGroup
.NET 10.0
- Microsoft.AspNetCore.Mvc.NewtonsoftJson (>= 10.0.11)
- Yitter.IdGenerator (>= 1.0.14)