Bizer.Client
0.8.0-preview1
dotnet add package Bizer.Client --version 0.8.0-preview1
NuGet\Install-Package Bizer.Client -Version 0.8.0-preview1
<PackageReference Include="Bizer.Client" Version="0.8.0-preview1" />
paket add Bizer.Client --version 0.8.0-preview1
#r "nuget: Bizer.Client, 0.8.0-preview1"
// Install Bizer.Client as a Cake Addin #addin nuget:?package=Bizer.Client&version=0.8.0-preview1&prerelease // Install Bizer.Client as a Cake Tool #tool nuget:?package=Bizer.Client&version=0.8.0-preview1&prerelease
Bizer
Bizer.Core 用于定义前后端 HTTP 的解析规范。 根据需要安装:
- 动态 HTTP 客户端 Bizer.Client: 根据接口的 HTTP 定义,自动发送 Http 请求
- 动态 API 服务端 Bizer.AspNetCore: 根据接口的 HTTP 定义,自动变成 WEB API 接口
🌈 优势
- 只需要定义一套接口,就可以完成前后端对接,减少重复工作量,不再担心 API 接口的规范不一致;
- 完美兼容任意项目,只需要给接口定义框架的 HTTP 规范即可;
- 非常灵活,可以将接口和实现作为普通的方法,根据选择配套安装
Bizer.AspNetCore
或Bizer.Client
即可实现动态 API 或动态 Http 的功能;
😄 概念图
快速上手
⚠️ 定义服务接口和 HTTP 路由规则
安装 Bizer
包
> Install-Package Bizer
定义接口
+[ApiRoute("api/account")] //定义 API 的路由基础路由
public interface IAccountService
{
+ [Post] //定义为 Post 请求
Task<Returns<string>> SignInAsync([Form]string userName, [Form]string password); //参数使用 form 方式
+ [Get("{id}")]//定义 Get 请求,路由为:api/account/{id}
Task<MyData> GetAsync(int id);
+ [Put("student/{id}")] // 定义 Put 请求,路由为:api/account/{id}
Task UpdateStudentAsync([Body]Student model, int id);
}
实现接口
public class AccountApplicationService : IAccountService
{
public Task<Returns<string>> SignInAsync(string userName, string password)
{
//...业务逻辑代码
return Returns<string>.Success(token);
}
//...其他实现
[Authorize(Roles = "admin")] //兼容 Microsoft.AspNetCore.Authorization 认证授权框架
Task UpdateStudentAsync([Body]Student model, int id)
{
//...
}
}
📌 动态 WEB API
在 ASP.NET CORE 项目中安装 Bizer.AspNetCore
包
> Install-Package Bizer.AspNetCore
配置服务
builder.Services
.AddBizer(options => options.AddAssembly(typeof(AccountService).Assembly)) //接口实现类所在的程序集
+ .AddDynamicWebApi(); //将扫描到的程序集的接口和实现秒变动态 WEB API 服务
自行安装相关的 Swagger 包即可看到生成的 API or 通过 Postman 来模拟发送 HTTP 测试 API 接口
🛡️ 动态 Http 代理
安装 Bizer.Client
包
> Install-Package Bizer.Client
配置要作为动态 HTTP 代理所在接口的程序集
builder.Services
.AddBizer(options => options.AddAssembly(typeof(IAccountService).Assembly)) //要扫描的程序集
+ .AddDynamicHttpProxy("http://{localhost}:{port}"); // 将扫描到的程序集的接口秒变动态 HTTP 代理
在任意地方调用接口方法:
private readonly IAccountService _accountService;
public MyClientService(IAccountService accountService)
{
_accountService = accountService;
}
//...
public async Task ProcceedAsync()
{
var result = _accountService.SignInAsync("admin", "password");
if(!result.Succeed)
{
//result.Errors 获取错误信息
}
var data = result.Data; //获取数据
}
💻 支持环境
- .NET 6
- .NET 7
- .NET 8
📃 许可证
:toolbox: API 路由和请求对照表
Bizer | Controller | 说明 |
---|---|---|
ApiRoute | Route | 路由模板 |
Get | HttpGet | Get 请求 |
Post | HttpPost | Post 请求 |
Put | HttpPut | Put 请求 |
Delete | HttpDelete | Delete 请求 |
Patch | HttpPatch | Patch 请求 |
Options | HttpOptions | Options 请求 |
🔥 API 参数定义对照表
Bizer | Controller | 说明 |
---|---|---|
Header | FromHeader | 参数是从 Header 中传递 |
Form | FromForm | 参数是从 Form 中传递 |
Body | FromBody | 参数是从 Json 中传递 |
Route | FromRoute | 参数从路由中传递 |
Query | FromQuery | 参数从查询字符串传递 |
❓ Q & A
- 为什么我的接口没有识别成 API?
只有接口定义了
ApiRouteAttribute
特性,才会被自动识别动态 API 或 HTTP 代理 - 我接口定义了
ApiRouteAttribute
特性,但是方法却没有识别成 API 接口中定义的方法,需要定义请求类型才会被正确识别成 API
使用过程中遇到的问题可在【Github Issue】提出
🎬 扩展
扩展可以根据自己的需要安装
Bizer.Extensions.AutoInjection
实现接口的自动化注入。接口中使用 InjectServiceAttribute
即可:
+[InjectService] //默认是 Scoped
public interface IMyService { }
+[InjectService(Lifetime = ServiceLifetime.Transient)] //注册成 Transient 生命周期
public interface IMyService { }
添加扩展模块:
builder.Services.AddBizer(...)
+ .AddServiceInjection() //扫描到的程序集中,接口定义了 InjectService 特性都会被添加成服务(IoC)
Bizer.Extensions.ApplicationService.EntityFrameworkCore
基于 EntityFrameworkCore 实现的应用服务,并使用 Mapster 实现对象映射。
类似于 Abp 的 ApplicationService 层,但比它更简单。
builder.Services.AddBizer(...)
+ .AddMapster() //添加 Mapster 服务
//使用内置的 BizerDbContext 作为项目
+ .AddDbContext(options => options.UseSqlServer("..."))
//或者使用自定义的 DbContext,要求继承自 BizerDbContext
+ .AddDbContext<MyDbContext>(options => options.UseSqlServer("..."))
- 接口可以继承自
IQueryService
(只读查询服务) 或ICrudService
(CRUD 服务)
public interface IUserQueryService : IQuerySerivce<Guid, UserQueryDto> { }
public interface IUserService : ICrudService<Guid, UserQueryDto, UserListDto, UserCreateDto, UserUpdateDto>
- 对应实现则是
QueryServiceBase
和CrudServiceBase
两个基类
public class UserQueryService : IUserQueryService, QueryServiceBase<Guid, User, UserQueryDto>
{
//...
}
public class UserService : IUserService, CrudServiceBase<Guid, User, UserQueryDto, UserListDto, UserCreateDto, UserUpdateDto>
{
//...
}
- 实体的配置需要实现接口
IEntityTypeConfiguration<TEntity>
使用 FluentAPI 配置
public class UserConfiguration : IEntityTypeConfiguration<User>
{
public void Configure(ModelBuilder<User> builder)
{
builder.HasKey(m=>m.Id);
builder.Property(m=>m.Name).IsRequired();
//...
builder.ToTable("MyUserTable");
}
}
内置的 BizerDbContext
会自动根据程序集将实现 IEntityTypeConfiguration<TEntity>
的配置加入到 DbContext
中,无需添加 DbSet
有关 EntityFrameworkCore 的 Fluent API 配置
- 你也可以实现自己的
DbContext
,或继承自BizerDbContext
,如果不继承BizerDbContext
就不会有自动配置功能,可按照常规方式自己添加或用DbSet
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions options) : base(options) { }
public DbSet<User> Users { get; set; }
}
那么 QueryServiceBase
或 CrudServiceBase
需要显示地指定你的 DbContext
对象:
+ public class UserQueryService : IUserQueryService, QueryServiceBase<AppDbContext, Guid, User, UserQueryDto>
- public class UserQueryService : IUserQueryService, QueryServiceBase<Guid, User, UserQueryDto>
{
//...
}
+ public class UserService : IUserService, CrudServiceBase<AppDbContext, Guid, User, UserQueryDto, UserListDto, UserCreateDto, UserUpdateDto>
- public class UserService : IUserService, CrudServiceBase<Guid, User, UserQueryDto, UserListDto, UserCreateDto, UserUpdateDto>
{
//...
}
最终在 Program.cs
中修改
builder.Services.AddBizer(...)
.AddMapster()
- .AddDbContext(options => options.UseSqlServer("..."))
+ .AddDbContext<AppDbContext>(options => options.UseSqlServer("..."))
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Bizer.Core (>= 0.8.0-preview1)
- Castle.Core (>= 5.1.1)
- Castle.Core.AsyncInterceptor (>= 2.1.0)
- Microsoft.Extensions.Http (>= 6.0.0)
-
net7.0
- Bizer.Core (>= 0.8.0-preview1)
- Castle.Core (>= 5.1.1)
- Castle.Core.AsyncInterceptor (>= 2.1.0)
- Microsoft.Extensions.Http (>= 7.0.0)
-
net8.0
- Bizer.Core (>= 0.8.0-preview1)
- Castle.Core (>= 5.1.1)
- Castle.Core.AsyncInterceptor (>= 2.1.0)
- Microsoft.Extensions.Http (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.