兩千星 .NET5 框架 Furion 亮點分析(一)
讓 .NET 開發更簡單,更通用,更流行。
Furion 介紹
Furion 是基於 .NET5 平台下打造的現代化 Web 框架。旨在 讓 .NET 開發更簡單,更通用,更流行。
。
Furion 非常精悍短小,底層只依賴兩個第三方庫,去除注釋文件僅有 73KB
大小。
麻雀雖小五臟俱全,企業級項目開發所需功能它一個也不少。
開源地址
- Gitee://gitee.com/monksoul/Furion
- GitHub://github.com/monksoul/Furion
文檔地址
- 中國文檔://monksoul.gitee.io/furion/
- 國外文檔://furion.pro
目前文檔正在逐步完善中。
項目案例
- 考試君:基於 Furion 的在線考試系統
- 園丁:基於 Furion + Blazor 的超簡單後台管理系統
- Queer:基於 Furion + Layui 的通用型管理系統
- Pear Admin:PearAdmin 官方和 Furion 官方合作管理系統
- JoyAdmin:基於 Furion + iviewadmin 開發的管理系統
Furion 亮點介紹
1. 極易集成
Furion
設計遵循「無侵入性或侵入性極小」原則,只需要在 Progame.cs
文件夾中添加 Inject()
方法即可完成初始化配置。
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace FurStart
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.Inject() // 只需這一行即可完成配置
.UseStartup<Startup>();
});
}
}
文檔傳送門://monksoul.gitee.io/furion/docs/get-start
2. 豐富腳手架
Furion
提供了 .NET5
所有 Web 類型的腳手架,可以極速搭建企業項目多層架構。
文檔傳送門://monksoul.gitee.io/furion/docs/template
3. 極少依賴
Furion
為了追求極速入門,極致性能,儘可能的不使用或減少第三方依賴。目前 Furion
僅集成了以下兩個依賴:
- MiniProfiler:性能分析和監聽必備
- Swashbuckle:
Swagger
介面文檔
麻雀雖小五臟俱全。Furion
即使只集成了這兩個依賴,但是主流的 依賴注入/控制反轉
,AOP
面向切面編程,事件匯流排
,數據驗證
,資料庫操作
等等一個都不少。
文檔傳送門://monksoul.gitee.io/furion/docs/
4. appsettings.json
分割合併
默認情況下,.NET5 的配置文件需寫在 appsettings.json
文件中,如需添加其他配置,需手動添加並在主機啟動時載入進來,Furion
提供了非常靈活方便的方式,支援配置文件放在項目其他位置,並自動載入,自動配置併合並。如:system.json
{
"AppInfo": {
"Name": "Furion",
"Version": "1.7.0"
}
}
此時 system.json
會自動載入並自動合併。
文檔傳送門://monksoul.gitee.io/furion/docs/configuration
5. 熱重載配置選項
Furion
提供了非常靈活的選項配置功能,支援後期配置,配置更改通知。
using Furion.ConfigurableOptions;
namespace Furion.Application
{
public class AppInfoOptions : IConfigurableOptionsListener<AppInfoOptions>
{
public string Name { get; set; }
public string Version { get; set; }
public string Company { get; set; }
// 選項更改監聽
public void OnListener(AppInfoOptions options, IConfiguration configuration)
{
var name = options.Name; // 實時的最新值
var version = options.Version; // 實時的最新值
}
// 選項後期配置
public void PostConfigure(AppInfoOptions options, IConfiguration configuration)
{
}
}
文檔傳送門://monksoul.gitee.io/furion/docs/options
6. 動態API及變體服務
Furion
提供了動態構建 WebApi
的方式,可以大大提高 WebApi
的開發效率,還能實現 WebApi
服務介面化。
using Furion.DynamicApiController;
namespace Furion.Application
{
public class FurAppService : IDynamicApiController
{
public string Get()
{
return $"GET 請求";
}
public string Post()
{
return $"POST 請求";
}
public string Delete()
{
return $"DELETE 請求";
}
public string Put()
{
return $"PUT 請求";
}
public string Patch()
{
return $"PATCH 請求";
}
}
}
文檔傳送門://monksoul.gitee.io/furion/docs/dynamic-api-controller
7. 統一結果規範化處理
Furion
提供了非常靈活的方式去規範化 WebApi
的返回結果,使其採用統一規範的結果返回。
using Furion.DependencyInjection;
using Furion.Utilities;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Furion.UnifyResult
{
/// <summary>
/// RESTful 風格返回值
/// </summary>
[SkipScan, UnifyModel(typeof(RESTfulResult<>))]
public class RESTfulResultProvider : IUnifyResultProvider
{
/// <summary>
/// 異常返回值
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public IActionResult OnException(ExceptionContext context)
{
// 解析異常資訊
var (ErrorCode, ErrorContent) = UnifyContext.GetExceptionMetadata(context);
return new JsonResult(new RESTfulResult<object>
{
StatusCode = ErrorCode,
Succeeded = false,
Data = null,
Errors = ErrorContent,
Extras = UnifyContext.Take(),
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
});
}
/// <summary>
/// 成功返回值
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public IActionResult OnSucceeded(ActionExecutedContext context)
{
object data;
// 處理內容結果
if (context.Result is ContentResult contentResult) data = contentResult.Content;
// 處理對象結果
else if (context.Result is ObjectResult objectResult) data = objectResult.Value;
else if (context.Result is EmptyResult) data = null;
else return null;
return new JsonResult(new RESTfulResult<object>
{
StatusCode = context.Result is EmptyResult ? StatusCodes.Status204NoContent : StatusCodes.Status200OK, // 處理沒有返回值情況 204
Succeeded = true,
Data = data,
Errors = null,
Extras = UnifyContext.Take(),
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
});
}
/// <summary>
/// 驗證失敗返回值
/// </summary>
/// <param name="context"></param>
/// <param name="modelStates"></param>
/// <param name="validationResults"></param>
/// <param name="validateFailedMessage"></param>
/// <returns></returns>
public IActionResult OnValidateFailed(ActionExecutingContext context, ModelStateDictionary modelStates, Dictionary<string, IEnumerable<string>> validationResults, string validateFailedMessage)
{
return new JsonResult(new RESTfulResult<object>
{
StatusCode = StatusCodes.Status400BadRequest,
Succeeded = false,
Data = null,
Errors = validationResults,
Extras = UnifyContext.Take(),
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
});
}
/// <summary>
/// 處理輸出狀態碼
/// </summary>
/// <param name="context"></param>
/// <param name="statusCode"></param>
/// <returns></returns>
public async Task OnResponseStatusCodes(HttpContext context, int statusCode)
{
switch (statusCode)
{
// 處理 401 狀態碼
case StatusCodes.Status401Unauthorized:
await context.Response.WriteAsJsonAsync(new RESTfulResult<object>
{
StatusCode = StatusCodes.Status401Unauthorized,
Succeeded = false,
Data = null,
Errors = "401 Unauthorized",
Extras = UnifyContext.Take(),
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
}, JsonSerializerUtility.GetDefaultJsonSerializerOptions());
break;
// 處理 403 狀態碼
case StatusCodes.Status403Forbidden:
await context.Response.WriteAsJsonAsync(new RESTfulResult<object>
{
StatusCode = StatusCodes.Status403Forbidden,
Succeeded = false,
Data = null,
Errors = "403 Forbidden",
Extras = UnifyContext.Take(),
Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
}, JsonSerializerUtility.GetDefaultJsonSerializerOptions());
break;
default:
break;
}
}
}
}
文檔傳送門://monksoul.gitee.io/furion/docs/specification-document#67-統一返回值模型
8. 強大的 Swagger
在線文檔
Furion
內置了強大的 Swagger
規範化文檔,並賦予了更多強大的能力。
文檔傳送門://monksoul.gitee.io/furion/docs/specification-document
9. 非常強大的資料庫操作功能
文檔傳送門://monksoul.gitee.io/furion/docs/dbcontext
10. 異常處理最佳實踐
Furion
採用獨特的異常處理方案,可以大大的將異常和業務邏輯分離。
using Furion.DynamicApiController;
using Furion.FriendlyException;
namespace Furion.Application
{
public class FurAppService : IDynamicApiController
{
[IfException(typeof(ExceptionType), ErrorMessage = "特定異常類型全局攔截")]
[IfException(ErrorMessage = "全局異常攔截")]
[IfException(ErrorCodes.z1000, ErrorMessage = "我覆蓋了默認的:{0} 不能小於 {1}")]
[IfException(ErrorCodes.x1001, "格式化參數1", "格式化參數2", ErrorMessage = "我覆蓋了默認的:{0} 不能小於 {1}")]
[IfException(ErrorCodes.x1000, "格式化參數1", "格式化參數2")]
[IfException(ErrorCodes.SERVER_ERROR, "格式化參數1", "格式化參數2")]
public int Get(int id)
{
if (id < 3)
{
throw Oops.Oh(ErrorCodes.z1000, id, 3);
}
return id;
}
}
}
文檔傳送門://monksoul.gitee.io/furion/docs/friendly-exception
11. 強大且靈活的 SaaS 多租戶實現方式
文檔傳送門://monksoul.gitee.io/furion/docs/saas
12. 極易使用的對象依賴配置
Furion
提供了三種極易配置的介面依賴配置。
using Furion.Core;
using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
namespace Furion.Application
{
public interface IBusinessService<T>
{
Person Get(int id);
}
public class BusinessService<T> : IBusinessService<T>, ITransient
{
private readonly IRepository<Person> _personRepository;
public BusinessService(IRepository<Person> personRepository)
{
_personRepository = personRepository;
}
public Person Get(int id)
{
return _personRepository.Find(id);
}
}
}
文檔傳送門://monksoul.gitee.io/furion/docs/dependency-injection
13. 強大的視圖引擎
Furion
內置了強大的視圖引擎功能,完美支援 Razor
語法。
var result = _viewEngine.RunCompile(@"
Hello @Model.Name
@foreach(var item in Model.Items)
{
<p>@item</p>
}
", new TestModel
{
Name = "Furion",
Items = new[] { 3, 1, 2 }
});
文檔傳送門://monksoul.gitee.io/furion/docs/view-engine
結語
由於篇幅有效,這裡只是拋磚引玉,但 Furion
的亮點遠不止這些,可以查看文檔了解並學習。
文檔地址://monksoul.gitee.io/furion/
最後,喜歡 Furion 可以給個 Star,您的支援 Furion 才能越走越遠。