.NET 未来已来,你来不来?!
重新起航
不忘初心,感恩遇见,感恩信任
2020 年 09 月 01 日,一个叫 Fur 的开源项目在 Gitee 的襁褓中悄然诞生,她的出生仿佛带着某种使命,没有包袱,无限可能。
她缓缓的张开双眼,干净雪亮的眼睛似乎对这个世界充满了好奇,任何事物在她眼前晃过都像是直击灵魂的思想碰撞,这些在她看来都是非常宝贵的财富。她貌似有用不完的精力,一路汲取知识,升级打怪,不断奔跑,乐此不疲。
记得 2020 年 11 月 11 日的单身节,她迎来了“一岁(v1.0.0)”生日,自那以后,IT 这个大银幕上频繁出现她的身影,越来越多 .NET5 开发者转粉,像是告诉这个世界,她就是 IT 界大明星。
每一个明星都有一个好听的艺名,她当然也不例外,2020 年 11 月 20 日,经纪人百小僧为她起名为 Furion。
2021 年 11 月 09 日起,她进入了每个孩子都经历过的叛逆期,年少轻狂喜新厌旧,抛弃了曾经支持她的 .NET5 粉丝们,投入到新的 .NET6 拥趸者怀抱中,自此过上了奢靡富足的生活。
但她过的不开心,时常在夜里想起 .NET5 的粉丝们,内心非常自责,但在双重工作压力下她毅然选择了忽视他们的诉求,仿佛他们就是累赘。
时间真的是好东西,曾经认为是对的,经过岁月的蹉跎历磨,渐渐的明白:不忘初心,方能始终。
这一次,不落下一人(.NET5,.NET6,...,.NET N),携手共进,重新起航,感恩遇见,感恩信任。
项目信息
准备工作
早就在 .NET7 发布 Preview 版本的时候,Furion 团队就着实进行适配,前前后后耗时4个多月解决了 .NET5 升级到 .NET6、.NET7 的所有问题,保证一套代码兼容 .NET5+,支持现有的所有 Furion 版本升级,包括 0.x,1.x,2.x,3.x 版本。
在适配 .NET7 过程中主要参考微软提供了两篇文档:
![]()
![]()
文档更新
1. 内置强大实时的本地搜索
![]()
2. 添加升级或集成 .NET7 的文档
![]()
3. 改进更新日志模板规范
![]()
本期更新
新特性
- [新增] 新增友好异常可控制是否输出错误日志配置
LogError: true #I5PKJH
- [新增]
DateOnlyJsonConverter 和 DateOnlyOffsetJsonConverter 序列化转换器 !565
- [新增] 事件总线
LogEnabled 配置,可控制是否输出服务日志 #I5QLY5
- [新增] 可实现任何多套规范化结果功能,支持特定控制器,特定方法 #I5QZ37
突破性变化
问题修复
其他更改
- [调整]
JWTEncryption 静态类,支持无需注册 services.AddJwt() 使用 #I5PPKE #I5POLZ
- [调整] 事件总线默认日志类名为
System.Logging.EventBusService #I5QLY5
文档
- [新增]
.NET6 升级 .NET7 文档
- [新增]
ASP.NET 7 集成文档
- [更新] 友好异常文档、远程请求文档、依赖注入文档、即时通讯文档、事件总线文档、Worker Service 文档、单元测试文档、入门指南文档
本期亮点
1. 文档支持全文搜索、模糊搜索、代码搜索、搜索高亮
![]()
2. 远程请求第三方 API 上传文件更加易用
代理模式
public interface IHttp : IHttpDispatchProxy
{
[Post("https://www.furion.icu/upload", ContentType = "multipart/form-data")]
Task<HttpResponseMessage> PostXXXAsync(HttpFile file);
// 支持多个文件
[Post("https://www.furion.icu/upload", ContentType = "multipart/form-data")]
Task<HttpResponseMessage> PostXXXAsync(HttpFile[] files);
// 支持多个文件
[Post("https://www.furion.icu/upload", ContentType = "multipart/form-data")]
Task<HttpResponseMessage> PostXXXAsync(IList<HttpFile> files);
}
字符串模式
var bytes = File.ReadAllBytes("image.png");
// 单个文件
var result = await "https://localhost:44316/api/test-module/upload-file"
.SetContentType("multipart/form-data")
.SetFiles(HttpFile.Create("file", bytes, "image.png")).PostAsync();
// 多个文件
var result = await "https://localhost:44316/api/test-module/upload-muliti-file"
.SetContentType("multipart/form-data")
.SetFiles(HttpFile.CreateMultiple("files", (bytes, "image1.png"), (bytes, "image2.png"))).PostAsync();
3. 简化框架初始配置参数签名
public void ConfigureServices(IServiceCollection services)
{
services.AddInject(options =>
{
options.ConfigureSwaggerGen(gen =>
{
// ...
});
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseInject(configure: options =>
{
options.ConfigureSwagger(swg =>
{
// ...
});
options.ConfigureSwaggerUI(ui =>
{
// ...
});
});
}
4. 支持多套接口规范化处理
// 替换默认的
services.AddUnifyProvider<SpeciallyResultProvider>();
// 添加更多规范化配置
services.AddUnifyProvider<SpeciallyResultProvider>("unique_name");
[UnifyProvider] // 默认的(不贴也是默认的)
public class FurionAppService: IDynamicApiController
{
}
[UnifyProvider("specially")] // 自定义的
public class FurionAppService: IDynamicApiController
{
}
[UnifyProvider] // 默认的
public class FurionAppService: IDynamicApiController
{
[UnifyProvider("specially")] // 复写默认的
public string GetName()
{
}
}