From aa30cc6e6679d444d7aa5d25eed0d87cd95c04f9 Mon Sep 17 00:00:00 2001 From: Monk Date: Wed, 9 Dec 2020 14:45:25 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A5=AF=20update=20documents.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 1 + README.md | 1 + docs/{3ab56fdf.d642cd04.js => 3ab56fdf.36e4c761.js} | 2 +- docs/404.html | 4 ++-- docs/{4c30b939.81ac0c15.js => 4c30b939.4e6c4238.js} | 2 +- docs/blog/index.html | 8 ++++---- docs/blog/tags/furion/index.html | 8 ++++---- docs/blog/tags/furos/index.html | 8 ++++---- docs/blog/tags/index.html | 4 ++-- docs/blog/tags/net-5/index.html | 8 ++++---- docs/blog/tags/net/index.html | 8 ++++---- docs/blog/tags/netcore/index.html | 8 ++++---- docs/blog/welcome/index.html | 10 +++++----- docs/{d3c206bc.d994b42e.js => d3c206bc.cc5f5f4c.js} | 2 +- docs/docs/answer/index.html | 4 ++-- docs/docs/appstartup/index.html | 4 ++-- docs/docs/auth-control/index.html | 4 ++-- docs/docs/author/index.html | 4 ++-- docs/docs/cache/index.html | 4 ++-- docs/docs/configuration/index.html | 4 ++-- docs/docs/contribute/index.html | 4 ++-- docs/docs/cors/index.html | 4 ++-- docs/docs/data-validation/index.html | 4 ++-- docs/docs/dbcontext-Interceptor/index.html | 4 ++-- docs/docs/dbcontext-add-or-update/index.html | 4 ++-- docs/docs/dbcontext-add/index.html | 4 ++-- docs/docs/dbcontext-audit/index.html | 4 ++-- docs/docs/dbcontext-batch/index.html | 4 ++-- docs/docs/dbcontext-code-first/index.html | 4 ++-- docs/docs/dbcontext-db-first/index.html | 4 ++-- docs/docs/dbcontext-delete/index.html | 4 ++-- docs/docs/dbcontext-entitytrigger/index.html | 4 ++-- docs/docs/dbcontext-filter/index.html | 4 ++-- docs/docs/dbcontext-function/index.html | 4 ++-- docs/docs/dbcontext-hight-query/index.html | 4 ++-- docs/docs/dbcontext-locator/index.html | 4 ++-- docs/docs/dbcontext-multi-database/index.html | 4 ++-- docs/docs/dbcontext-proc/index.html | 4 ++-- docs/docs/dbcontext-query/index.html | 4 ++-- docs/docs/dbcontext-read-write/index.html | 4 ++-- docs/docs/dbcontext-repository/index.html | 4 ++-- docs/docs/dbcontext-seed-data/index.html | 4 ++-- docs/docs/dbcontext-sql-proxy/index.html | 4 ++-- docs/docs/dbcontext-sql-template/index.html | 4 ++-- docs/docs/dbcontext-sql/index.html | 4 ++-- docs/docs/dbcontext-update/index.html | 4 ++-- docs/docs/dbcontext-view/index.html | 4 ++-- docs/docs/dbcontext/index.html | 4 ++-- docs/docs/dependency-injection/index.html | 4 ++-- docs/docs/deploy/index.html | 4 ++-- docs/docs/devops/index.html | 4 ++-- docs/docs/dynamic-api-controller/index.html | 4 ++-- docs/docs/entity/index.html | 4 ++-- docs/docs/errors/index.html | 4 ++-- docs/docs/event-bus/index.html | 4 ++-- docs/docs/friendly-exception/index.html | 4 ++-- docs/docs/get-start/index.html | 4 ++-- docs/docs/gooduse/index.html | 4 ++-- docs/docs/grpc/index.html | 4 ++-- docs/docs/http/index.html | 4 ++-- docs/docs/index.html | 10 +++++----- docs/docs/job/index.html | 4 ++-- docs/docs/local-language/index.html | 4 ++-- docs/docs/logging/index.html | 4 ++-- docs/docs/object-mapper/index.html | 4 ++-- docs/docs/options/index.html | 4 ++-- docs/docs/performance/index.html | 4 ++-- docs/docs/process-service/index.html | 4 ++-- docs/docs/reference/index.html | 4 ++-- docs/docs/saas/index.html | 4 ++-- docs/docs/signalr/index.html | 4 ++-- docs/docs/source/index.html | 4 ++-- docs/docs/specification-document/index.html | 4 ++-- docs/docs/split-db/index.html | 4 ++-- docs/docs/template/index.html | 4 ++-- docs/docs/tran/index.html | 4 ++-- docs/docs/unittest/index.html | 4 ++-- docs/docs/view-engine/index.html | 4 ++-- docs/index.html | 4 ++-- ...ntime~main.02007f49.js => runtime~main.2ee33f4e.js} | 2 +- handbook/blog/2020-08-19-welcome.mdx | 1 + .../{3ab56fdf.606edfc0.js => 3ab56fdf.f902488f.js} | 2 +- handbook/build/404.html | 4 ++-- .../{4c30b939.242cc4f5.js => 4c30b939.b9285c57.js} | 2 +- handbook/build/blog/index.html | 8 ++++---- handbook/build/blog/tags/furion/index.html | 8 ++++---- handbook/build/blog/tags/furos/index.html | 8 ++++---- handbook/build/blog/tags/index.html | 4 ++-- handbook/build/blog/tags/net-5/index.html | 8 ++++---- handbook/build/blog/tags/net/index.html | 8 ++++---- handbook/build/blog/tags/netcore/index.html | 8 ++++---- handbook/build/blog/welcome/index.html | 10 +++++----- .../{d3c206bc.816569fe.js => d3c206bc.a5d72d34.js} | 2 +- handbook/build/docs/answer/index.html | 4 ++-- handbook/build/docs/appstartup/index.html | 4 ++-- handbook/build/docs/auth-control/index.html | 4 ++-- handbook/build/docs/author/index.html | 4 ++-- handbook/build/docs/cache/index.html | 4 ++-- handbook/build/docs/configuration/index.html | 4 ++-- handbook/build/docs/contribute/index.html | 4 ++-- handbook/build/docs/cors/index.html | 4 ++-- handbook/build/docs/data-validation/index.html | 4 ++-- handbook/build/docs/dbcontext-Interceptor/index.html | 4 ++-- handbook/build/docs/dbcontext-add-or-update/index.html | 4 ++-- handbook/build/docs/dbcontext-add/index.html | 4 ++-- handbook/build/docs/dbcontext-audit/index.html | 4 ++-- handbook/build/docs/dbcontext-batch/index.html | 4 ++-- handbook/build/docs/dbcontext-code-first/index.html | 4 ++-- handbook/build/docs/dbcontext-db-first/index.html | 4 ++-- handbook/build/docs/dbcontext-delete/index.html | 4 ++-- handbook/build/docs/dbcontext-entitytrigger/index.html | 4 ++-- handbook/build/docs/dbcontext-filter/index.html | 4 ++-- handbook/build/docs/dbcontext-function/index.html | 4 ++-- handbook/build/docs/dbcontext-hight-query/index.html | 4 ++-- handbook/build/docs/dbcontext-locator/index.html | 4 ++-- .../build/docs/dbcontext-multi-database/index.html | 4 ++-- handbook/build/docs/dbcontext-proc/index.html | 4 ++-- handbook/build/docs/dbcontext-query/index.html | 4 ++-- handbook/build/docs/dbcontext-read-write/index.html | 4 ++-- handbook/build/docs/dbcontext-repository/index.html | 4 ++-- handbook/build/docs/dbcontext-seed-data/index.html | 4 ++-- handbook/build/docs/dbcontext-sql-proxy/index.html | 4 ++-- handbook/build/docs/dbcontext-sql-template/index.html | 4 ++-- handbook/build/docs/dbcontext-sql/index.html | 4 ++-- handbook/build/docs/dbcontext-update/index.html | 4 ++-- handbook/build/docs/dbcontext-view/index.html | 4 ++-- handbook/build/docs/dbcontext/index.html | 4 ++-- handbook/build/docs/dependency-injection/index.html | 4 ++-- handbook/build/docs/deploy/index.html | 4 ++-- handbook/build/docs/devops/index.html | 4 ++-- handbook/build/docs/dynamic-api-controller/index.html | 4 ++-- handbook/build/docs/entity/index.html | 4 ++-- handbook/build/docs/errors/index.html | 4 ++-- handbook/build/docs/event-bus/index.html | 4 ++-- handbook/build/docs/friendly-exception/index.html | 4 ++-- handbook/build/docs/get-start/index.html | 4 ++-- handbook/build/docs/gooduse/index.html | 4 ++-- handbook/build/docs/grpc/index.html | 4 ++-- handbook/build/docs/http/index.html | 4 ++-- handbook/build/docs/index.html | 10 +++++----- handbook/build/docs/job/index.html | 4 ++-- handbook/build/docs/local-language/index.html | 4 ++-- handbook/build/docs/logging/index.html | 4 ++-- handbook/build/docs/object-mapper/index.html | 4 ++-- handbook/build/docs/options/index.html | 4 ++-- handbook/build/docs/performance/index.html | 4 ++-- handbook/build/docs/process-service/index.html | 4 ++-- handbook/build/docs/reference/index.html | 4 ++-- handbook/build/docs/saas/index.html | 4 ++-- handbook/build/docs/signalr/index.html | 4 ++-- handbook/build/docs/source/index.html | 4 ++-- handbook/build/docs/specification-document/index.html | 4 ++-- handbook/build/docs/split-db/index.html | 4 ++-- handbook/build/docs/template/index.html | 4 ++-- handbook/build/docs/tran/index.html | 4 ++-- handbook/build/docs/unittest/index.html | 4 ++-- handbook/build/docs/view-engine/index.html | 4 ++-- handbook/build/index.html | 4 ++-- ...ntime~main.45113da2.js => runtime~main.46b3fd00.js} | 2 +- handbook/docs/introduce.mdx | 1 + 160 files changed, 344 insertions(+), 340 deletions(-) rename docs/{3ab56fdf.d642cd04.js => 3ab56fdf.36e4c761.js} (75%) rename docs/{4c30b939.81ac0c15.js => 4c30b939.4e6c4238.js} (76%) rename docs/{d3c206bc.d994b42e.js => d3c206bc.cc5f5f4c.js} (99%) rename docs/{runtime~main.02007f49.js => runtime~main.2ee33f4e.js} (96%) rename handbook/build/{3ab56fdf.606edfc0.js => 3ab56fdf.f902488f.js} (76%) rename handbook/build/{4c30b939.242cc4f5.js => 4c30b939.b9285c57.js} (75%) rename handbook/build/{d3c206bc.816569fe.js => d3c206bc.a5d72d34.js} (99%) rename handbook/build/{runtime~main.45113da2.js => runtime~main.46b3fd00.js} (78%) diff --git a/README.en.md b/README.en.md index 4227a75e200..f44fe1a04f0 100644 --- a/README.en.md +++ b/README.en.md @@ -257,6 +257,7 @@ docker run --name furion -p 5000:80 furion:v1.4.3 - 泉州市润海信息科技有限公司 - 成都市彼岸里信息科技有限公司 - 福建省山水生活服务集团有限公司 +- 安徽宝典网络科技有限公司 如果您的项目使用到 `Furion` 开发,可以告诉我们。 diff --git a/README.md b/README.md index 4227a75e200..f44fe1a04f0 100644 --- a/README.md +++ b/README.md @@ -257,6 +257,7 @@ docker run --name furion -p 5000:80 furion:v1.4.3 - 泉州市润海信息科技有限公司 - 成都市彼岸里信息科技有限公司 - 福建省山水生活服务集团有限公司 +- 安徽宝典网络科技有限公司 如果您的项目使用到 `Furion` 开发,可以告诉我们。 diff --git a/docs/3ab56fdf.d642cd04.js b/docs/3ab56fdf.36e4c761.js similarity index 75% rename from docs/3ab56fdf.d642cd04.js rename to docs/3ab56fdf.36e4c761.js index 0d6eb88e38f..2291d0312bc 100644 --- a/docs/3ab56fdf.d642cd04.js +++ b/docs/3ab56fdf.36e4c761.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[22],{154:function(e,t,a){"use strict";a.d(t,"a",(function(){return O})),a.d(t,"b",(function(){return g}));var n=a(0),b=a.n(n);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function c(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function l(e){for(var t=1;t=0||(b[a]=e[a]);return b}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(b[a]=e[a])}return b}var p=b.a.createContext({}),o=function(e){var t=b.a.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},O=function(e){var t=o(e.components);return b.a.createElement(p.Provider,{value:t},e.children)},j={inlineCode:"code",wrapper:function(e){var t=e.children;return b.a.createElement(b.a.Fragment,{},t)}},m=b.a.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),O=o(a),m=n,g=O["".concat(c,".").concat(m)]||O[m]||j[m]||r;return a?b.a.createElement(g,l(l({ref:t},p),{},{components:a})):b.a.createElement(g,l({ref:t},p))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,c=new Array(r);c[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:n,c[1]=l;for(var p=2;p=0||(b[a]=e[a]);return b}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(b[a]=e[a])}return b}var p=b.a.createContext({}),o=function(e){var t=b.a.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},O=function(e){var t=o(e.components);return b.a.createElement(p.Provider,{value:t},e.children)},j={inlineCode:"code",wrapper:function(e){var t=e.children;return b.a.createElement(b.a.Fragment,{},t)}},m=b.a.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),O=o(a),m=n,g=O["".concat(c,".").concat(m)]||O[m]||j[m]||r;return a?b.a.createElement(g,l(l({ref:t},p),{},{components:a})):b.a.createElement(g,l({ref:t},p))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,c=new Array(r);c[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:n,c[1]=l;for(var p=2;p Page Not Found | Furion - +

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/docs/4c30b939.81ac0c15.js b/docs/4c30b939.4e6c4238.js similarity index 76% rename from docs/4c30b939.81ac0c15.js rename to docs/4c30b939.4e6c4238.js index 341b03f2fc5..ca72c79358a 100644 --- a/docs/4c30b939.81ac0c15.js +++ b/docs/4c30b939.4e6c4238.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[27],{154:function(e,t,a){"use strict";a.d(t,"a",(function(){return j})),a.d(t,"b",(function(){return u}));var n=a(0),b=a.n(n);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function c(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function l(e){for(var t=1;t=0||(b[a]=e[a]);return b}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(b[a]=e[a])}return b}var p=b.a.createContext({}),O=function(e){var t=b.a.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},j=function(e){var t=O(e.components);return b.a.createElement(p.Provider,{value:t},e.children)},o={inlineCode:"code",wrapper:function(e){var t=e.children;return b.a.createElement(b.a.Fragment,{},t)}},m=b.a.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),j=O(a),m=n,u=j["".concat(c,".").concat(m)]||j[m]||o[m]||r;return a?b.a.createElement(u,l(l({ref:t},p),{},{components:a})):b.a.createElement(u,l({ref:t},p))}));function u(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,c=new Array(r);c[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:n,c[1]=l;for(var p=2;p=0||(b[a]=e[a]);return b}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(b[a]=e[a])}return b}var p=b.a.createContext({}),O=function(e){var t=b.a.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},j=function(e){var t=O(e.components);return b.a.createElement(p.Provider,{value:t},e.children)},o={inlineCode:"code",wrapper:function(e){var t=e.children;return b.a.createElement(b.a.Fragment,{},t)}},m=b.a.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),j=O(a),m=n,u=j["".concat(c,".").concat(m)]||j[m]||o[m]||r;return a?b.a.createElement(u,l(l({ref:t},p),{},{components:a})):b.a.createElement(u,l({ref:t},p))}));function u(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,c=new Array(r);c[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:n,c[1]=l;for(var p=2;p Blog | Furion - + @@ -18,14 +18,14 @@ - +

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/docs/blog/tags/furion/index.html b/docs/blog/tags/furion/index.html index 75dbe3f7166..966b24f470e 100644 --- a/docs/blog/tags/furion/index.html +++ b/docs/blog/tags/furion/index.html @@ -6,7 +6,7 @@ Posts tagged "furion" | Furion - + @@ -18,14 +18,14 @@ - +

1 post tagged with "furion"

View All Tags

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/docs/blog/tags/furos/index.html b/docs/blog/tags/furos/index.html index 8f9e6916aa6..8d154c556b2 100644 --- a/docs/blog/tags/furos/index.html +++ b/docs/blog/tags/furos/index.html @@ -6,7 +6,7 @@ Posts tagged "furos" | Furion - + @@ -18,14 +18,14 @@ - +

1 post tagged with "furos"

View All Tags

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/docs/blog/tags/index.html b/docs/blog/tags/index.html index 2bca3d89d85..e33119cb5b6 100644 --- a/docs/blog/tags/index.html +++ b/docs/blog/tags/index.html @@ -6,7 +6,7 @@ Tags | Furion - + @@ -23,7 +23,7 @@ - + diff --git a/docs/blog/tags/net-5/index.html b/docs/blog/tags/net-5/index.html index 7d16c789788..607869e112b 100644 --- a/docs/blog/tags/net-5/index.html +++ b/docs/blog/tags/net-5/index.html @@ -6,7 +6,7 @@ Posts tagged ".net5" | Furion - + @@ -18,14 +18,14 @@ - +

1 post tagged with ".net5"

View All Tags

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/docs/blog/tags/net/index.html b/docs/blog/tags/net/index.html index 4eba7e068f6..973015a9c2f 100644 --- a/docs/blog/tags/net/index.html +++ b/docs/blog/tags/net/index.html @@ -6,7 +6,7 @@ Posts tagged ".net" | Furion - + @@ -18,14 +18,14 @@ - +

1 post tagged with ".net"

View All Tags

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/docs/blog/tags/netcore/index.html b/docs/blog/tags/netcore/index.html index e0c27066fdd..f511e4c2c7f 100644 --- a/docs/blog/tags/netcore/index.html +++ b/docs/blog/tags/netcore/index.html @@ -6,7 +6,7 @@ Posts tagged ".netcore" | Furion - + @@ -18,14 +18,14 @@ - +

1 post tagged with ".netcore"

View All Tags

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/docs/blog/welcome/index.html b/docs/blog/welcome/index.html index de1a582b2c9..a8c4d6f1060 100644 --- a/docs/blog/welcome/index.html +++ b/docs/blog/welcome/index.html @@ -6,7 +6,7 @@ Furion 介绍 | Furion - + @@ -18,13 +18,13 @@ - +
-

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

🌭 开源地址

🍿 Docker 镜像

  • Docker Hub 线上镜像
docker run --name furion -p 5000:80 monksoul/furion:v1.4.3
  • 手动 打包镜像

打开 CMD/Shell/PowerShell 进入 Furion 项目根目录打包 Furion 镜像:

docker build -t furion:v1.4.3 .

打包成功后,直接 docker run

docker run --name furion -p 5000:80 furion:v1.4.3

🥥 Furion 官方包

包类型名称版本描述
nugetFurionnugetFurion 总包
nugetFurion.Extras.Authentication.JwtBearernugetFurion Jwt 拓展包
nugetFurion.Extras.DependencyModel.CodeAnalysisnugetFurion 动态反射 拓展包

🍄 Furion 脚手架

模板类型名称版本描述
nugetFurion.Template.MvcnugetMvc 模板
nugetFurion.Template.ApinugetWebApi 模板
nugetFurion.Template.AppnugetMvc/WebApi 模板
nugetFurion.Template.RazornugetRazorPages 模板
nugetFurion.Template.RazorWithWebApinugetRazorPages/WebApi 模板
nugetFurion.Template.BlazornugetBlazor 模板
nugetFurion.Template.BlazorWithWebApinugetBlazor/WebApi 模板

如何使用脚手架

🍎 框架特点

  • 全新面貌:基于 .NET 5 平台,没有历史包袱
  • 极易入门:只需要一个 Inject() 即可完成配置
  • 极速开发:内置丰富的企业应用开发功能
  • 极少依赖:框架只依赖三个第三方包
  • 极其灵活:轻松面对多变复杂的需求
  • 极易维护:采用独特的架构思想,只为长久维护设计
  • 完整文档:提供完善的开发文档

🥞 架构设计

正在整理中...

🥝 功能模块

🥐 框架依赖

Furion 为了追求极速入门,极致性能,尽可能的不使用或减少第三方依赖。目前 Furion 仅集成了以下三个依赖:

麻雀虽小五脏俱全。Furion 即使只集成了这三个依赖,但是主流的 依赖注入/控制反转AOP 面向切面编程,事件总线数据验证数据库操作 等等一个都不少。

🥗 环境要求

  • Visual Studio 2019 16.8 +
  • .NET 5 SDK +
  • .Net Standard 2.1 +

🥪 支持平台

  • 运行环境
    • Windows
    • Linux
    • MacOS
    • Docker/K8S/K3S/Rancher
    • Xamarin/MAUI
  • 数据库
    • SqlServer
    • Sqlite
    • Azure Cosmos
    • MySql
    • MariaDB
    • PostgreSQL
    • InMemoryDatabase
    • Oracle(并未完全适配
    • Firebird
    • 达梦数据库
  • 应用部署
    • Kestrel
    • Nginx
    • Jexus
    • IIS
    • Apache
    • PM2
    • Supervisor
    • 单文件
    • 容器(Docker/K8S/K3S/Rancher)

🍖 关于性能

Furion 目前采用 Visual Studio 2019 16.8 自带性能测试和 JMeter 进行测试,由于篇幅有限,只贴部分测试图,测试结果如下:


🍚 关于作者

一个拥有 12 年开发经验 .NETer。喜欢分享,喜欢新技术,在互联网多个技术领域皆有涉猎,dotNET China MIP,同时多次获得开源中国 Gitee 授予 GVP 证书。

🍤 项目成员

🎈 欢迎更多的开发者加入 Furion 大家庭。

🍝 他们都在用

  • 百签科技(广东)有限公司
  • 码为科技(广州)有限公司
  • 广州启顺国际货运代理有限公司
  • 森丰供应链服务(广州)有限公司
  • 中山赢友网络科技有限公司
  • 中山模思软件科技有限公司
  • 珠海市恒泰新软件有限责任公司
  • 珠海思诺锐创软件有限公司
  • 深圳市易胜科技有限公司
  • 重庆虫儿飞科技有限公司
  • 重庆林木森科技有限公司
  • 深圳市品立方科技有限公司
  • 上海奥达科股份有限公司
  • 中山市泓升软件科技有限公司
  • 唐山天权建筑科技有限公司
  • 北京帝龙科技有限公司
  • 深圳市希立网络有限公司
  • 广州市飞帆计算机技术有限公司
  • 泉州市润海信息科技有限公司
  • 成都市彼岸里信息科技有限公司
  • 福建省山水生活服务集团有限公司

如果您的项目使用到 Furion 开发,可以告诉我们。

🍻 贡献代码

Furion 遵循 Apache-2.0 开源协议,欢迎大家提交 PRIssue

如果要为项目做出贡献,请查看贡献指南。

🍍 捐赠列表

注:排序按捐赠顺序书写

捐赠人昵称捐赠金额(元)附语
🤴 爱吃油麦菜100感谢您的开源项目!
👳‍♂️ 麦壳饼200感谢您的开源项目!
👨 Sun100感谢您的开源项目!
👶 d61761720感谢您的开源项目!
👦 Diqiguoji00816.66见贤思齐
👲 nodyang100感谢您的开源项目!
👳‍♀️ mictxd100吹过的牛都实现。
🧓 欧流全10希望将来超越 Spring
👨‍⚕️ lionkon10...看了框架感觉拿来学习是很不错的...
😤 好人!10Nice 的小僧,我们的 dotnetchina 马上火起来了
😮 木木 Woody10感谢您的开源项目!
😚 Joker HouQQ 超级会员一个月
🤠 ccdfzQQ 专属红包 199
🌝 天夫李总支付宝 6666Furion 非常有意思,持续关注
😝 六尘子微信红包 199公司已经使用,小小敬意
🤠 ccdfzQQ 专属红包 200赞助一根内存条
🤑 邓亮灯28.88感谢您的开源项目!
😬 天道酬勤微信二维码 188小小心意
🥰 却月居士QQ 专属红包 100恭喜发财
🤩 鲁旭100感谢您的开源项目!
😬 散客行微信二维码 666终于找到一个不错的框架
😌 本心100项目功能很强大
🙆‍♂️ 毕业生100请你喝杯咖啡
🦹‍♀️ 猪鼻子微信二维码 668
🧟‍♂️ 明年·今日200使用的框架里最爽的,最理想的!加油
👨‍🎓 过去的过去50感谢您的开源项目!
👨‍🔧 万里兮100新公司的第一个项目从 Furion 开始
👴 Muphalem20很热心很亲切的开发者,加油!
💂‍♂️ 吃锅巴的码农微信二维码 500就冲你的文档写得好!
🤴 三重罗生门微信红包 200下次烤鱼你请!

非常感谢您们的支持,正是因为您们,中国开源才可以越走越远,Furion 越走越远。

🥔 QQ 交流群

🧆 友情链接

👉 Furion 👉 SqlSugar 👉 Layx 👉 t-io 👉 ThinkPHP 👉 Hutool 👉 BootstrapAdmin 👉 BootstrapBlazor 👉 IoTSharp 👉 Anno.Core 👉 WaterCloud

+

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

🌭 开源地址

🍿 Docker 镜像

  • Docker Hub 线上镜像
docker run --name furion -p 5000:80 monksoul/furion:v1.4.3
  • 手动 打包镜像

打开 CMD/Shell/PowerShell 进入 Furion 项目根目录打包 Furion 镜像:

docker build -t furion:v1.4.3 .

打包成功后,直接 docker run

docker run --name furion -p 5000:80 furion:v1.4.3

🥥 Furion 官方包

包类型名称版本描述
nugetFurionnugetFurion 总包
nugetFurion.Extras.Authentication.JwtBearernugetFurion Jwt 拓展包
nugetFurion.Extras.DependencyModel.CodeAnalysisnugetFurion 动态反射 拓展包

🍄 Furion 脚手架

模板类型名称版本描述
nugetFurion.Template.MvcnugetMvc 模板
nugetFurion.Template.ApinugetWebApi 模板
nugetFurion.Template.AppnugetMvc/WebApi 模板
nugetFurion.Template.RazornugetRazorPages 模板
nugetFurion.Template.RazorWithWebApinugetRazorPages/WebApi 模板
nugetFurion.Template.BlazornugetBlazor 模板
nugetFurion.Template.BlazorWithWebApinugetBlazor/WebApi 模板

如何使用脚手架

🍎 框架特点

  • 全新面貌:基于 .NET 5 平台,没有历史包袱
  • 极易入门:只需要一个 Inject() 即可完成配置
  • 极速开发:内置丰富的企业应用开发功能
  • 极少依赖:框架只依赖三个第三方包
  • 极其灵活:轻松面对多变复杂的需求
  • 极易维护:采用独特的架构思想,只为长久维护设计
  • 完整文档:提供完善的开发文档

🥞 架构设计

正在整理中...

🥝 功能模块

🥐 框架依赖

Furion 为了追求极速入门,极致性能,尽可能的不使用或减少第三方依赖。目前 Furion 仅集成了以下三个依赖:

麻雀虽小五脏俱全。Furion 即使只集成了这三个依赖,但是主流的 依赖注入/控制反转AOP 面向切面编程,事件总线数据验证数据库操作 等等一个都不少。

🥗 环境要求

  • Visual Studio 2019 16.8 +
  • .NET 5 SDK +
  • .Net Standard 2.1 +

🥪 支持平台

  • 运行环境
    • Windows
    • Linux
    • MacOS
    • Docker/K8S/K3S/Rancher
    • Xamarin/MAUI
  • 数据库
    • SqlServer
    • Sqlite
    • Azure Cosmos
    • MySql
    • MariaDB
    • PostgreSQL
    • InMemoryDatabase
    • Oracle(并未完全适配
    • Firebird
    • 达梦数据库
  • 应用部署
    • Kestrel
    • Nginx
    • Jexus
    • IIS
    • Apache
    • PM2
    • Supervisor
    • 单文件
    • 容器(Docker/K8S/K3S/Rancher)

🍖 关于性能

Furion 目前采用 Visual Studio 2019 16.8 自带性能测试和 JMeter 进行测试,由于篇幅有限,只贴部分测试图,测试结果如下:


🍚 关于作者

一个拥有 12 年开发经验 .NETer。喜欢分享,喜欢新技术,在互联网多个技术领域皆有涉猎,dotNET China MIP,同时多次获得开源中国 Gitee 授予 GVP 证书。

🍤 项目成员

🎈 欢迎更多的开发者加入 Furion 大家庭。

🍝 他们都在用

  • 百签科技(广东)有限公司
  • 码为科技(广州)有限公司
  • 广州启顺国际货运代理有限公司
  • 森丰供应链服务(广州)有限公司
  • 中山赢友网络科技有限公司
  • 中山模思软件科技有限公司
  • 珠海市恒泰新软件有限责任公司
  • 珠海思诺锐创软件有限公司
  • 深圳市易胜科技有限公司
  • 重庆虫儿飞科技有限公司
  • 重庆林木森科技有限公司
  • 深圳市品立方科技有限公司
  • 上海奥达科股份有限公司
  • 中山市泓升软件科技有限公司
  • 唐山天权建筑科技有限公司
  • 北京帝龙科技有限公司
  • 深圳市希立网络有限公司
  • 广州市飞帆计算机技术有限公司
  • 泉州市润海信息科技有限公司
  • 成都市彼岸里信息科技有限公司
  • 福建省山水生活服务集团有限公司
  • 安徽宝典网络科技有限公司

如果您的项目使用到 Furion 开发,可以告诉我们。

🍻 贡献代码

Furion 遵循 Apache-2.0 开源协议,欢迎大家提交 PRIssue

如果要为项目做出贡献,请查看贡献指南。

🍍 捐赠列表

注:排序按捐赠顺序书写

捐赠人昵称捐赠金额(元)附语
🤴 爱吃油麦菜100感谢您的开源项目!
👳‍♂️ 麦壳饼200感谢您的开源项目!
👨 Sun100感谢您的开源项目!
👶 d61761720感谢您的开源项目!
👦 Diqiguoji00816.66见贤思齐
👲 nodyang100感谢您的开源项目!
👳‍♀️ mictxd100吹过的牛都实现。
🧓 欧流全10希望将来超越 Spring
👨‍⚕️ lionkon10...看了框架感觉拿来学习是很不错的...
😤 好人!10Nice 的小僧,我们的 dotnetchina 马上火起来了
😮 木木 Woody10感谢您的开源项目!
😚 Joker HouQQ 超级会员一个月
🤠 ccdfzQQ 专属红包 199
🌝 天夫李总支付宝 6666Furion 非常有意思,持续关注
😝 六尘子微信红包 199公司已经使用,小小敬意
🤠 ccdfzQQ 专属红包 200赞助一根内存条
🤑 邓亮灯28.88感谢您的开源项目!
😬 天道酬勤微信二维码 188小小心意
🥰 却月居士QQ 专属红包 100恭喜发财
🤩 鲁旭100感谢您的开源项目!
😬 散客行微信二维码 666终于找到一个不错的框架
😌 本心100项目功能很强大
🙆‍♂️ 毕业生100请你喝杯咖啡
🦹‍♀️ 猪鼻子微信二维码 668
🧟‍♂️ 明年·今日200使用的框架里最爽的,最理想的!加油
👨‍🎓 过去的过去50感谢您的开源项目!
👨‍🔧 万里兮100新公司的第一个项目从 Furion 开始
👴 Muphalem20很热心很亲切的开发者,加油!
💂‍♂️ 吃锅巴的码农微信二维码 500就冲你的文档写得好!
🤴 三重罗生门微信红包 200下次烤鱼你请!

非常感谢您们的支持,正是因为您们,中国开源才可以越走越远,Furion 越走越远。

🥔 QQ 交流群

🧆 友情链接

👉 Furion 👉 SqlSugar 👉 Layx 👉 t-io 👉 ThinkPHP 👉 Hutool 👉 BootstrapAdmin 👉 BootstrapBlazor 👉 IoTSharp 👉 Anno.Core 👉 WaterCloud

- + @@ -36,6 +36,6 @@ - + \ No newline at end of file diff --git a/docs/d3c206bc.d994b42e.js b/docs/d3c206bc.cc5f5f4c.js similarity index 99% rename from docs/d3c206bc.d994b42e.js rename to docs/d3c206bc.cc5f5f4c.js index db1c13f096f..a016b263804 100644 --- a/docs/d3c206bc.d994b42e.js +++ b/docs/d3c206bc.cc5f5f4c.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[63],{128:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return b})),n.d(t,"metadata",(function(){return c})),n.d(t,"rightToc",(function(){return l})),n.d(t,"default",(function(){return p}));var r=n(3),a=n(7),o=(n(0),n(154)),i=n(156),b={slug:"welcome",title:"Furion \u4ecb\u7ecd",author:"dotnet\u4e2d\u56fd",author_title:"\u4e3a\u4e2d\u56fd .NET \u5f00\u53d1\u8005\u63d0\u4f9b\u4f18\u8d28\u7684\u8d44\u8baf\u548c\u6280\u672f\u5206\u4eab\u3002",author_url:"https://furion.pro",author_image_url:"https://i.loli.net/2020/10/01/94AxjHp21aPKQWd.png",tags:["furion","furos",".net",".netcore",".net5"]},c={permalink:"/blog/welcome",editUrl:"https://gitee.com/monksoul/Furion/tree/master/handbook/blog/2020-08-19-welcome.mdx",source:"@site/blog\\2020-08-19-welcome.mdx",description:"=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=a.a.createContext({}),u=function(e){var t=a.a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):b(b({},t),e)),n},p=function(e){var t=u(e.components);return a.a.createElement(l.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.a.createElement(a.a.Fragment,{},t)}},m=a.a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,O=p["".concat(i,".").concat(m)]||p[m]||s[m]||o;return n?a.a.createElement(O,b(b({ref:t},l),{},{components:n})):a.a.createElement(O,b({ref:t},l))}));function O(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var b={};for(var c in t)hasOwnProperty.call(t,c)&&(b[c]=t[c]);b.originalType=e,b.mdxType="string"==typeof e?e:r,i[1]=b;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=a.a.createContext({}),u=function(e){var t=a.a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):b(b({},t),e)),n},p=function(e){var t=u(e.components);return a.a.createElement(l.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.a.createElement(a.a.Fragment,{},t)}},m=a.a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,O=p["".concat(i,".").concat(m)]||p[m]||s[m]||o;return n?a.a.createElement(O,b(b({ref:t},l),{},{components:n})):a.a.createElement(O,b({ref:t},l))}));function O(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var b={};for(var c in t)hasOwnProperty.call(t,c)&&(b[c]=t[c]);b.originalType=e,b.mdxType="string"==typeof e?e:r,i[1]=b;for(var l=2;l 29.1 常见问题 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/appstartup/index.html b/docs/docs/appstartup/index.html index 96b24de6fde..d5c66ec3489 100644 --- a/docs/docs/appstartup/index.html +++ b/docs/docs/appstartup/index.html @@ -6,7 +6,7 @@ 3. 应用启动 | Furion - + @@ -52,7 +52,7 @@
namespace Furion.Web.Entry
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
}
}
}
Startup.cs 代码迁移

只需要将 ConfigureServicesConfigure 方法代码迁移到 Furion.Web.Core.Startup.cs 中即可,而 Startup.cs 中两个方法留空即可。

非常简单吧。我们后续创建任何 MVCRazorPagesBlazor 项目只需要添加 Furion.Web.Core 引用和调用 Inject() 即可。

3.6 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/auth-control/index.html b/docs/docs/auth-control/index.html index 313c01cf154..f5583c87a04 100644 --- a/docs/docs/auth-control/index.html +++ b/docs/docs/auth-control/index.html @@ -6,7 +6,7 @@ 14. 安全鉴权 | Furion - + @@ -31,7 +31,7 @@
/// <summary>
/// 检查权限
/// </summary>
/// <param name="httpContext"></param>
/// <returns></returns>
private static bool CheckAuthorzie(DefaultHttpContext httpContext)
{
// 获取权限特性
var securityDefineAttribute = httpContext.GetMetadata<SecurityDefineAttribute>();
if (securityDefineAttribute == null) return true;
return App.GetService<IAuthorizationManager>().CheckSecurity(securityDefineAttribute.ResourceId);
}
}
}

之后注册 JwtHandler 即可:

services.AddJwt<JwtHandler>();

14.4 授权特性及全局授权

默认情况下,所有的路由都是允许匿名访问的,所以如果需要对某个 ActionController 设定授权访问,只需要在 ActionController[AppAuthorize][Authorize] 特性即可。

如果需要对特定的 ActionController 允许匿名访问,则贴 [AllowAnonymous] 即可。

14.4.1 全局授权

services.AddJwt<JwtHandler>(enableGlobalAuthorize:true);

14.4.2 匿名访问

如果需要对特定的 ActionController 允许匿名访问,则贴 [AllowAnonymous] 即可。

14.5 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 鉴权授权 知识可查阅 ASP.NET Core - 安全和标识 章节。

- + diff --git a/docs/docs/author/index.html b/docs/docs/author/index.html index 22e86e2cf23..09efc10254f 100644 --- a/docs/docs/author/index.html +++ b/docs/docs/author/index.html @@ -6,7 +6,7 @@ 1.2 关于作者 | Furion - + @@ -25,7 +25,7 @@

1.2 关于作者

互联网账号

  • 百小僧
  • Monk/MonkSoul

技术能力

自 2008 年 接触 IT 这个行业也有十余年了,在 后端(.NET/.NET Core/Java/PHP)、移动端(Xamarin/小程序/Java/Objective-C)、桌面端(WinForm/WPF/Electron)、前端(React/Vue/Angular/Node)等主流领域略知一二。

同时在技术培训领域也多有涉足。dotNET China MIP,同时多次获得开源中国 Gitee 授予 GVP 证书。

职业情况

自 2012 年 06 月 29 日创办一家高科技软件公司到至今,主要销售自主研发的家具 ERP 产品和港澳台及国外服务外包业务。

吃不起饭的时候也会接国内外包项目。

兴趣爱好

是个吃货,迷恋纹身文化,喜欢看抖音,看动漫,看美剧,看博客园、看开源中国、看 Github/Gitee。

对新技术颇感兴趣,喜欢开源事业,喜欢分享技术。

个人主页

https://gitee.com/monksoul

https://github.com/monksoul

- + diff --git a/docs/docs/cache/index.html b/docs/docs/cache/index.html index 81b09735bbd..dd1c87c8285 100644 --- a/docs/docs/cache/index.html +++ b/docs/docs/cache/index.html @@ -6,7 +6,7 @@ 13. 分布式缓存 | Furion - + @@ -45,7 +45,7 @@
await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);
return RedirectToPage();
}
}

13.6 分布式缓存建议

确定 IDistributedCache 最适合你的应用的实现时,请考虑以下事项:

  • 现有基础结构
  • 性能要求
  • 成本
  • 团队经验

缓存解决方案通常依赖于内存中的存储以快速检索缓存的数据,但是,内存是有限的资源,并且很昂贵。 仅将常用数据存储在缓存中。

通常,Redis 缓存提供比 SQL Server 缓存更高的吞吐量和更低的延迟。 但是,通常需要进行基准测试来确定缓存策略的性能特征。

SQL Server 用作分布式缓存后备存储时,对缓存使用同一数据库,并且应用的普通数据存储和检索会对这两种情况的性能产生负面影响。 建议使用分布式缓存后备存储的专用 SQL Server 实例。

13.7 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 分布式缓存 知识可查阅 ASP.NET Core - 分布式缓存 章节。

- + diff --git a/docs/docs/configuration/index.html b/docs/docs/configuration/index.html index 12da925931b..272a1ceb208 100644 --- a/docs/docs/configuration/index.html +++ b/docs/docs/configuration/index.html @@ -6,7 +6,7 @@ 4.1 配置 | Furion - + @@ -27,7 +27,7 @@
namespace Furion.Web.Entry.Controllers
{
[Route("api/[controller]")]
public class DefaultController : ControllerBase
{
[HttpGet]
public string Get()
{
return $@"名称:{App.Configuration["AppInfo:Name"]},
版本:{App.Configuration["AppInfo:Version"]},
公司:{App.Configuration["AppInfo:Company"]}";
}
}
}
依赖注入的方式

通过依赖注入注入实例有几种方式:

  • 构造函数注入方式
private readonly IConfiguration _configuration;
public DefaultController(IConfiguration configuration)
{
_configuration = configuration;
}
  • 参数注入方式 [FromServices]
public string Get([FromServices] IConfiguration configuration)
{
}
  • 属性注入方式
public IConfiguration Configuration { get; set; }

想了解更多关于《ASP.NET Core - 依赖注入》 知识

4.1.2.3 如何选择读取方式

  • 在可依赖注入类中,依赖注入 IConfiguration 读取
  • 在静态类/非依赖注入类中,选择 App.Configuration[jsonKey] 读取

4.1.3 路径符 查找节点

ASP.NET Core 中,配置采用 : 分隔符来读取分层配置数据。如上述例子中的 AppInfo:Name。如有更多层级数据则只需要通过 : 进入下一层节点即可。

假设我们有以下配置信息:

{
"AppInfo": {
"Name": "Furion",
"Version": "1.0.0",
"Company": {
"Name": "Baiqian",
"Address": {
"City": "中国",
"Province": "广东省",
"Detail": "中山市东区紫马公园西门"
}
}
}
}
var companyName = App.Configuration["AppInfo:Name"]; // => Furion

4.1.4 自定义配置文件

大多情况下,我们的配置只需要在 appsettings.json 中配置即可,但一些特殊情况下,我们希望某些组件或功能拥有独立的配置,这个时候就需要用到自定义配置,Furion 目前支持 .json.xml 两种方式配置,如:

Furion.Web.Entry/emailsetting.json
{
"outlook": {
"smtp": {
"server": "smtp.office365.com",
"port": "587",
"ssl": "STARTTLS"
},
"pop": {
"server": "outlook.office365.com",
"port": "995",
"ssl": "TLS"
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<MyKey>MyXMLFile Value</MyKey>
<Position>
<Title>Title from MyXMLFile</Title>
<Name>Name from MyXMLFile</Name>
</Position>
<Logging>
<LogLevel>
<Default>Information</Default>
<Microsoft>Warning</Microsoft>
</LogLevel>
</Logging>
</configuration>
xml 配置事项

如果采用 xml 配置,那么文件名必须以 .config.xml 结尾(不区分大小写)。

特别说明

Furion 框架会在启动时自动扫描每一个项目层根目录下的 *.json*.xml 文件加入配置中,所以无需手工配置。

新增 *.json*.xml 文件的属性复制到输出目录设置为始终复制,否则不会载入。另外配置文件不能出现重名,也就是保证整个项目中配置文件名字唯一。

同时 Furion 提供了非常灵活的方式支持自定义配置文件读取,如:

4.1.4.1 读取 emailsetting.json 配置

读取自定义配置文件和读取 appsettings.json 一致,系统会自动从多个配置文件中读取输入,如:

var smtpServer = App.Configuration["outlook:smtp:server"]; // => smtp.office365.com

4.1.4.2 排除特定配置文件

有些时候,我们不需要 .json.xml 自定载入配置中,我们只需要在启动层 appsettings.json 中添加 IgnoreConfigurationFiles 节点即可:

{
"IgnoreConfigurationFiles": ["runtime.json"]
}

4.1.5 不同环境读取

在实际应用开发中,我们可能会根据不同的环境加载不同的配置文件,如 数据库连接字符串

这时我们只需要遵循特定命名规范 {name}.{Environment}.json 即可。如:

  • appsettings.Development.json
  • appsettings.Staging.json
  • appsettings.Production.json
  • emailsetting.Development.json
  • emailsetting.Staging.json
  • emailsetting.Production.json

这时,ASP.NET Core 会在应用启动时自动加载不同环境的配置文件。

4.1.6 配置更改通知(热更新

.NET Core 应用程序中,配置支持更改通知,也就是热更新操作。一旦监听到 appsetting.json 或自定义配置文件发生变动,就会触发 OnChange 方法。代码如下:

var appInfoConfiguration = App.Configuration["AppInfo"];
ChangeToken.OnChange(() => appInfoConfiguration.GetReloadToken(), () =>
{
var name = appInfoConfiguration["Name"]; // 实时的最新值
var version = appInfoConfiguration["Version"]; // 实时的最新值
});

4.1.7 配置的优缺点

  • 优点

    • 能够在系统运行时快速读取
    • 无需额外配置
  • 缺点

    • 存在重复读取
    • 通过硬编码字符串读取,容易出错
    • 不能设置默认值
    • 不能在运行环境中动态配置
    • 不能验证配置有效性
    • 不支持更改通知

4.1.8 配置使用场景

如果只需要一次性读取配置信息,则使用配置,否则应该使用 《4.2 选项》代替。

4.1.9 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 配置 知识可查阅 ASP.NET Core - 配置 章节。

- + diff --git a/docs/docs/contribute/index.html b/docs/docs/contribute/index.html index d1252b43da9..0823e1ac620 100644 --- a/docs/docs/contribute/index.html +++ b/docs/docs/contribute/index.html @@ -6,7 +6,7 @@ 28. 贡献指南 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/cors/index.html b/docs/docs/cors/index.html index d86b4954130..023b76ff5af 100644 --- a/docs/docs/cors/index.html +++ b/docs/docs/cors/index.html @@ -6,7 +6,7 @@ 15. CORS 跨域 | Furion - + @@ -30,7 +30,7 @@
app.UseCorsAccessor();
// ...
}
}
}
特别注意

services.AddCorsAccessor(); 需在 services.AddControllers() 之前注册。

app.UseCorsAccessor(); 需在 app.UseRouting();app.UseAuthentication(); 之间注册。

15.4.2 配置允许跨域域名

小提醒

默认情况下,Furion 允许所有域名来源访问,也就是无需配置任何来源域名,另外前端也需要设置请求参数:withCredentials:false

如果需要指定特定域名,则添加以下配置即可:

{
"CorsAccessorSettings": {
"PolicyName": "自定义跨域策略名",
"WithOrigins": ["http://localhost:4200", "https://furion.pro"]
}
}

15.5 CorsAccessorSettings 配置

  • CorsAccessorSettings
    • PolicyName:跨域策略名,字符串类型,必填,默认 FurCorsAccessor
    • WithOrigins:允许跨域的域名列表,字符串数组类型,默认 [ "http://localhost:4200" ]
    • WithHeaders:请求表头,没有配置则允许所有表头,字符串数组类型
    • WithExposedHeaders:响应标头,字符串数组类型
    • WithMethods:设置跨域允许请求谓词,没有配置则允许所有,字符串数组类型
    • AllowCredentials:跨域请求中的凭据,bool 类型
    • SetPreflightMaxAge:设置预检过期时间,int 类型

15.6 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 跨域请求 知识可查阅 ASP.NET Core - 启用跨域请求 章节。

- + diff --git a/docs/docs/data-validation/index.html b/docs/docs/data-validation/index.html index ac258462c31..1a4c0fe9009 100644 --- a/docs/docs/data-validation/index.html +++ b/docs/docs/data-validation/index.html @@ -6,7 +6,7 @@ 8. 数据校验 | Furion - + @@ -77,7 +77,7 @@
namespace Furion.Application
{
public class FurAppService : IDynamicApiController
{
[TypeFilter(typeof(DataValidationFilter))]
public TestDto Post(TestDto testDto)
{
return testDto;
}
}
}

8.9.4 [ApiController] 控制器范围验证

[ApiController]Mvc 提供的控制器范围(含所有动作方法)的验证。

using Microsoft.AspNetCore.Mvc;
namespace Furion.Web.Entry.Controllers
{
[ApiController]
public class MvcController : Controller
{
public IActionResult Index()
{
return View();
}
}
}

8.10 MiniProfiler 查看

如下图所示:

8.11 多语言支持

文档整理中...

8.12 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-Interceptor/index.html b/docs/docs/dbcontext-Interceptor/index.html index 590a19e5e4a..f89949fafee 100644 --- a/docs/docs/dbcontext-Interceptor/index.html +++ b/docs/docs/dbcontext-Interceptor/index.html @@ -6,7 +6,7 @@ 9.24 数据库操作拦截器 | Furion - + @@ -58,7 +58,7 @@
// 提交数据库失败
public override void SaveChangesFailed(DbContextErrorEventData eventData)
{
base.SaveChangesFailed(eventData);
}
// 提交数据库失败(异步)
public override Task SaveChangesFailedAsync(DbContextErrorEventData eventData, CancellationToken cancellationToken = default)
{
return base.SaveChangesFailedAsync(eventData, cancellationToken);
}
}
}

9.24.2.4 SavedChangesEvent 拦截

Furion 框架中为所有 AppDbContext 子类都提供了三个可重写的方法,这三个方法分别由三个事件触发:

  • 提交更改之前 SavingChanges 事件:触发 void SavingChangesEvent(object sender, SavingChangesEventArgs e) 方法
  • 提交更改之后 SavedChanges 事件:触发 void SavedChangesEvent(object sender, SavedChangesEventArgs e) 方法
  • 提交更改失败 SaveChangesFailed 事件:触发 void SaveChangesFailedEvent(object sender, SaveChangesFailedEventArgs e) 方法

通过这三个事件我们可以在数据库做增、删、改时候做拦截,比如设置创建时间、更新时间或其他默认操作

如自动添加租户Id:

protected override void SavingChangesEvent(object sender, SavingChangesEventArgs e)
{
// 获取当前事件对应上下文
var dbContext = sender as FurDbContext;
// 获取所有新增和更新的实体
var entities = dbContext.ChangeTracker.Entries()
.Where(u => u.State == EntityState.Added || u.State == EntityState.Modified);
foreach (var entity in entities)
{
switch (entity.State)
{
// 自动设置租户Id
case EntityState.Added:
entity.Property(nameof(Entity.TenantId)).CurrentValue = GetTenantId();
break;
// 排除租户Id
case EntityState.Modified:
entity.Property(nameof(Entity.TenantId)).IsModified = false;
break;
}
}
}

9.24.3 注册自定义过滤器

定义好过滤器之后,我们需要在数据库上下文中注册:

services.AddSqlitePool<FurDbContext>(interceptors: new IInterceptor[] {
new SqlConnectionProfilerInterceptor(),
new DbContextSaveChangesInterceptor(),
new SqlCommandProfilerInterceptor()
});

9.24.4 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-add-or-update/index.html b/docs/docs/dbcontext-add-or-update/index.html index 5b6b59336f0..0c67d28080d 100644 --- a/docs/docs/dbcontext-add-or-update/index.html +++ b/docs/docs/dbcontext-add-or-update/index.html @@ -6,7 +6,7 @@ 9.7 新增或更新操作 | Furion - + @@ -103,7 +103,7 @@
// 示例七
await user.InsertOrUpdateExcludeNowAsync(new[] { u=>u.Name, u=>u.Age});
// 示例八
await user.InsertOrUpdateExcludeNowAsync(new[] {"Age", "Name"});

9.5.7 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-add/index.html b/docs/docs/dbcontext-add/index.html index b822cf95316..77765d7bede 100644 --- a/docs/docs/dbcontext-add/index.html +++ b/docs/docs/dbcontext-add/index.html @@ -6,7 +6,7 @@ 9.5 新增操作 | Furion - + @@ -54,7 +54,7 @@
// 示例二
await repository.InsertNowAsync(new List<User> { user, user2 });
// 示例三
await repository.InsertNowAsync(new[] {user, user2 });
小知识

所有带 Now 结尾的表示立即提交到数据库,也就是立即调用 SaveChangesSaveChangesAsync

9.5.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-audit/index.html b/docs/docs/dbcontext-audit/index.html index 593fcfad444..528463c0a97 100644 --- a/docs/docs/dbcontext-audit/index.html +++ b/docs/docs/dbcontext-audit/index.html @@ -6,7 +6,7 @@ 9.22 审计日志 | Furion - + @@ -38,7 +38,7 @@
object oldValue = null;
// 如果是新增数据,则 databaseValues 为空,所以需要判断一下
if (databaseValues != null)
{
oldValue = databaseValues[propName];
}
// 插入审计日志表
dbContext.Audits.Add(new Audit
{
Table = entityType.Name, // 表名
Column = propName, // 更新的列
NewValue = newValue, // 新值
OldValue = oldValue, // 旧值
CreatedTime = DateTime.Now, // 操作时间
UserId = userId, // 操作人
Operate = entity.State.ToString(); // 操作方式:新增、更新、删除
});
}
}
}
}
}
小知识

如果对性能有所要求,那么建议审计日志通过 日志组件 写入数据库,如,通过 Nlog、Log4Net 这些等:

// 插入审计日志表
dbContext.Audits.Add(new Audit
{
Table = entityType.Name, // 表名
Column = propName, // 更新的列
newValue = newValue, // 新值
OldValue = oldValue, // 旧值
CreatedTime = DateTime.Now, // 操作时间
UserId = userId, // 操作人
Operate = entity.State.ToString(); // 操作方式:新增、更新、删除
});

替换为:

logger.Information(JsonConvert.SerializeObject(new Audit
{
Table = entityType.Name, // 表名
Column = propName, // 更新的列
newValue = newValue, // 新值
OldValue = oldValue, // 旧值
CreatedTime = DateTime.Now, // 操作时间
UserId = userId, // 操作人
Operate = entity.State.ToString(); // 操作方式:新增、更新、删除
}));

通过上面的例子,我们就可以对数据库所有的新增、更新、删除进行监控了。

9.22.4 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-batch/index.html b/docs/docs/dbcontext-batch/index.html index d85e0fa7e07..779fd0e1ee1 100644 --- a/docs/docs/dbcontext-batch/index.html +++ b/docs/docs/dbcontext-batch/index.html @@ -6,7 +6,7 @@ 9.9 批量操作 | Furion - + @@ -33,7 +33,7 @@
// 根据条件批量更新
repository.Where(a => a.ItemId <= 500).BatchUpdate(a => new Item { Quantity = a.Quantity + 100 });
repository.Where(a => a.ItemId <= 500).BatchUpdate(new Item { Description = "Updated" });
await repository.Where(a => a.ItemId <= 500).BatchUpdateAsync(new Item { Description = "Updated" });
// 批量更新指定列
var updateColumns = new List<string> { nameof(Item.Quantity) };
var q = repository.Where(a => a.ItemId <= 500);
int affected = q.BatchUpdate(new Item { Description = "Updated" }, updateColumns);

9.9.3 批量操作性能

Operations\Rows100,000 EF100,000 EFBulk1,000,000 EFBulk
Insert38.98 s2.10 s17.99 s
Update109.25 s3.96 s31.45 s
Delete7.26 s2.04 s12.18 s
---------------------------------------------------------------
Together70.70 s5.88 s56.84 s

9.9.4 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 EFCore.BulkExtensions 知识可查阅 EFCore.BulkExtensions 开源仓库

- + diff --git a/docs/docs/dbcontext-code-first/index.html b/docs/docs/dbcontext-code-first/index.html index a5d47a25401..7b1ad9cd7db 100644 --- a/docs/docs/dbcontext-code-first/index.html +++ b/docs/docs/dbcontext-code-first/index.html @@ -6,7 +6,7 @@ 9.20 模型生成数据库 | Furion - + @@ -29,7 +29,7 @@
/// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
/// <summary>
/// 住址
/// </summary>
public string Address { get; set; }
}
}
实体约定

所有数据库实体必须直接或间接继承 IEntity 接口。

9.20.2.2 打开 程序包管理控制台

9.20.2.3 切换默认项目

程序包管理控制台 默认项目设置为 Furion.Database.Migrations

9.20.2.4 创建模型版本

Add-Migration v1.0.0
特别说明

v1.0.0 是此处数据库更改的版本号,可以写任何字符串,但推荐写版本号,每次 +1

最终命令如下:

PM> Add-Migration v1.0.0
Build started...
Build succeeded.
Microsoft.EntityFrameworkCore.Model.Validation[10400]
Sensitive data logging is enabled. Log entries and exception messages may include sensitive application data, this mode should only be enabled during development.
Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 5.0.0-rc.1.20451.13 initialized 'FurDbContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: SensitiveDataLoggingEnabled DetailedErrorsEnabled MaxPoolSize=100 MigrationsAssembly=Furion.Database.Migrations
To undo this action, use Remove-Migration.
PM>

生成成功后,Furion.Database.Migrations 项目下会新增 Migrations 文件夹(如果没有),同时本次的架构生成文件,如:

9.20.2.5 更新到数据库

Update-Database

执行该命令后,数据库就会自动根据模型生成对于的表。

小知识

如果 Update-Database 后面带字符串参数,则会自动还原数据库到指定版本,如:

Update-Database v0.0.3

将数据库还原到 v0.0.3 版本

9.20.3 更新模型

如果模型改变了,重复上面操作即可,如:

Add-Migration v1.0.1
Update-Database

9.20.4 导出 Sql

有些时候,我们没有直接更新数据库的权限,或者怕出问题,我们都会先生成 Sql 看看,这时候只需要通过 Script-Migration 导出即可,如:

Script-Migration

9.20.5 VS Code 方式

9.20.5.1 安装 dotnet ef

dotnet tool install --global dotnet-ef --version 5.0.0-rc.2.20475.6

9.20.5.2 cd 目录

通过 VS Code 打开 .sln 所在的目录,如:framework

之后进入 Furion.Database.Migrations 目录

cd Furion.Database.Migrations

9.20.5.3 执行命令

dotnet ef migrations add v1.0.0 -s "../Furion.Web.Entry"
dotnet ef database update -s "../Furion.Web.Entry"

9.20.6 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 正向工厂 知识可查阅 EF Core - 管理数据库架构 章节。

- + diff --git a/docs/docs/dbcontext-db-first/index.html b/docs/docs/dbcontext-db-first/index.html index 0cdfb0656a4..47036f4de1a 100644 --- a/docs/docs/dbcontext-db-first/index.html +++ b/docs/docs/dbcontext-db-first/index.html @@ -6,7 +6,7 @@ 9.19 数据库生成模型 | Furion - + @@ -62,7 +62,7 @@
}
}
Furion Tools v1.0.0 全部实体生成成功!
PM>

9.13.4 命令参数配置

Furion Tools Cli 支持多个参数配置,使用方法只需要在命令后面添加即可,如:

&"../tools/cli.ps1" -Context 数据库上下文名 -ConnectionName 连接字符串Key

支持参数如下:

  • -Tables:配置要生成的数据库表,数组类型,如果为空,则生成数据库所有表和视图。如:-Tables Person,PersonDetails
  • -Context:配置数据库上下文,默认 FurDbContext,如果有多个数据库上下文,则此参数必须配置
  • -ConnectionName:配置数据库连接字符串,对于 appsetting.json 中的 Key
  • -OutputDir:生成实体代码输出目录,默认为:./Furion.Core/Entities/
  • -DbProvider:数据库提供器,默认是 Microsoft.EntityFrameworkCore.SqlServer,其他数据库请指定对应程序集
    • SqlServerMicrosoft.EntityFrameworkCore.SqlServer
    • SqliteMicrosoft.EntityFrameworkCore.Sqlite
    • CosmosMicrosoft.EntityFrameworkCore.Cosmos
    • InMemoryDatabaseMicrosoft.EntityFrameworkCore.InMemory
    • MySqlPomelo.EntityFrameworkCore.MySql
    • PostgreSQLNpgsql.EntityFrameworkCore.PostgreSQL
    • OracleCitms.EntityFrameworkCore.Oracle
    • DmMicrosoft.EntityFrameworkCore.Dm
  • -EntryProject:Web 启用项目层名,默认 Furion.Web.Entry
  • -CoreProject:实体项目层名,默认 Furion.Core
  • -DbContextLocators:多数据库上下文定位器,默认 MasterDbContextLocator,支持多个,如:MasterDbContextLocator,MySqlDbContextLocator
  • -Product:解决方案默认前缀,如 Furion
  • -UseDatabaseNames:是否保持生成和数据库、表一致的名称

9.13.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-delete/index.html b/docs/docs/dbcontext-delete/index.html index 1e9c4510dfb..0e625fa7d40 100644 --- a/docs/docs/dbcontext-delete/index.html +++ b/docs/docs/dbcontext-delete/index.html @@ -6,7 +6,7 @@ 9.8 删除操作 | Furion - + @@ -70,7 +70,7 @@
// 示例五
await entity.FakeDeleteAsync();
// 示例六
await repository.UpdateIncludeAsync(user, u => u.IsDeleted);

9.8.9 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-entitytrigger/index.html b/docs/docs/dbcontext-entitytrigger/index.html index 56f0f2b5fb5..1a8d8a8dfae 100644 --- a/docs/docs/dbcontext-entitytrigger/index.html +++ b/docs/docs/dbcontext-entitytrigger/index.html @@ -6,7 +6,7 @@ 9.25. 实体数据监听器 | Furion - + @@ -32,7 +32,7 @@
/// <summary>
/// 监听数据改变之后(仅支持EFCore操作)
/// </summary>
/// <param name="entity"></param>
/// <param name="dbContext"></param>
/// <param name="dbContextLocator"></param>
/// <param name="state"></param>
void OnChanged(TEntity entity, DbContext dbContext, Type dbContextLocator, EntityState state);
/// <summary>
/// 监听数据改变失败(仅支持EFCore操作)
/// </summary>
/// <param name="entity"></param>
/// <param name="dbContext"></param>
/// <param name="dbContextLocator"></param>
/// <param name="state"></param>
void OnChangeFailed(TEntity entity, DbContext dbContext, Type dbContextLocator, EntityState state) { }
}

9.29.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-filter/index.html b/docs/docs/dbcontext-filter/index.html index b3b9b1b262e..c053f86ddd7 100644 --- a/docs/docs/dbcontext-filter/index.html +++ b/docs/docs/dbcontext-filter/index.html @@ -6,7 +6,7 @@ 9.23 实体/全局查询筛选器 | Furion - + @@ -37,7 +37,7 @@
// 创建表达式元素
var parameter = Expression.Parameter(metadata.ClrType, "u");
var properyName = Expression.Constant(nameof(Entity.IsDeleted));
var propertyValue = Expression.Constant(false);
// 构建表达式 u => EF.Property<bool>(u, "IsDeleted") == false
var expressionBody = Expression.Equal(Expression.Call(typeof(EF), nameof(EF.Property), new[] { typeof(bool) }, parameter, properyName), propertyValue);
var expression = Expression.Lambda(expressionBody, parameter);
return expression;
}
}
}
小建议

如果对动态构建 LambdaExpression 不熟悉的朋友,可以使用 System.Linq.Dynamic.Corehttps://github.com/zzzprojects/System.Linq.Dynamic.Core

9.23.3 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-function/index.html b/docs/docs/dbcontext-function/index.html index 3c545180fcb..2ba09aacb24 100644 --- a/docs/docs/dbcontext-function/index.html +++ b/docs/docs/dbcontext-function/index.html @@ -6,7 +6,7 @@ 9.14 函数操作 | Furion - + @@ -49,7 +49,7 @@
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity(typeof(F_Person)).HasNoKey();
modelBuilder.HasDbFunction(() => GetPersons(default));
}
}
}

9.14.5.4 在 Linq 中使用

IQueryable<F_Person> query = _repository.DynamicDbContext.GetPersons(1);
var result = query.Where(u => u.Name.Equals("Furion")).ToList();

最终生成 Sql

SELECT [g].Id, [g].Name, [g].Age, [g].Address
FROM dbo.GetPersons(1) AS [g]
WHERE [g].Name == N'Furion';

9.14.6 在 EF Core 内置函数

EF Core 为我们提供了很多常用的内置函数,可以在 Lambda 条件中使用,主要是通过 EF.Functions 调用,如:

_repository.Where(u => EF.Functions.DateDiffHour(u.CreatedDt, DateTime.Now) > 8).FirstOrDefault();

这个语句使用了 EF.Functions.DateDiffHour 最终生成的 Sql 如下:

SELECT TOP(1) [a].*
FROM [dbo].[TEST] AS [a]
WHERE DATEDIFF(HOUR, [a].[CREATED_DT], GETDATE()) > 8

EF Core 内置函数就不一一列出了,可以通过 EF.Functions 查看更多,如果不能满足自己的需求,那么可以自定义 Linq 标量函数

9.14.7 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-hight-query/index.html b/docs/docs/dbcontext-hight-query/index.html index 6f373e87055..6ca5ff53228 100644 --- a/docs/docs/dbcontext-hight-query/index.html +++ b/docs/docs/dbcontext-hight-query/index.html @@ -6,7 +6,7 @@ 9.11 高级查询操作 | Furion - + @@ -71,7 +71,7 @@
namespace Furion.Core
{
public class Person : Entity, IEntityTypeBuilder<Person>
{
public string Name { get; set; }
/// <summary>
/// 配置实体关系
/// </summary>
/// <param name="entityBuilder"></param>
/// <param name="dbContext"></param>
/// <param name="dbContextLocator"></param>
public void Configure(EntityTypeBuilder<City> entityBuilder, DbContext dbContext, Type dbContextLocator)
{
entityBuilder.ToSqlQuery(
@"select * from dbo.person.2020-09-19
union all
select * from dbo.person.2020-09-20");
}
}
}
var posts = repository.Where(u => u.Id > 10).ToList();

9.11.14 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-locator/index.html b/docs/docs/dbcontext-locator/index.html index 64a8590d37a..6ef15c46419 100644 --- a/docs/docs/dbcontext-locator/index.html +++ b/docs/docs/dbcontext-locator/index.html @@ -6,7 +6,7 @@ 9.2 数据库上下文定位器 | Furion - + @@ -27,7 +27,7 @@
namespace Furion.Core
{
public sealed class FurDbContextLocator : IDbContextLocator
{
}
}

9.2.4 默认数据库上下文定位器

Furion 框架中已经提供了 MasterDbContextLocator 默认数据库上下文定位器,所以默认数据库上下文只需继承 AppDbContext<TDbContext> 即可。

AppDbContext<TDbContext> 定义代码如下:

using Furion.DependencyInjection;
using Microsoft.EntityFrameworkCore;
namespace Furion.DatabaseAccessor
{
/// <summary>
/// 默认应用数据库上下文
/// </summary>
/// <typeparam name="TDbContext">数据库上下文</typeparam>
[NonBeScan]
public abstract class AppDbContext<TDbContext> : AppDbContext<TDbContext, MasterDbContextLocator>
where TDbContext : DbContext
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="options"></param>
public AppDbContext(DbContextOptions<TDbContext> options) : base(options)
{
}
}
}

9.2.5 数据库上下文定位器支持对象

目前数据库上下文支持以下多个对象:

  • AppDbContext<TEntity, TDbContextLocator>:数据上下文
  • IRepository<TEntity, TDbContextLocator:实体仓储
  • ISqlRepository<TDbContextLocator>: Sql 操作仓储
  • Func<Type, DbContext>:依赖注入获取数据库上下文
  • Entity<Tkey, TDbContextLocator> :实体配置
  • EntityBase<Tkey, TDbContextLocator1, ... TDbContextLocator8>:实体配置
  • EntityNotKey<TDbContextLocator1, ... TDbContextLocator8>:无键实体配置
  • IEntitySeedData<TEntity, TDbContextLocator1, ... TDbContextLocator8>:种子数据配置
  • IEntityTypeBuilder<TEntity, TDbContextLocator1, ... TDbContextLocator8>:实体类型构建器
  • IModelBuilderFilter<TDbContextLocator1, ... TDbContextLocator8>:模型构建筛选器
  • [QueryableFunction(DbContextLocators=Type[])]:查询函数

9.2.6 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-multi-database/index.html b/docs/docs/dbcontext-multi-database/index.html index 785d6d2985f..8be06fc9b5b 100644 --- a/docs/docs/dbcontext-multi-database/index.html +++ b/docs/docs/dbcontext-multi-database/index.html @@ -6,7 +6,7 @@ 9.18 多数据库操作 | Furion - + @@ -42,7 +42,7 @@
// 支持一个数据库
public class Person: IEntity<MySqlDbContextLocator>
{
// ....
}
// 支持多个数据库
public class Person: IEntity<MySqlDbContextLocator, SqliteDbContextLocator>
{
// ....
}
小知识

所有的 实体依赖接口或抽象类 都支持泛型方式 指定 数据库上下文定位器,最多支持 8 个。

9.18.3.5 Linq 函数方式

public static class QueryFunctions
{
[QueryableFunction("FN_GetId", "dbo", typeof(MySqlDbContextLocator), typeof(SqliteDbContextLocator))]
public static int GetId(int id) => throw new NotSupportedException();
}

9.18.4 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-proc/index.html b/docs/docs/dbcontext-proc/index.html index acaa83713bd..8b2bc06f25f 100644 --- a/docs/docs/dbcontext-proc/index.html +++ b/docs/docs/dbcontext-proc/index.html @@ -6,7 +6,7 @@ 9.13 存储过程操作 | Furion - + @@ -120,7 +120,7 @@
// 获取 RETURN 返回值
var reval = result.ReturnValue;
// 获取返回结果集
var (list1,list2) = result.Result;
关于异步

Furion 框架每一个数据库操作都支持异步方式,由于篇幅有限,就不列举异步方式了。

9.13.3 关于 [DbParameter]

[DbParameter] 特性是用来标注 Sql函数存储过程 参数的,可配置属性:

  • Direction:设置参数方向,ParameterDirection 枚举类型,默认 ParameterDirection.Input
  • DbType:设置参数类型,DbType 枚举类型,无默认
  • Size:设置参数长度的,int 类型

其中 Direction 属性是默认构造函数参数。

9.13.4 关于 ProcedureOutputResult

ProcedureOutputResultProcedureOutputResult<TResult> 是复杂存储过程执行返回模型类,有以下属性:

  • OutputValues:多个输出值,ProcedureOutputValue 类型
  • ReturnValue:返回值,object 类型
  • Result:结果集,非泛型版本是 DataSet类型,否则是 泛型类型

9.13.5 存储过程参数

所有 sql 参数都支持四种方式:

  • DbParameter[]:数组类型
  • new {}:匿名类型
  • new Class{}:强类型类型(支持复杂存储过程参数)
  • Dictionary<string,object> 类型

9.13.6 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-query/index.html b/docs/docs/dbcontext-query/index.html index be742fd7ef6..587db5afec1 100644 --- a/docs/docs/dbcontext-query/index.html +++ b/docs/docs/dbcontext-query/index.html @@ -6,7 +6,7 @@ 9.10 查询操作 | Furion - + @@ -137,7 +137,7 @@
// 示例二
_testRepository.Where(u => u.Name.EndWith("Furion"));
// 示例三
_testRepository.Where(u => u.Name.Contains("Furion"));

9.10.6.9 Case When

数据库中的 Case When 实际上对应的是我们程序中的 三元表达式 ,也就是使用 三元表达式 即可自动生成 Case When 语句。

9.10.7 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-read-write/index.html b/docs/docs/dbcontext-read-write/index.html index 55ce1c40d8d..2b57abd0dce 100644 --- a/docs/docs/dbcontext-read-write/index.html +++ b/docs/docs/dbcontext-read-write/index.html @@ -6,7 +6,7 @@ 9.27 读写分离/主从复制 | Furion - + @@ -37,7 +37,7 @@
/// <summary>
/// 查询走从库
/// </summary>
/// <returns></returns>
public List<Person> Get()
{
return _msRepository.Slave1<Person>().AsEnumerable();
}
}
}

9.27.3 主从复制

主从复制:是一种数据备份的方案。

简单来说,是使用两个或两个以上相同的数据库,将一个数据库当做主数据库,而另一个数据库当做从数据库。在主数据库中进行相应操作时,从数据库记录下所有主数据库的操作,使其二者一模一样。

9.27.4 主从复制几种方式

9.27.4.1 同步复制

所谓的同步复制,意思是 Master 的变化,必须等待 Slave-1,Slave-2,...,Slave-n 完成后才能返回。 这样,显然不可取,比如,在 Web 前端页面上,用户增加了条记录,需要等待很长时间。

9.27.4.2 异步复制

如同 AJAX 请求一样。Master 只需要完成自己的数据库操作即可。至于 Slaves 是否收到二进制日志,是否完成操作,不用关心。(推荐方式)

9.27.4.3 半同步复制

Master 只保证 Slaves 中的一个操作成功,就返回,其他 Slave 不管。

下面将使用 SqlServer 简单配置主从复制功能。

9.27.5 SqlServer 主库配置

9.27.5.1 添加 本地发布

9.27.5.2 选择 分发服务器

9.27.5.3 启用 代理

9.27.5.4 发布数据库

9.27.5.5 快照发布

具体选择何种发布类型,视具体业务场景而定。

9.27.5.6 选择发布项目

9.27.5.7 配置分发计划

9.27.5.8 配置安全设置

9.27.5.9 完成配置

9.27.6 SqlServer 从库配置

9.27.6.1 添加 本地订阅

9.27.6.2 选择 分发服务器

9.27.6.3 选择 分发代理位置

9.27.6.4 选择 订阅数据库

9.27.6.5 选择 分发安全设置

9.27.6.6 选择 同步计划

9.27.6.7 完成订阅

9.27.7 分发定义监视

9.27.8 查看主从复制结果

特别特性

主从复制有一定迟延性,所以系统设计要有一定“容忍性"。

9.27.9 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-repository/index.html b/docs/docs/dbcontext-repository/index.html index 245fd199d89..41480d8d7fb 100644 --- a/docs/docs/dbcontext-repository/index.html +++ b/docs/docs/dbcontext-repository/index.html @@ -6,7 +6,7 @@ 9.4 仓储模式 | Furion - + @@ -32,7 +32,7 @@
// 其他更多数据库一样的操作

另外任何仓储或实体配置都支持多个数据库同时操作

仓储方式

IRepository<Person, MsSqlDbContextLocator> mssqlRepository
ISqlRepository<MsSqlDbContextLocator> mssqlRepository;

动态 sql 方式

"select * from person".Change<MsSqlDbContextLocator>().SqlQuery();

实体配置方式

public class User:Entity<MsSqlDbContextLocator, MySqlDbContextLocator>
{
}

Sql 代理方式

[SqlFunction("funcName", DbContextLocator = typeof(MySqlDbContextLocator))]
int GetAge(int id);

Linq 中方式

[QueryableFunction("funcName","dbo", DbContextLocator = typeof(MySqlDbContextLocator))]
string GetName()=> throw Oops.Oh("不支持该数据库操作");

9.4.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-seed-data/index.html b/docs/docs/dbcontext-seed-data/index.html index 3c0953bd938..3f51cbb3b78 100644 --- a/docs/docs/dbcontext-seed-data/index.html +++ b/docs/docs/dbcontext-seed-data/index.html @@ -6,7 +6,7 @@ 9.21 实体种子数据 | Furion - + @@ -31,7 +31,7 @@
namespace Furion.Application
{
public class PersonSeedData : IEntitySeedData<Person>
{
// 配置种子数据
public IEnumerable<Person> HasData(DbContext dbContext, Type dbContextLocator)
{
return new List<Person>
{
new Person { Id = 1, Name = "百小僧", Address = "广东省中山市" },
new Person { Id = 2, Name = "新生帝", Address = "广东省珠海市" }
};
}
}
}

9.21.3 导航属性

通常我们的实体有 一对多多对多等外键关系,那么我们需要单独为每一个实体添加数据种子,而不是直接写在主表中。

9.21.4 多个数据库种子数据

Furion 提供泛型的方式支持多个数据库种子数据设定,如:

using Furion.DatabaseAccessor;
using System.Collections.Generic;
namespace Furion.Application
{
public class PersonSeedData : IEntitySeedData<Person, MySqlDbContextLocator, SqliteDbContextLocator>
{
// 配置种子数据
public IEnumerable<Person> HasData(DbContext dbContext, Type dbContextLocator)
{
return new List<Person>
{
new Person { Id = 1, Name = "百小僧", Address = "广东省中山市" },
new Person { Id = 2, Name = "新生帝", Address = "广东省珠海市" }
};
}
}
}

上面的例子表示同时为 MySqlDbContextSqliteDbContext 创建种子数据。

9.21.5 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 数据种子 知识可查阅 EF Core - 数据种子设定 章节。

- + diff --git a/docs/docs/dbcontext-sql-proxy/index.html b/docs/docs/dbcontext-sql-proxy/index.html index b6d801d2c5f..e83c4316548 100644 --- a/docs/docs/dbcontext-sql-proxy/index.html +++ b/docs/docs/dbcontext-sql-proxy/index.html @@ -6,7 +6,7 @@ 9.17 Sql 高级代理 | Furion - + @@ -75,7 +75,7 @@
namespace Furion.Application
{
public interface ISql : ISqlDispatchProxy
{
[SqlFunction("FN_Name")] // 标量函数
string GetValue(MyParam dto);
[SqlProcedure("FN_Name")] // 表值函数
List<Person> GetPersons(int id);
}
}
补充说明

Sql 代理会自动判断返回值然后自动执行特定函数类型。

9.17.6 为什么用它?

通过上面的例子大家就可以了解,这种方式操作 sql 非常简单,而且极易维护。大家不用去关系返回值,关心用哪个方法,所有东西会自动给你处理好。

所以,如果需要用 Sql 操作,推荐使用 Sql 高级代理。

9.17.7 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-sql-template/index.html b/docs/docs/dbcontext-sql-template/index.html index 061cd544cce..811eee0ba36 100644 --- a/docs/docs/dbcontext-sql-template/index.html +++ b/docs/docs/dbcontext-sql-template/index.html @@ -6,7 +6,7 @@ 9.16 Sql 模板 | Furion - + @@ -27,7 +27,7 @@
// 懒人方式
var users = "#(Select.User)".SqlQuery<User>(new { id = 1});
// Sql 代理方式
[SqlExecute("#(Select.User)")]
List<User> GetUser(int id);

9.16.3.2 高级嵌套

var users = repository.SqlQuery<User>(
@"select * from user u
left join #(User.Detail) d on u.Id = d.UserId
where id > @id");

9.16.4 Sql 模板配置

9.16.4.1 普通模式

{
"Select.User": "select * from User"
}

9.16.4.2 更多配置

{
"Select.User": {
"Sql": "select * from User where id > @id and Name = @name",
"Params": [
{
"Name": " Id",
"Value": "1",
"DbType": "Int16",
"Size": 10
},
{
"Name": " Name",
"Value": "百小僧",
"DbType": "String",
"Size": 10
}
]
}
}

9.16.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-sql/index.html b/docs/docs/dbcontext-sql/index.html index acc4d88c981..f964d41f906 100644 --- a/docs/docs/dbcontext-sql/index.html +++ b/docs/docs/dbcontext-sql/index.html @@ -6,7 +6,7 @@ 9.15 Sql 操作 | Furion - + @@ -172,7 +172,7 @@
// 不再举例子。。。
补充说明

不管是那种方式操作 Sql ,方法名参数都是一致的,如:

  • SqlQuery
  • SqlQueryAsync
  • SqlQueries
  • SqlQueriesAsync
  • SqlNonQuery
  • SqlNonQueryAsync
  • SqlScalar
  • SqlScalarAsync
  • SqlProcedureQuery
  • SqlProcedureQueryAsync
  • SqlProcedureQueries
  • SqlProcedureQueriesAsync
  • SqlProcedureScalar
  • SqlProcedureScalarAsync
  • SqlProcedureNonQuery
  • SqlProcedureNonQueryAsync
  • SqlProcedureOutput
  • SqlProcedureOutputAsync
  • SqlFunctionScalar
  • SqlFunctionScalarAsync
  • SqlFunctionQuery
  • SqlFunctionQuery

9.15.6 IRepository 操作

IRepository 也能操作 sql,调用方法也是和上面一致的,如:

var dataTable = repository.Sql().SqlQuery("select * from person");
特别说明

由于篇幅有限,不再列举所有例子。

9.15.7 IRepository<TEntity> 操作

IRepository<TEntity> 也能操作 sql,调用方法也是和上面一致的,如:

var dataTable = personRepository.SqlQuery("select * from person");
特别说明

由于篇幅有限,不再列举所有例子。

9.15.8 关于 Sql 参数

所有 sql存储过程函数 参数都支持四种方式:

  • DbParameter[]:数组类型
  • new {}:匿名类型
  • new Class{}:强类型类型(支持复杂存储过程参数)
  • Dictionary<string,object> 类型
小知识

建议除了复杂的存储过程(带 OUTPUT/RETURN)的以外,所有参数建议使用 new {} 匿名类型,如果需要动态参数,则可以使用 Dictionary<string,object> 类型。

9.15.9 多数据库 Sql 操作 💯 💛

Furion 框架拥有非常灵活的多数据库操作方式,只需通过多数据库上下文定位器即可动态切换数据库。

9.15.9.1 懒人无敌 🐮 方式

var dataTable = "select * from person".Change<MySqlDbContextLocator>().SqlQuery();
var persons = "select * from person whre id > @id".Change<SqliteDbContextLocator>().SqlQuery<Person>();
补充说明

懒人方式 只需要通过 Change<TDbContextLocator> 方式即可动态切换数据库。

9.15.9.2 ISqlRepository 方式

只需要通过 ISqlRepository<TDbContextLocator> 注入或通过 sqlRepository.Change<TDbContextLocator>() 切换。

9.15.9.3 IRepository 方式

只需要通过 repository.Change<TDbContextLocator>() 获取即可。

9.15.9.4 IRepository<TEntity> 方式

只需要通过 IRepository<TEntity, TDbContextLocator> 注入或通过 personRepository.Change<TEntity, TDbContextLocator>() 切换。

9.15.10 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-update/index.html b/docs/docs/dbcontext-update/index.html index 56b0fb5b162..6a9717488a4 100644 --- a/docs/docs/dbcontext-update/index.html +++ b/docs/docs/dbcontext-update/index.html @@ -6,7 +6,7 @@ 9.6 更新操作 | Furion - + @@ -197,7 +197,7 @@
// 示例二
await repository.UpdateNowAsync(new List<User> { user, user2 });
// 示例三
await repository.UpdateNowAsync(new[] {user, user2 });
小知识

所有带 Now 结尾的表示立即提交到数据库,也就是立即调用 SaveChangesSaveChangesAsync

9.6.15 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext-view/index.html b/docs/docs/dbcontext-view/index.html index f6a449a2bf5..7bc350158ed 100644 --- a/docs/docs/dbcontext-view/index.html +++ b/docs/docs/dbcontext-view/index.html @@ -6,7 +6,7 @@ 9.12 视图操作 | Furion - + @@ -33,7 +33,7 @@
public FurService(IRepository<V_Person> repository)
{
// 初始化只读仓储
_readableRepository = repository.Constraint<IReadableRepository<V_Person>>();
}
/// <summary>
/// 读取视图
/// </summary>
/// <returns></returns>
public async Task<List<V_Person>> GetVPerson()
{
var list = await _readableRepository.AsAsyncEnumerable();
return list;
}
}
}
小知识

通过 .Constraint<TEntity,TDbContextLocator> 方法可以将仓储约束为特定仓储,如只读仓储,可读可写仓储,只新增仓储等。

9.12.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/dbcontext/index.html b/docs/docs/dbcontext/index.html index 7d1c176e201..9021b94931a 100644 --- a/docs/docs/dbcontext/index.html +++ b/docs/docs/dbcontext/index.html @@ -6,7 +6,7 @@ 9.1 数据库上下文 | Furion - + @@ -36,7 +36,7 @@
options.AddDbPool<SecondDbContext, SecondDbContextDbContextLocator>(DbProvider.SqlServer); // 第二个数据库
options.AddDbPool<ThirdDbContext, ThirdDbContextDbContextLocator>(DbProvider.SqlServer); // 第三个数据库

9.1.8 动态数据库上下文对象

Furion 框架中,数据库上下文是定义在 Furion.EntityFramework.Core 项目层,并且该层不被 Furion.ApplicationFurion.Core 等层引用。

所以就不能直接在 Furion.Application 项目层直接使用 Furion.EntityFramework.Core 定义的数据库上下文。

Furion 为了解决这个问题,提供了两种方式处理:

  • respository.DbContext :当前数据库上下文对象,返回是 DbContext 抽象类型
  • respository.DynamicDbContext:当前数据库上下文对象,返回的是 dynamic 类型

如果你只是想使用 DbContext 的功能,直接使用 respository.DbContext 即可,如:

respository.DbContext.SaveChanges();

如果你想能够获取具体的数据库上下文类型,如 MyDbContext,那么使用 respository.DynamicDbContext 就可以获取到具体的 MyDbContext 类型。如:

var persons = respository.DynamicDbContext.Persons.Find(1);
var users = respository.DynamicDbContext.Users;

这样就可以直接操作 MyDbContext 定义的属性和方法了。

9.1.9 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 数据库上下文 知识可查阅 EF Core - 配置 DbContext 章节。

- + diff --git a/docs/docs/dependency-injection/index.html b/docs/docs/dependency-injection/index.html index 1ca651964cf..1ec077c793c 100644 --- a/docs/docs/dependency-injection/index.html +++ b/docs/docs/dependency-injection/index.html @@ -6,7 +6,7 @@ 11. 依赖注入/控制反转 | Furion - + @@ -58,7 +58,7 @@
Console.WriteLine("SayHello 方法返回值:" + result);
return result;
}
}
}

之后我们只需要为 TestService 增加 [Injection] 特性即可,如:

[Injection(Proxy = typeof(LogDispatchProxy))]
public class TestService: ITestService, ITransient
{
public string SayHello(string word)
{
return $"Hello {word}";
}
}

之后 SayHello 方法被调用的时候就可以实现动态拦截了,比如这里写日志。

11.12.1 全局Aop拦截

Furion 框架也提供了全局拦截的方式,只需要在 Startup.cs 中注册即可:

service.AddServiceProxy<LogDispatchProxy>();

这样就会拦截所有的 Service,当然也可以通过给特定类贴 [SkipProxy] 跳过全局拦截操作。

拦截优先级

[SkipProxy] > [Injection(Proxy = typeof(LogDispatchProxy))] > 全局拦截

11.12.2 AOP 的作用

这种面向切面的能力(动态拦截/代理)可以实现很多很多功能,如:

  • 动态日志记录
  • 动态修改参数
  • 动态修改返回值
  • 动态方法重定向
  • 动态修改代码逻辑
  • 动态实现异常监听

还可以做更多更多的事情。

11.13 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/deploy/index.html b/docs/docs/deploy/index.html index 611a56ceac5..7ffd5ddfd4c 100644 --- a/docs/docs/deploy/index.html +++ b/docs/docs/deploy/index.html @@ -6,7 +6,7 @@ 25. 托管部署 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/devops/index.html b/docs/docs/devops/index.html index e59bdb75d33..bd74396bf01 100644 --- a/docs/docs/devops/index.html +++ b/docs/docs/devops/index.html @@ -6,7 +6,7 @@ 26. 持续部署集成 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/dynamic-api-controller/index.html b/docs/docs/dynamic-api-controller/index.html index f78183549c9..51380c10ee4 100644 --- a/docs/docs/dynamic-api-controller/index.html +++ b/docs/docs/dynamic-api-controller/index.html @@ -6,7 +6,7 @@ 5. 动态 WebAPI | Furion - + @@ -81,7 +81,7 @@
namespace Furion.Web.Entry.Controllers
{
public class MvcController : ControllerBase
{
public string Get()
{
return nameof(Furion);
}
}
}
注意事项

启用该配置后,如果 Mvc 控制器 没有任何 [Route] 特性,但是贴了 [ApiController] 特性将会报错。原因是 [ApiController] 特性内部做了路由特性检测。所以建议使用 [ApiDataValidation] 代替。

查看 ASP.NET Core - ApiBehaviorApplicationModelProvider 源码

5.11 关于 AOP 拦截

动态WebAPI 支持 Controller 的所有过滤器/筛选器拦截,也就是可以通过 ActionFilterResultFilter 进行拦截操作。如:

public class SampleAsyncActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context,ActionExecutionDelegate next)
{
var resultContext = await next();
}
}

5.12 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/entity/index.html b/docs/docs/entity/index.html index 2edd69a232f..36d275fee3c 100644 --- a/docs/docs/entity/index.html +++ b/docs/docs/entity/index.html @@ -6,7 +6,7 @@ 9.3 数据库实体 | Furion - + @@ -38,7 +38,7 @@
// 配置数据库实体
public void Configure(EntityTypeBuilder<User> entityBuilder, DbContext dbContext, Type dbContextLocator)
{
entityBuilder.HasKey(u => u.Id);
entityBuilder.HasIndex(u => u.Name);
}
}
}

9.3.3.2 在任何实例类中配置

using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
namespace Furion.Core
{
public class SomeClass : IEntityTypeBuilder<User>
{
public void Configure(EntityTypeBuilder<User> entityBuilder, DbContext dbContext, Type dbContextLocator)
{
entityBuilder.HasKey(u => u.Id);
entityBuilder.HasIndex(u => u.Name);
}
}
}

如,上面例子,通过 SomeClass 配置 User 数据库实体。

9.3.4 数据库实体配置说明

Furion 框架会自动扫描所有继承 IEntity 接口的类进行 DbSet<TEntity> 注册,也就是实现自动配置 DbContextOnModelCreating

如果需要跳过自动注册,只需要贴 [NonAutomatic][SkipScan] 特性即可。一旦贴了此特性,那么就需要手动配置 DbContextOnModelCreating

9.3.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/errors/index.html b/docs/docs/errors/index.html index e9f40d2d2f8..4a75aa0c769 100644 --- a/docs/docs/errors/index.html +++ b/docs/docs/errors/index.html @@ -6,7 +6,7 @@ 29.2 常见错误 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/event-bus/index.html b/docs/docs/event-bus/index.html index b52db9bd3d1..57583eb0d19 100644 --- a/docs/docs/event-bus/index.html +++ b/docs/docs/event-bus/index.html @@ -6,7 +6,7 @@ 18. 事件总线 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/friendly-exception/index.html b/docs/docs/friendly-exception/index.html index 783f595bb24..92e8ab700a1 100644 --- a/docs/docs/friendly-exception/index.html +++ b/docs/docs/friendly-exception/index.html @@ -6,7 +6,7 @@ 7. 友好异常处理 | Furion - + @@ -63,7 +63,7 @@
namespace Furion.Application
{
public class LogExceptionHandler : IGlobalExceptionHandler, ISingleton
{
public Task OnExceptionAsync(ExceptionContext context)
{
// 写日志
return Task.CompletedTask;
}
}
}

7.15 FriendlyExceptionSettings 配置

  • HideErrorCode:隐藏错误码,bool 类型,默认 false
  • DefaultErrorCode:默认错误码,string 类型
  • DefaultErrorMessage:默认错误消息,string 类型

配置示例

{
"FriendlyExceptionSettings": {
"DefaultErrorMessage": "系统异常,请联系管理员"
}
}

7.16 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/get-start/index.html b/docs/docs/get-start/index.html index 6a69e694970..870402297d8 100644 --- a/docs/docs/get-start/index.html +++ b/docs/docs/get-start/index.html @@ -6,7 +6,7 @@ 2.1 一分钟入门 | Furion - + @@ -36,7 +36,7 @@
// 添加这一行,如果是 MVC和API共存项目,无需添加 string.Empty
app.UseInject(string.Empty);
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
小提醒

如果 app.UseInject() 不输入参数,则默认地址为 /api,如果输入 string.Empty 则为 / 目录。

2.4 启动浏览器

启动浏览器查看效果。

说好一分钟入门,你们用了多长时间。😁

- + diff --git a/docs/docs/gooduse/index.html b/docs/docs/gooduse/index.html index 746ab9247da..1727feeac54 100644 --- a/docs/docs/gooduse/index.html +++ b/docs/docs/gooduse/index.html @@ -6,7 +6,7 @@ 29.3 最佳实践 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/grpc/index.html b/docs/docs/grpc/index.html index 272e73a1829..83b50a1d478 100644 --- a/docs/docs/grpc/index.html +++ b/docs/docs/grpc/index.html @@ -6,7 +6,7 @@ 24. Grpc 服务 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/http/index.html b/docs/docs/http/index.html index cb801421b84..c3d0c885fa8 100644 --- a/docs/docs/http/index.html +++ b/docs/docs/http/index.html @@ -6,7 +6,7 @@ 20. 网络请求 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/index.html b/docs/docs/index.html index dfaad168b95..92b069616fc 100644 --- a/docs/docs/index.html +++ b/docs/docs/index.html @@ -6,7 +6,7 @@ 1.1 介绍 | Furion - + @@ -19,13 +19,13 @@ - +
-

1.1 介绍

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

🌭 开源地址

🍿 Docker 镜像

  • Docker Hub 线上镜像
docker run --name furion -p 5000:80 monksoul/furion:v1.4.3
  • 手动 打包镜像

打开 CMD/Shell/PowerShell 进入 Furion 项目根目录打包 Furion 镜像:

docker build -t furion:v1.4.3 .

打包成功后,直接 docker run

docker run --name furion -p 5000:80 furion:v1.4.3

🥥 Furion 官方包

包类型名称版本描述
nugetFurionnugetFurion 总包
nugetFurion.Extras.Authentication.JwtBearernugetFurion Jwt 拓展包
nugetFurion.Extras.DependencyModel.CodeAnalysisnugetFurion 动态反射 拓展包

🍄 Furion 脚手架

模板类型名称版本描述
nugetFurion.Template.MvcnugetMvc 模板
nugetFurion.Template.ApinugetWebApi 模板
nugetFurion.Template.AppnugetMvc/WebApi 模板
nugetFurion.Template.RazornugetRazorPages 模板
nugetFurion.Template.RazorWithWebApinugetRazorPages/WebApi 模板
nugetFurion.Template.BlazornugetBlazor 模板
nugetFurion.Template.BlazorWithWebApinugetBlazor/WebApi 模板

如何使用脚手架

🍎 框架特点

  • 全新面貌:基于 .NET 5 平台,没有历史包袱
  • 极易入门:只需要一个 Inject() 即可完成配置
  • 极速开发:内置丰富的企业应用开发功能
  • 极少依赖:框架只依赖三个第三方包
  • 极其灵活:轻松面对多变复杂的需求
  • 极易维护:采用独特的架构思想,只为长久维护设计
  • 完整文档:提供完善的开发文档

🥞 架构设计

正在整理中...

🥝 功能模块

🥐 框架依赖

Furion 为了追求极速入门,极致性能,尽可能的不使用或减少第三方依赖。目前 Furion 仅集成了以下三个依赖:

麻雀虽小五脏俱全。Furion 即使只集成了这三个依赖,但是主流的 依赖注入/控制反转AOP 面向切面编程,事件总线数据验证数据库操作 等等一个都不少。

🥗 环境要求

  • Visual Studio 2019 16.8 +
  • .NET 5 SDK +
  • .Net Standard 2.1 +

🥪 支持平台

  • 运行环境
    • Windows
    • Linux
    • MacOS
    • Docker/K8S/K3S/Rancher
    • Xamarin/MAUI
  • 数据库
    • SqlServer
    • Sqlite
    • Azure Cosmos
    • MySql
    • MariaDB
    • PostgreSQL
    • InMemoryDatabase
    • Oracle(并未完全适配
    • Firebird
    • 达梦数据库
  • 应用部署
    • Kestrel
    • Nginx
    • Jexus
    • IIS
    • Apache
    • PM2
    • Supervisor
    • 单文件
    • 容器(Docker/K8S/K3S/Rancher)

🍖 关于性能

Furion 目前采用 Visual Studio 2019 16.8 自带性能测试和 JMeter 进行测试,由于篇幅有限,只贴部分测试图,测试结果如下:


🍚 关于作者

一个拥有 12 年开发经验 .NETer。喜欢分享,喜欢新技术,在互联网多个技术领域皆有涉猎,dotNET China MIP,同时多次获得开源中国 Gitee 授予 GVP 证书。

🍤 项目成员

🎈 欢迎更多的开发者加入 Furion 大家庭。

🍝 他们都在用

  • 百签科技(广东)有限公司
  • 码为科技(广州)有限公司
  • 广州启顺国际货运代理有限公司
  • 森丰供应链服务(广州)有限公司
  • 中山赢友网络科技有限公司
  • 中山模思软件科技有限公司
  • 珠海市恒泰新软件有限责任公司
  • 珠海思诺锐创软件有限公司
  • 深圳市易胜科技有限公司
  • 重庆虫儿飞科技有限公司
  • 重庆林木森科技有限公司
  • 深圳市品立方科技有限公司
  • 上海奥达科股份有限公司
  • 中山市泓升软件科技有限公司
  • 唐山天权建筑科技有限公司
  • 北京帝龙科技有限公司
  • 深圳市希立网络有限公司
  • 广州市飞帆计算机技术有限公司
  • 泉州市润海信息科技有限公司
  • 成都市彼岸里信息科技有限公司
  • 福建省山水生活服务集团有限公司

如果您的项目使用到 Furion 开发,可以告诉我们。

🍻 贡献代码

Furion 遵循 Apache-2.0 开源协议,欢迎大家提交 PRIssue

如果要为项目做出贡献,请查看贡献指南。

🍍 捐赠列表

注:排序按捐赠顺序书写

捐赠人昵称捐赠金额(元)附语
🤴 爱吃油麦菜100感谢您的开源项目!
👳‍♂️ 麦壳饼200感谢您的开源项目!
👨 Sun100感谢您的开源项目!
👶 d61761720感谢您的开源项目!
👦 Diqiguoji00816.66见贤思齐
👲 nodyang100感谢您的开源项目!
👳‍♀️ mictxd100吹过的牛都实现。
🧓 欧流全10希望将来超越 Spring
👨‍⚕️ lionkon10...看了框架感觉拿来学习是很不错的...
😤 好人!10Nice 的小僧,我们的 dotnetchina 马上火起来了
😮 木木 Woody10感谢您的开源项目!
😚 Joker HouQQ 超级会员一个月
🤠 ccdfzQQ 专属红包 199
🌝 天夫李总支付宝 6666Furion 非常有意思,持续关注
😝 六尘子微信红包 199公司已经使用,小小敬意
🤠 ccdfzQQ 专属红包 200赞助一根内存条
🤑 邓亮灯28.88感谢您的开源项目!
😬 天道酬勤微信二维码 188小小心意
🥰 却月居士QQ 专属红包 100恭喜发财
🤩 鲁旭100感谢您的开源项目!
😬 散客行微信二维码 666终于找到一个不错的框架
😌 本心100项目功能很强大
🙆‍♂️ 毕业生100请你喝杯咖啡
🦹‍♀️ 猪鼻子微信二维码 668
🧟‍♂️ 明年·今日200使用的框架里最爽的,最理想的!加油
👨‍🎓 过去的过去50感谢您的开源项目!
👨‍🔧 万里兮100新公司的第一个项目从 Furion 开始
👴 Muphalem20很热心很亲切的开发者,加油!
💂‍♂️ 吃锅巴的码农微信二维码 500就冲你的文档写得好!
🤴 三重罗生门微信红包 200下次烤鱼你请!

非常感谢您们的支持,正是因为您们,中国开源才可以越走越远,Furion 越走越远。

🥔 QQ 交流群

🧆 友情链接

👉 Furion 👉 SqlSugar 👉 Layx 👉 t-io 👉 ThinkPHP 👉 Hutool 👉 BootstrapAdmin 👉 BootstrapBlazor 👉 IoTSharp 👉 Anno.Core 👉 WaterCloud

+

1.1 介绍

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

🌭 开源地址

🍿 Docker 镜像

  • Docker Hub 线上镜像
docker run --name furion -p 5000:80 monksoul/furion:v1.4.3
  • 手动 打包镜像

打开 CMD/Shell/PowerShell 进入 Furion 项目根目录打包 Furion 镜像:

docker build -t furion:v1.4.3 .

打包成功后,直接 docker run

docker run --name furion -p 5000:80 furion:v1.4.3

🥥 Furion 官方包

包类型名称版本描述
nugetFurionnugetFurion 总包
nugetFurion.Extras.Authentication.JwtBearernugetFurion Jwt 拓展包
nugetFurion.Extras.DependencyModel.CodeAnalysisnugetFurion 动态反射 拓展包

🍄 Furion 脚手架

模板类型名称版本描述
nugetFurion.Template.MvcnugetMvc 模板
nugetFurion.Template.ApinugetWebApi 模板
nugetFurion.Template.AppnugetMvc/WebApi 模板
nugetFurion.Template.RazornugetRazorPages 模板
nugetFurion.Template.RazorWithWebApinugetRazorPages/WebApi 模板
nugetFurion.Template.BlazornugetBlazor 模板
nugetFurion.Template.BlazorWithWebApinugetBlazor/WebApi 模板

如何使用脚手架

🍎 框架特点

  • 全新面貌:基于 .NET 5 平台,没有历史包袱
  • 极易入门:只需要一个 Inject() 即可完成配置
  • 极速开发:内置丰富的企业应用开发功能
  • 极少依赖:框架只依赖三个第三方包
  • 极其灵活:轻松面对多变复杂的需求
  • 极易维护:采用独特的架构思想,只为长久维护设计
  • 完整文档:提供完善的开发文档

🥞 架构设计

正在整理中...

🥝 功能模块

🥐 框架依赖

Furion 为了追求极速入门,极致性能,尽可能的不使用或减少第三方依赖。目前 Furion 仅集成了以下三个依赖:

麻雀虽小五脏俱全。Furion 即使只集成了这三个依赖,但是主流的 依赖注入/控制反转AOP 面向切面编程,事件总线数据验证数据库操作 等等一个都不少。

🥗 环境要求

  • Visual Studio 2019 16.8 +
  • .NET 5 SDK +
  • .Net Standard 2.1 +

🥪 支持平台

  • 运行环境
    • Windows
    • Linux
    • MacOS
    • Docker/K8S/K3S/Rancher
    • Xamarin/MAUI
  • 数据库
    • SqlServer
    • Sqlite
    • Azure Cosmos
    • MySql
    • MariaDB
    • PostgreSQL
    • InMemoryDatabase
    • Oracle(并未完全适配
    • Firebird
    • 达梦数据库
  • 应用部署
    • Kestrel
    • Nginx
    • Jexus
    • IIS
    • Apache
    • PM2
    • Supervisor
    • 单文件
    • 容器(Docker/K8S/K3S/Rancher)

🍖 关于性能

Furion 目前采用 Visual Studio 2019 16.8 自带性能测试和 JMeter 进行测试,由于篇幅有限,只贴部分测试图,测试结果如下:


🍚 关于作者

一个拥有 12 年开发经验 .NETer。喜欢分享,喜欢新技术,在互联网多个技术领域皆有涉猎,dotNET China MIP,同时多次获得开源中国 Gitee 授予 GVP 证书。

🍤 项目成员

🎈 欢迎更多的开发者加入 Furion 大家庭。

🍝 他们都在用

  • 百签科技(广东)有限公司
  • 码为科技(广州)有限公司
  • 广州启顺国际货运代理有限公司
  • 森丰供应链服务(广州)有限公司
  • 中山赢友网络科技有限公司
  • 中山模思软件科技有限公司
  • 珠海市恒泰新软件有限责任公司
  • 珠海思诺锐创软件有限公司
  • 深圳市易胜科技有限公司
  • 重庆虫儿飞科技有限公司
  • 重庆林木森科技有限公司
  • 深圳市品立方科技有限公司
  • 上海奥达科股份有限公司
  • 中山市泓升软件科技有限公司
  • 唐山天权建筑科技有限公司
  • 北京帝龙科技有限公司
  • 深圳市希立网络有限公司
  • 广州市飞帆计算机技术有限公司
  • 泉州市润海信息科技有限公司
  • 成都市彼岸里信息科技有限公司
  • 福建省山水生活服务集团有限公司
  • 安徽宝典网络科技有限公司

如果您的项目使用到 Furion 开发,可以告诉我们。

🍻 贡献代码

Furion 遵循 Apache-2.0 开源协议,欢迎大家提交 PRIssue

如果要为项目做出贡献,请查看贡献指南。

🍍 捐赠列表

注:排序按捐赠顺序书写

捐赠人昵称捐赠金额(元)附语
🤴 爱吃油麦菜100感谢您的开源项目!
👳‍♂️ 麦壳饼200感谢您的开源项目!
👨 Sun100感谢您的开源项目!
👶 d61761720感谢您的开源项目!
👦 Diqiguoji00816.66见贤思齐
👲 nodyang100感谢您的开源项目!
👳‍♀️ mictxd100吹过的牛都实现。
🧓 欧流全10希望将来超越 Spring
👨‍⚕️ lionkon10...看了框架感觉拿来学习是很不错的...
😤 好人!10Nice 的小僧,我们的 dotnetchina 马上火起来了
😮 木木 Woody10感谢您的开源项目!
😚 Joker HouQQ 超级会员一个月
🤠 ccdfzQQ 专属红包 199
🌝 天夫李总支付宝 6666Furion 非常有意思,持续关注
😝 六尘子微信红包 199公司已经使用,小小敬意
🤠 ccdfzQQ 专属红包 200赞助一根内存条
🤑 邓亮灯28.88感谢您的开源项目!
😬 天道酬勤微信二维码 188小小心意
🥰 却月居士QQ 专属红包 100恭喜发财
🤩 鲁旭100感谢您的开源项目!
😬 散客行微信二维码 666终于找到一个不错的框架
😌 本心100项目功能很强大
🙆‍♂️ 毕业生100请你喝杯咖啡
🦹‍♀️ 猪鼻子微信二维码 668
🧟‍♂️ 明年·今日200使用的框架里最爽的,最理想的!加油
👨‍🎓 过去的过去50感谢您的开源项目!
👨‍🔧 万里兮100新公司的第一个项目从 Furion 开始
👴 Muphalem20很热心很亲切的开发者,加油!
💂‍♂️ 吃锅巴的码农微信二维码 500就冲你的文档写得好!
🤴 三重罗生门微信红包 200下次烤鱼你请!

非常感谢您们的支持,正是因为您们,中国开源才可以越走越远,Furion 越走越远。

🥔 QQ 交流群

🧆 友情链接

👉 Furion 👉 SqlSugar 👉 Layx 👉 t-io 👉 ThinkPHP 👉 Hutool 👉 BootstrapAdmin 👉 BootstrapBlazor 👉 IoTSharp 👉 Anno.Core 👉 WaterCloud

- + @@ -38,6 +38,6 @@ - + \ No newline at end of file diff --git a/docs/docs/job/index.html b/docs/docs/job/index.html index 5373b67e7ef..3de11999537 100644 --- a/docs/docs/job/index.html +++ b/docs/docs/job/index.html @@ -6,7 +6,7 @@ 22. 任务调度 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/local-language/index.html b/docs/docs/local-language/index.html index f4e621d7beb..19425b2b241 100644 --- a/docs/docs/local-language/index.html +++ b/docs/docs/local-language/index.html @@ -6,7 +6,7 @@ 17. 多语言处理 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/logging/index.html b/docs/docs/logging/index.html index 77ca6c30981..ac2df3b243a 100644 --- a/docs/docs/logging/index.html +++ b/docs/docs/logging/index.html @@ -6,7 +6,7 @@ 19. 日志记录 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/object-mapper/index.html b/docs/docs/object-mapper/index.html index b1e0b2f5f46..23b195860b9 100644 --- a/docs/docs/object-mapper/index.html +++ b/docs/docs/object-mapper/index.html @@ -6,7 +6,7 @@ 12. 对象数据映射 | Furion - + @@ -27,7 +27,7 @@
var dto = new Dto();
dto.Id = entity.Id;
dto.Name = entity.Name;
dto.Age = entity.Age;
dto.Address = entity.Address;
dto.FullName = entity.FirstName + entity.LastName;
dto.IdCard = entity.IdCard.Replace("1234", "****");

上面的例子似乎没有任何问题,但是如果很多地方需要这样的赋值操作、或者相同的赋值操作在多个地方使用,又或者一个类中含有非常多的属性或自定义赋值操作。那么这样的操作效率极低,容易出错,且代码非常臃肿和冗余。

所以,实现自动映射赋值和支持特殊配置的需求就有了。目前 C# 平台有两个优秀的对象映射工具:MapsterAutoMapperFurion 框架中,默认集成的是 MapsterMapster 是一款极易使用且超高性能的对象映射框架。

12.3 Mapster 使用

现在,我们可以通过 Mapster 提供的对象映射方法:Adapt 方法改造上面的例子:

12.3.1 极易入门

var entity = repository.Find(1);
var dto = entity.Adapt<Dto>();

仅仅一行代码就可以实现 entity -> dto 的转换,如果涉及到赋值的复制操作,如 dto.FullNamedto.IdCard,我们只需要自定义映射规则类即可。

12.3.2 自定义映射规则

using Furion.ObjectMapper;
using Mapster;
using System;
namespace Furion.Application
{
public class Mapper : IObjectMapper
{
public void Register(TypeAdapterConfig config)
{
config.ForType<Entity, Dto>()
.Map(dest => dest.FullName, src => src.FirstName + src.LastName)
.Map(dest => dest.IdCard, src => src.IdCard.Replace("1234", "****"));
}
}
}
小知识

该映射文件 Mapper.cs 可以放在任何项目或文件夹中,Furion 会在程序启动的时候自动扫描并注入配置。

12.3.3 依赖注入方式

Mapster 除了提供 Adapt 拓展方法以外,同时还提供依赖注入的方式。

public Person(IMapper mapper)
{
var dto = _mapper.Map<Dto>(entity);
}

12.3.4 和 EFCore 配合

Mapster 还提供了 ProjectToType Linq 拓展方法减少我们手动 Select 操作,如:

正常的操作:

var destinations = context.Sources
.Select(c => new Destination {
Id = p.Id,
Name = p.Name,
Surname = p.Surname,
....
})
.ToList();

使用 Mapster 之后:

var destinations = context.Sources.ProjectToType<Destination>().ToList();

12.5 全局默认配置

Furion 提供全局默认映射配置选项 TypeAdapterConfig.GlobalSettings.Default,可在 Startup 中配置即可,如:

TypeAdapterConfig.GlobalSettings.Default
.PreserveReference(true);

12.6 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 Mapster 知识可查阅 Mapster - Wiki 文档。

- + diff --git a/docs/docs/options/index.html b/docs/docs/options/index.html index 1eace4b1dca..35b2b3638da 100644 --- a/docs/docs/options/index.html +++ b/docs/docs/options/index.html @@ -6,7 +6,7 @@ 4.2 选项 | Furion - + @@ -55,7 +55,7 @@
public void OnListener(AppInfoOptions options, IConfiguration configuration)
{
var name = options.Name; // 实时的最新值
var version = options.Version; // 实时的最新值
}
public void PostConfigure(AppInfoOptions options, IConfiguration configuration)
{
}
}
特别说明

IConfigurableOptionsListener<TOptions> 继承自 IConfigurableOptions<TOptions>

4.2.10 选项的优缺点

  • 优点

    • 强类型配置
    • 提供多种读取方式
    • 支持热加载
    • 支持设置默认值/后期配置
    • 支持在运行环境中动态配置
    • 支持验证配置有效性
    • 支持更改通知
    • 支持命名选项
  • 缺点

    • 需要定义对应类型
    • 需要在启动时注册

4.2.11 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 选项 知识可查阅 ASP.NET Core - 选项 章节。

- + diff --git a/docs/docs/performance/index.html b/docs/docs/performance/index.html index d35fa3cb704..2fb9a5cd85a 100644 --- a/docs/docs/performance/index.html +++ b/docs/docs/performance/index.html @@ -6,7 +6,7 @@ 27.2 性能测试 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/process-service/index.html b/docs/docs/process-service/index.html index 3873b1eec1f..644a7eee52b 100644 --- a/docs/docs/process-service/index.html +++ b/docs/docs/process-service/index.html @@ -6,7 +6,7 @@ 21. 进程服务 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/reference/index.html b/docs/docs/reference/index.html index e5c6e577e66..2c98c94614b 100644 --- a/docs/docs/reference/index.html +++ b/docs/docs/reference/index.html @@ -6,7 +6,7 @@ 2.3 框架项目引用 | Furion - + @@ -27,7 +27,7 @@
namespace Furion.Web.Entry
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.Inject()
.UseStartup<Startup>();
});
}
}
}

2.3.3 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/saas/index.html b/docs/docs/saas/index.html index 11e366af44b..761e478b6f0 100644 --- a/docs/docs/saas/index.html +++ b/docs/docs/saas/index.html @@ -6,7 +6,7 @@ 10. SaaS 多租户 | Furion - + @@ -62,7 +62,7 @@
public string Name { get; set; }
public string Host { get; set; }
}
}

如果需要查询该租户信息,可通过以下代码获取,如:

var tenantDbContext = Db.GetDbContext<MultiTenantDbContextLocator>();
var myTenant = tenantDbContext.Set<MyTenant>();

10.9 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/signalr/index.html b/docs/docs/signalr/index.html index 9bd615ea80d..e7805d43ff3 100644 --- a/docs/docs/signalr/index.html +++ b/docs/docs/signalr/index.html @@ -6,7 +6,7 @@ 23. 即时通讯 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/source/index.html b/docs/docs/source/index.html index 5ed6209f205..e038f226cb4 100644 --- a/docs/docs/source/index.html +++ b/docs/docs/source/index.html @@ -6,7 +6,7 @@ 1.3 源码结构 | Furion - + @@ -57,7 +57,7 @@
#prefer fields not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_field = false:suggestion
#prefer methods not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_method = false:suggestion
#prefer properties not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_property = false:suggestion
# Add file header
file_header_template = -----------------------------------------------------------------------------\nFur 是 .NET 5 平台下企业应用开发最佳实践框架。\nCopyright © 2020 Furion, Baiqian Co.,Ltd.\n\n框架名称:Furion\n框架作者:百小僧\n框架版本:1.0.0\n源码地址:Gitee:https://gitee.com/monksoul/Furion \n Github:https://github.com/monksoul/Furion \n开源协议:Apache-2.0(http://www.apache.org/licenses/LICENSE-2.0)\n-----------------------------------------------------------------------------

1.2.4 Furion 核心层

Furion 核心层是 Furion 框架的中心,也是 Furion 能够支撑起来的必备层。

源码结构:

Furion
├─Furion.csproj
├─Furion.csproj.user
├─FurStartup.cs
├─ViewEngine
| ├─IViewEngine.cs
| ├─ViewEngine.cs
| ├─Templates
| | ├─IViewEngineCompiledTemplate.cs
| | ├─IViewEngineTemplate.cs
| | ├─ViewEngineCompiledTemplate.cs
| | └ViewEngineTemplate.cs
| ├─Options
| | └ViewEngineCompilationOptions.cs
| ├─Models
| | └AnonymousTypeWrapper.cs
| ├─Exceptions
| | ├─ViewEngineCompilationException.cs
| | └ViewEngineException.cs
| ├─Compilations
| | ├─IViewEngineCompilationOptionsBuilder.cs
| | └ViewEngineCompilationOptionsBuilder.cs
├─UnifyResult
| ├─Providers
| | ├─IUnifyResultProvider.cs
| | └RESTfulResultProvider.cs
| ├─Models
| | └RESTfulResult.cs
| ├─Filters
| | └SuccessUnifyResultFilter.cs
| ├─Extensions
| | └UnifyResultServiceCollectionExtensions.cs
├─SpecificationDocument
| ├─Options
| | └SpecificationDocumentSettingsOptions.cs
| ├─Models
| | ├─GroupOrder.cs
| | ├─SpecificationOpenApiInfo.cs
| | ├─SpecificationOpenApiSecurityRequirementItem.cs
| | └SpecificationOpenApiSecurityScheme.cs
| ├─Extensions
| | ├─SpecificationDocumentApplicationBuilderExtensions.cs
| | └SpecificationDocumentServiceCollectionExtensions.cs
| ├─Builders
| | └SpecificationDocumentBuilder.cs
| ├─Assets
| | └index-mini-profiler.html
├─ObjectMapper
| ├─Extensions
| | └ObjectMapperServiceCollectionExtensions.cs
| ├─Dependencies
| | └IObjectMapper.cs
├─LinqBuilder
| ├─Visitors
| | └ParameterReplaceExpressionVisitor.cs
| ├─Extensions
| | └LinqExtensions.cs
| ├─Builders
| | └LinqExpression.cs
├─FriendlyException
| ├─Oops.cs
| ├─Providers
| | └IErrorCodeTypeProvider.cs
| ├─Options
| | └ErrorCodeMessageSettingsOptions.cs
| ├─Models
| | └MethodIfException.cs
| ├─Filters
| | └FriendlyExceptionFilter.cs
| ├─Extensions
| | └FriendlyExceptionServiceCollectionExtensions.cs
| ├─Attributes
| | ├─ErrorCodeItemMetadataAttribute.cs
| | ├─ErrorCodeTypeAttribute.cs
| | └IfExceptionAttribute.cs
├─DynamicApiController
| ├─Penetrates.cs
| ├─Providers
| | └DynamicApiControllerFeatureProvider.cs
| ├─Options
| | └DynamicApiControllerSettingsOptions.cs
| ├─Models
| | └ParameterRouteTemplate.cs
| ├─Extensions
| | └DynamicApiControllerServiceCollectionExtensions.cs
| ├─Enums
| | └ApiSeats.cs
| ├─Dependencies
| | └IDynamicApiController.cs
| ├─Conventions
| | └DynamicApiControllerApplicationModelConvention.cs
| ├─Attributes
| | ├─ApiDescriptionSettingsAttribute.cs
| | ├─ApiSeatAttribute.cs
| | └DynamicApiControllerAttribute.cs
├─DependencyInjection
| ├─Options
| | └DependencyInjectionSettingsOptions.cs
| ├─Models
| | └ExternalService.cs
| ├─Extensions
| | └DependencyInjectionServiceCollectionExtensions.cs
| ├─Enums
| | ├─InjectionActions.cs
| | ├─InjectionPatterns.cs
| | └RegisterType.cs
| ├─Dependencies
| | ├─IPrivateDependency.cs
| | ├─IScoped.cs
| | ├─ISingleton.cs
| | ├─ITransient.cs
| | ├─Proxies
| | | └IDispatchProxy.cs
| ├─Attributes
| | ├─InjectionAttribute.cs
| | └SkipScanAttribute.cs
├─DataValidation
| ├─Validators
| | └DataValidator.cs
| ├─Providers
| | └IValidationMessageTypeProvider.cs
| ├─Options
| | └ValidationTypeMessageSettingsOptions.cs
| ├─Models
| | └DataValidationResult.cs
| ├─Filters
| | └DataValidationFilter.cs
| ├─Extensions
| | ├─DataValidationExtensions.cs
| | └DataValidationServiceCollectionExtensions.cs
| ├─Enums
| | ├─ValidationPattern.cs
| | └ValidationTypes.cs
| ├─Attributes
| | ├─DataValidationAttribute.cs
| | ├─NonValidationAttribute.cs
| | ├─ValidationItemMetadataAttribute.cs
| | ├─ValidationMessageAttribute.cs
| | ├─ValidationMessageTypeAttribute.cs
| | └ValidationTypeAttribute.cs
├─DataEncryption
| ├─AESEncryption.cs
| ├─DESCEncryption.cs
| └MD5Encryption.cs
├─DatabaseAccessor
| ├─UnitOfWork
| | ├─Filters
| | | └UnitOfWorkFilter.cs
| | ├─Attributes
| | | ├─NonTransactAttribute.cs
| | | └UnitOfWorkAttribute.cs
| ├─Repositories
| | ├─EFCoreRepository.cs
| | ├─IMSRepository.cs
| | ├─IRepository.cs
| | ├─ISqlRepository.cs
| | ├─MSRepository.cs
| | ├─SqlRepository.cs
| | ├─Implantations
| | | ├─DeletableRepository.cs
| | | ├─InsertableRepository.cs
| | | ├─OperableRepository.cs
| | | ├─ReadableRepository.cs
| | | ├─SqlExecutableRepository.cs
| | | ├─SqlReaderRepository.cs
| | | ├─UpdateableRepository.cs
| | | └WritableRepository.cs
| | ├─Dependencies
| | | ├─IDeletableRepository.cs
| | | ├─IInsertableRepository.cs
| | | ├─IOperableRepository.cs
| | | ├─IReadableRepository.cs
| | | ├─IRepositoryDependency.cs
| | | ├─ISqlExecutableRepository.cs
| | | ├─ISqlReaderRepository.cs
| | | ├─IUpdateableRepository.cs
| | | └IWritableRepository.cs
| ├─Pools
| | ├─DbContextPool.cs
| | └IDbContextPool.cs
| ├─MultiTenants
| | ├─Locators
| | | └MultiTenantDbContextLocator.cs
| | ├─Enums
| | | └MultiTenantOptions.cs
| | ├─Entities
| | | └Tenant.cs
| | ├─Dependencies
| | | ├─IMultiTenantOnDatabase.cs
| | | ├─IMultiTenantOnSchema.cs
| | | ├─IMultiTenantOnTable.cs
| | | └IPrivateMultiTenant.cs
| ├─Models
| | ├─DbProvider.cs
| | ├─PagedList.cs
| | ├─ProcedureOutputResult.cs
| | ├─ProcedureOutputValue.cs
| | ├─SqlTemplate.cs
| | └SqlTemplateParameter.cs
| ├─Locators
| | ├─IDbContextLocator.cs
| | └MasterDbContextLocator.cs
| ├─Interceptors
| | ├─DbContextSaveChangesInterceptor.cs
| | ├─SqlCommandProfilerInterceptor.cs
| | └SqlConnectionProfilerInterceptor.cs
| ├─Helpers
| | └DbHelpers.cs
| ├─Extensions
| | ├─DatabaseAccessorServiceCollectionExtensions.cs
| | ├─PagedQueryableExtensions.cs
| | ├─Repositories
| | | ├─IEntityExtensions.cs
| | | ├─IEntityWithDbContextLocatorExtensions.cs
| | | └SqlExtensions.cs
| | ├─DatabaseProvider
| | | ├─DatabaseProviderServiceCollectionExtensions.cs
| | | └Penetrates.cs
| | ├─DatabaseFacade
| | | ├─DbDataConvertExtensions.cs
| | | ├─DbObjectExtensions.cs
| | | └SqlAdoNetExtensions.cs
| ├─Enums
| | ├─DbFunctionType.cs
| | ├─EFCoreErrorCodes.cs
| | └ManualOptions.cs
| ├─Entities
| | ├─Dependencies
| | | ├─Entity.cs
| | | ├─EntityBase.cs
| | | ├─EntityNotKey.cs
| | | ├─IEntity.cs
| | | └IEntityNotKey.cs
| | ├─Configures
| | | ├─IEntitySeedData.cs
| | | ├─IEntityTypeBuilder.cs
| | | ├─IModelBuilderFilter.cs
| | | └IPrivateModelBuilder.cs
| | ├─Attributes
| | | ├─FakeDeleteAttribute.cs
| | | ├─NonAutomaticAttribute.cs
| | | └QueryableFunctionAttribute.cs
| ├─DynamicModels
| | ├─DynamicModelCacheKeyFactory.cs
| | └IEntityMutableTable.cs
| ├─Contexts
| | ├─AppDbContext.cs
| | ├─Builders
| | | ├─AppDbContextBuilder.cs
| | | ├─Models
| | | | └DbContextCorrelationType.cs
| | ├─Attributes
| | | └AppDbContextAttribute.cs
| ├─Attributes
| | └DbParameterAttribute.cs
| ├─Advances
| | ├─Proxies
| | | └SqlDispatchProxy.cs
| | ├─Models
| | | └SqlProxyMethod.cs
| | ├─Dependencies
| | | └ISqlDispatchProxy.cs
| | ├─Attributes
| | | ├─SqlExecuteAttribute.cs
| | | ├─SqlFunctionAttribute.cs
| | | ├─SqlProcedureAttribute.cs
| | | ├─Basics
| | | | ├─SqlObjectProxyAttribute.cs
| | | | ├─SqlProxyAttribute.cs
| | | | └SqlSentenceProxyAttribute.cs
├─CorsAccessor
| ├─Options
| | └CorsAccessorSettingsOptions.cs
| ├─Extensions
| | ├─CorsAccessorApplicationBuilderExtensions.cs
| | └CorsAccessorServiceCollectionExtensions.cs
├─ConfigurableOptions
| ├─Options
| | └IConfigurableOptions.cs
| ├─Extensions
| | └ConfigurableOptionsServiceCollectionExtensions.cs
| ├─Attributes
| | └OptionsSettingsAttribute.cs
├─Authorization
| ├─Penetrates.cs
| ├─Requirements
| | └AuthorizePolicyRequirement.cs
| ├─Providers
| | └AuthorizePolicyProvider.cs
| ├─Options
| | └JWTSettingsOptions.cs
| ├─Handlers
| | └AuthorizePolicyHandler.cs
| ├─Extensions
| | └PolicyAuthorizationServiceCollectionExtensions.cs
| ├─Attributes
| | └AuthorizePolicyAttribute.cs
├─App
| ├─App.cs
| ├─Startups
| | ├─AppStartup.cs
| | └HostingStartup.cs
| ├─Options
| | └AppSettingsOptions.cs
| ├─Filters
| | └StartupFilter.cs
| ├─Extensions
| | ├─AppApplicationBuilderExtensions.cs
| | ├─AppServiceCollectionExtensions.cs
| | ├─WebHostBuilderExtensions.cs
| | ├─Types
| | | └ObjectExtensions.cs
| ├─Attributes
| | └AppStartupAttribute.cs

1.2.5 Furion.Application 业务应用层

Furion.Application 业务应用层是最常用的层,几乎所有的业务代码都在这个层中编写。

源码结构:

Furion.Application
├─Furion.Application.Core.csproj
├─Furion.Application.Core.xml
└FurApplicationStartup.cs

1.2.6 Furion.Core 仓储实体层

Furion.Core 主要是存储自定义仓储和定义实体的层。

源码结构:

Furion.Core
├─Furion.Core.csproj
└FurCoreStartup.cs

1.2.7 Furion.Database.Migrations 数据库架构维护层

Furion.Database.Migrations 主要是用来存放 Database FirstCode First 生成的维护文件。

源码结构:

Furion.Database.Migrations
└Furion.Database.Migrations.csproj

1.2.8 Furion.EntityFramework.Core 数据库上下文配置层

Furion.EntityFramework.Core 主要是用来配置数据库上下文和其他数据库相关配置信息的。

源码结构:

Furion.EntityFramework.Core
└Furion.EntityFramework.Core.csproj

1.2.9 Furion.Web.Core 应用核心层

Furion.Web.Core 主要是用来配置 Web 入口一些代码,如 FilterMiddlewares 等。

源码结构:

Furion.Web.Core
├─Furion.Web.Core.xml
└FurWebCoreStartup.cs

1.2.10 Furion.Web.Entry 应用入口层

Furion.Web.Entry 是我们的应用层,也就是我们的 Web 项目层,发布层。

源码结构:

Furion.Web.Entry
├─appsettings.Development.json
├─appsettings.json
├─Furion.Web.Entry.csproj
├─Furion.Web.Entry.csproj.user
├─Furion.Web.Entry.xml
├─Program.cs
├─Startup.cs
├─wwwroot
| └README.md
├─Properties
| └launchSettings.json
├─Controllers
- + diff --git a/docs/docs/specification-document/index.html b/docs/docs/specification-document/index.html index 5ca06622b38..1de7c98ca94 100644 --- a/docs/docs/specification-document/index.html +++ b/docs/docs/specification-document/index.html @@ -6,7 +6,7 @@ 6. 规范化接口文档 | Furion - + @@ -59,7 +59,7 @@
/// <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,
Successed = false,
Data = null,
Errors = "401 Unauthorized",
Extras = UnifyResultContext.Take()
}, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonSerializerUtility.EnabledPascalPropertyNaming ? null : JsonNamingPolicy.CamelCase
});
break;
// 处理 403 状态码
case StatusCodes.Status403Forbidden:
await context.Response.WriteAsJsonAsync(new RESTfulResult<object>
{
StatusCode = StatusCodes.Status403Forbidden,
Successed = false,
Data = null,
Errors = "403 Forbidden",
Extras = UnifyResultContext.Take()
}, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonSerializerUtility.EnabledPascalPropertyNaming ? null : JsonNamingPolicy.CamelCase
});
break;
default:
break;
}
}
}
}

之后在 Startup.cs 中注册即可:

services.AddControllers()
.AddInjectWithUnifyResult<RESTfulResultProvider>();

6.8 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/split-db/index.html b/docs/docs/split-db/index.html index 8e956f8ce72..82825f29320 100644 --- a/docs/docs/split-db/index.html +++ b/docs/docs/split-db/index.html @@ -6,7 +6,7 @@ 9.28 分表分库 | Furion - + @@ -29,7 +29,7 @@
// 通过数据库上下文定位器切换
repository.Change<Entity, MyDbContextLocator2>();

如需跨库查询,需用到数据库技术,如 SqlServer 链接服务器或同义词。

  • 动态切换数据库表
// 直接改变表,会有多线程操作bug,同时无法刷新模型
repository.ChangeTable("数据库表");
// 创建新的 DbContext,然后刷新 OnModelCreating(推荐方式)
var dynamicDbContextResolve = App.GetService<Func<Type, IScoped, DbContext>>();
var dynamicDbContext = dynamicDbContextResolve(typeof(MyDbContextLocator), default);
// 重新调用 OnModelCreating,在 OnModelCreating 中配置 ToTable("动态表") 即可。
DynamicModelCacheKeyFactory.RebuildModels();
var persons= dynamicDbContext.Set<Person>();
persons.Add(new Person{});
了解更多

想了解更多 DynamicModelCacheKeyFactory 知识可查阅 EF Core - 多个模型之间交替 章节。

9.28.7 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/docs/template/index.html b/docs/docs/template/index.html index 94713823c4e..ebcb3413824 100644 --- a/docs/docs/template/index.html +++ b/docs/docs/template/index.html @@ -6,7 +6,7 @@ 2.2 官方脚手架 | Furion - + @@ -25,7 +25,7 @@

2.2 官方脚手架

2.2.1 脚手架

Furion 官方提供了多种 Web 应用类型的脚手架,方便大家快速创建多层架构项目。目前支持以下应用脚手架:

模板类型名称版本关键词描述
nugetFurion.Template.Mvcnuget👉 furionmvcMvc 模板
nugetFurion.Template.Apinuget👉 furionapiWebApi 模板
nugetFurion.Template.Appnuget👉 furionappMvc/WebApi 模板
nugetFurion.Template.Razornuget👉 furionrazorRazorPages 模板
nugetFurion.Template.RazorWithWebApinuget👉 furionrazorapiRazorPages/WebApi 模板
nugetFurion.Template.Blazornuget👉 furionblazorBlazor 模板
nugetFurion.Template.BlazorWithWebApinuget👉 furionblazorapiBlazor/WebApi 模板

2.2.2 安装脚手架

打开 CMDPowershell 执行模板安装命令:

dotnet new --install Furion.Template.Mvc::1.1.1

2.2.3 使用脚手架

dotnet new furionmvc -n 项目名称

这样就可以生成项目代码了,生成之后推荐将所有的 nuget 包更新到最新版本。

特别提醒

furionmvc 对应的是上面列表的 关键字,我们也可以通过 dotnet new --list 查看。

想了解更多可以使用 dotnet new 关键字 --help 查看更多参数。

2.2.4 脚手架更新

只需要重新安装最新版替换即可,如:

dotnet new --install Furion.Template.Mvc::1.x.x

不带版本号总是安装最新的版本。

2.2.5 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 模板知识 知识可查阅 dotnet-new 模板 章节。

- + diff --git a/docs/docs/tran/index.html b/docs/docs/tran/index.html index 96021ab3cf9..4f01a27203c 100644 --- a/docs/docs/tran/index.html +++ b/docs/docs/tran/index.html @@ -6,7 +6,7 @@ 9.26 事务和工作单元 | Furion - + @@ -37,7 +37,7 @@
// 框架封装的仓储
_testRepository.Insert(new Blog { Url = "http://blogs.msdn.com/dotnet" });
_testRepository.SaveChanges();
// 提交事务
scope.Complete();
}
catch (System.Exception)
{
// 自动回滚
}
}
}

9.26.4 工作单元特性说明

9.26.4.1 [UnitOfWork]

[UnitOfWork] 特性用来标记事务信息,如作用范围,隔离级别等。

  • Enabled:是否启动工作单元,默认 true
  • ScopeOption:定义事务范围行为,默认 TransactionScopeOption.Required
  • IsolationLevel:设置事务隔离级别,默认 IsolationLevel.ReadCommitted;
  • AsyncFlowOption:允许跨线程连续任务的事务流,如有异步操作需开启该选项,默认开启
特别注意

一旦方法贴了 [UnitOfWork(false)] 特性后,那么该方法不再启用工作单元模式,也就是不包含事务,也不会自动提交数据库。慎用!

9.26.5 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 事务 知识可查阅 EF Core - 使用事务 章节。

- + diff --git a/docs/docs/unittest/index.html b/docs/docs/unittest/index.html index f2c51a1523c..3e817d5047d 100644 --- a/docs/docs/unittest/index.html +++ b/docs/docs/unittest/index.html @@ -6,7 +6,7 @@ 27.1 单元测试 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/docs/docs/view-engine/index.html b/docs/docs/view-engine/index.html index 1db12fc5801..92d55d4f3ea 100644 --- a/docs/docs/view-engine/index.html +++ b/docs/docs/view-engine/index.html @@ -6,7 +6,7 @@ 16. 视图引擎 | Furion - + @@ -30,7 +30,7 @@
var template = _viewEngine.Compile<CustomModel>(content);
var result = template.Run(instance =>
{
instance.A = 10;
instance.B = "Alex";
});

结果:

Hello 10, Alex, -=123=-

16.5 IViewEngine 接口

IViewEngine 提供了简单方便的 RunCompile 方法,也提供了最原始化的 CompileRun 方法。

通过原始的 CompileRun 方法可以实现很多复杂的逻辑和自定义指令集。

/// <summary>
/// 编译模板
/// </summary>
/// <param name="content"></param>
/// <param name="builderAction"></param>
/// <returns></returns>
IViewEngineTemplate Compile(string content, Action<IViewEngineOptionsBuilder> builderAction = null);
/// <summary>
/// 编译模板
/// </summary>
/// <param name="content"></param>
/// <param name="builderAction"></param>
/// <returns></returns>
Task<IViewEngineTemplate> CompileAsync(string content, Action<IViewEngineOptionsBuilder> builderAction = null);
/// <summary>
/// 编译模板
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="content"></param>
/// <param name="builderAction"></param>
/// <returns></returns>
IViewEngineTemplate<T> Compile<T>(string content, Action<IViewEngineOptionsBuilder> builderAction = null)
where T : IViewEngineModel;
/// <summary>
/// 编译模板
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="content"></param>
/// <param name="builderAction"></param>
/// <returns></returns>
Task<IViewEngineTemplate<T>> CompileAsync<T>(string content, Action<IViewEngineOptionsBuilder> builderAction = null)
where T : IViewEngineModel;

16.6 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/docs/index.html b/docs/index.html index 0784cd069c2..3bcefa71513 100644 --- a/docs/index.html +++ b/docs/index.html @@ -6,7 +6,7 @@ 让 .NET 开发更简单,更通用,更流行。 Furion | Furion - + @@ -21,7 +21,7 @@

Your Docusaurus site did not load properly.

A very common reason is a wrong site baseUrl configuration.

Current configured baseUrl = / (default value)

We suggest trying baseUrl =

让 .NET 开发更简单,更通用,更流行。

[object Object]

.NET 5 新起点

.NET 5 是 .NET 的重要且令人兴奋的新方向。你会看到 .NET 变得更加简单,但也有更广泛的功能和实用程序。所有新的开发和功能都将是 .NET 5 的一部分,包括新的 C# 版本

[object Object]

“六极” 架构

Furion 在设计之初就秉承着 “六极” :极易入门、极速开发、极少依赖、极少配置、极其灵活、极易维护 的设计思想,在架构设计上做了大量的优化,支持各个能力阶层技术员极速上手。

[object Object]

冲一杯咖啡的时间

Furion 除了独具创新的设计理念和灵活的架构设计以外,同时还结合了主流的敏捷开发模式打造的一款极速开发框架。只需冲制一杯咖啡的时间便可完成工作

- + diff --git a/docs/runtime~main.02007f49.js b/docs/runtime~main.2ee33f4e.js similarity index 96% rename from docs/runtime~main.02007f49.js rename to docs/runtime~main.2ee33f4e.js index c6279cbb089..f5bacf11b67 100644 --- a/docs/runtime~main.02007f49.js +++ b/docs/runtime~main.2ee33f4e.js @@ -1 +1 @@ -!function(e){function c(c){for(var a,r,t=c[0],n=c[1],o=c[2],u=0,l=[];u=0||(b[a]=e[a]);return b}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(b[a]=e[a])}return b}var p=b.a.createContext({}),o=function(e){var t=b.a.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},O=function(e){var t=o(e.components);return b.a.createElement(p.Provider,{value:t},e.children)},j={inlineCode:"code",wrapper:function(e){var t=e.children;return b.a.createElement(b.a.Fragment,{},t)}},m=b.a.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),O=o(a),m=n,g=O["".concat(c,".").concat(m)]||O[m]||j[m]||r;return a?b.a.createElement(g,l(l({ref:t},p),{},{components:a})):b.a.createElement(g,l({ref:t},p))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,c=new Array(r);c[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:n,c[1]=l;for(var p=2;p=0||(b[a]=e[a]);return b}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(b[a]=e[a])}return b}var p=b.a.createContext({}),o=function(e){var t=b.a.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},O=function(e){var t=o(e.components);return b.a.createElement(p.Provider,{value:t},e.children)},j={inlineCode:"code",wrapper:function(e){var t=e.children;return b.a.createElement(b.a.Fragment,{},t)}},m=b.a.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),O=o(a),m=n,g=O["".concat(c,".").concat(m)]||O[m]||j[m]||r;return a?b.a.createElement(g,l(l({ref:t},p),{},{components:a})):b.a.createElement(g,l({ref:t},p))}));function g(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,c=new Array(r);c[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:n,c[1]=l;for(var p=2;p Page Not Found | Furion - +

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/handbook/build/4c30b939.242cc4f5.js b/handbook/build/4c30b939.b9285c57.js similarity index 75% rename from handbook/build/4c30b939.242cc4f5.js rename to handbook/build/4c30b939.b9285c57.js index 7e382acbb68..3c868876210 100644 --- a/handbook/build/4c30b939.242cc4f5.js +++ b/handbook/build/4c30b939.b9285c57.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[28],{154:function(e,t,a){"use strict";a.d(t,"a",(function(){return o})),a.d(t,"b",(function(){return u}));var n=a(0),b=a.n(n);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function c(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function l(e){for(var t=1;t=0||(b[a]=e[a]);return b}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(b[a]=e[a])}return b}var p=b.a.createContext({}),O=function(e){var t=b.a.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},o=function(e){var t=O(e.components);return b.a.createElement(p.Provider,{value:t},e.children)},j={inlineCode:"code",wrapper:function(e){var t=e.children;return b.a.createElement(b.a.Fragment,{},t)}},m=b.a.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),o=O(a),m=n,u=o["".concat(c,".").concat(m)]||o[m]||j[m]||r;return a?b.a.createElement(u,l(l({ref:t},p),{},{components:a})):b.a.createElement(u,l({ref:t},p))}));function u(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,c=new Array(r);c[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:n,c[1]=l;for(var p=2;p=0||(b[a]=e[a]);return b}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(b[a]=e[a])}return b}var p=b.a.createContext({}),O=function(e){var t=b.a.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},o=function(e){var t=O(e.components);return b.a.createElement(p.Provider,{value:t},e.children)},j={inlineCode:"code",wrapper:function(e){var t=e.children;return b.a.createElement(b.a.Fragment,{},t)}},m=b.a.forwardRef((function(e,t){var a=e.components,n=e.mdxType,r=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),o=O(a),m=n,u=o["".concat(c,".").concat(m)]||o[m]||j[m]||r;return a?b.a.createElement(u,l(l({ref:t},p),{},{components:a})):b.a.createElement(u,l({ref:t},p))}));function u(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=a.length,c=new Array(r);c[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:n,c[1]=l;for(var p=2;p Blog | Furion - + @@ -18,14 +18,14 @@ - +

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/handbook/build/blog/tags/furion/index.html b/handbook/build/blog/tags/furion/index.html index 2560b52f646..9cbc4f5785f 100644 --- a/handbook/build/blog/tags/furion/index.html +++ b/handbook/build/blog/tags/furion/index.html @@ -6,7 +6,7 @@ Posts tagged "furion" | Furion - + @@ -18,14 +18,14 @@ - +

1 post tagged with "furion"

View All Tags

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/handbook/build/blog/tags/furos/index.html b/handbook/build/blog/tags/furos/index.html index 14a017bb882..4a20eed3ec1 100644 --- a/handbook/build/blog/tags/furos/index.html +++ b/handbook/build/blog/tags/furos/index.html @@ -6,7 +6,7 @@ Posts tagged "furos" | Furion - + @@ -18,14 +18,14 @@ - +

1 post tagged with "furos"

View All Tags

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/handbook/build/blog/tags/index.html b/handbook/build/blog/tags/index.html index c4dc18d8bb9..b061302ce0b 100644 --- a/handbook/build/blog/tags/index.html +++ b/handbook/build/blog/tags/index.html @@ -6,7 +6,7 @@ Tags | Furion - + @@ -23,7 +23,7 @@ - + diff --git a/handbook/build/blog/tags/net-5/index.html b/handbook/build/blog/tags/net-5/index.html index b96483fb4b8..528cadee525 100644 --- a/handbook/build/blog/tags/net-5/index.html +++ b/handbook/build/blog/tags/net-5/index.html @@ -6,7 +6,7 @@ Posts tagged ".net5" | Furion - + @@ -18,14 +18,14 @@ - +

1 post tagged with ".net5"

View All Tags

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/handbook/build/blog/tags/net/index.html b/handbook/build/blog/tags/net/index.html index 72a67deeaf5..5ab096a74bc 100644 --- a/handbook/build/blog/tags/net/index.html +++ b/handbook/build/blog/tags/net/index.html @@ -6,7 +6,7 @@ Posts tagged ".net" | Furion - + @@ -18,14 +18,14 @@ - +

1 post tagged with ".net"

View All Tags

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/handbook/build/blog/tags/netcore/index.html b/handbook/build/blog/tags/netcore/index.html index 78527f64abd..cf1d7666215 100644 --- a/handbook/build/blog/tags/netcore/index.html +++ b/handbook/build/blog/tags/netcore/index.html @@ -6,7 +6,7 @@ Posts tagged ".netcore" | Furion - + @@ -18,14 +18,14 @@ - +

1 post tagged with ".netcore"

View All Tags

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

- + @@ -37,7 +37,7 @@ - + \ No newline at end of file diff --git a/handbook/build/blog/welcome/index.html b/handbook/build/blog/welcome/index.html index ec0f4a6514c..4653e62d5fe 100644 --- a/handbook/build/blog/welcome/index.html +++ b/handbook/build/blog/welcome/index.html @@ -6,7 +6,7 @@ Furion 介绍 | Furion - + @@ -18,13 +18,13 @@ - +
-

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

🌭 开源地址

🍿 Docker 镜像

  • Docker Hub 线上镜像
docker run --name furion -p 5000:80 monksoul/furion:v1.4.3
  • 手动 打包镜像

打开 CMD/Shell/PowerShell 进入 Furion 项目根目录打包 Furion 镜像:

docker build -t furion:v1.4.3 .

打包成功后,直接 docker run

docker run --name furion -p 5000:80 furion:v1.4.3

🥥 Furion 官方包

包类型名称版本描述
nugetFurionnugetFurion 总包
nugetFurion.Extras.Authentication.JwtBearernugetFurion Jwt 拓展包
nugetFurion.Extras.DependencyModel.CodeAnalysisnugetFurion 动态反射 拓展包

🍄 Furion 脚手架

模板类型名称版本描述
nugetFurion.Template.MvcnugetMvc 模板
nugetFurion.Template.ApinugetWebApi 模板
nugetFurion.Template.AppnugetMvc/WebApi 模板
nugetFurion.Template.RazornugetRazorPages 模板
nugetFurion.Template.RazorWithWebApinugetRazorPages/WebApi 模板
nugetFurion.Template.BlazornugetBlazor 模板
nugetFurion.Template.BlazorWithWebApinugetBlazor/WebApi 模板

如何使用脚手架

🍎 框架特点

  • 全新面貌:基于 .NET 5 平台,没有历史包袱
  • 极易入门:只需要一个 Inject() 即可完成配置
  • 极速开发:内置丰富的企业应用开发功能
  • 极少依赖:框架只依赖三个第三方包
  • 极其灵活:轻松面对多变复杂的需求
  • 极易维护:采用独特的架构思想,只为长久维护设计
  • 完整文档:提供完善的开发文档

🥞 架构设计

正在整理中...

🥝 功能模块

🥐 框架依赖

Furion 为了追求极速入门,极致性能,尽可能的不使用或减少第三方依赖。目前 Furion 仅集成了以下三个依赖:

麻雀虽小五脏俱全。Furion 即使只集成了这三个依赖,但是主流的 依赖注入/控制反转AOP 面向切面编程,事件总线数据验证数据库操作 等等一个都不少。

🥗 环境要求

  • Visual Studio 2019 16.8 +
  • .NET 5 SDK +
  • .Net Standard 2.1 +

🥪 支持平台

  • 运行环境
    • Windows
    • Linux
    • MacOS
    • Docker/K8S/K3S/Rancher
    • Xamarin/MAUI
  • 数据库
    • SqlServer
    • Sqlite
    • Azure Cosmos
    • MySql
    • MariaDB
    • PostgreSQL
    • InMemoryDatabase
    • Oracle(并未完全适配
    • Firebird
    • 达梦数据库
  • 应用部署
    • Kestrel
    • Nginx
    • Jexus
    • IIS
    • Apache
    • PM2
    • Supervisor
    • 单文件
    • 容器(Docker/K8S/K3S/Rancher)

🍖 关于性能

Furion 目前采用 Visual Studio 2019 16.8 自带性能测试和 JMeter 进行测试,由于篇幅有限,只贴部分测试图,测试结果如下:


🍚 关于作者

一个拥有 12 年开发经验 .NETer。喜欢分享,喜欢新技术,在互联网多个技术领域皆有涉猎,dotNET China MIP,同时多次获得开源中国 Gitee 授予 GVP 证书。

🍤 项目成员

🎈 欢迎更多的开发者加入 Furion 大家庭。

🍝 他们都在用

  • 百签科技(广东)有限公司
  • 码为科技(广州)有限公司
  • 广州启顺国际货运代理有限公司
  • 森丰供应链服务(广州)有限公司
  • 中山赢友网络科技有限公司
  • 中山模思软件科技有限公司
  • 珠海市恒泰新软件有限责任公司
  • 珠海思诺锐创软件有限公司
  • 深圳市易胜科技有限公司
  • 重庆虫儿飞科技有限公司
  • 重庆林木森科技有限公司
  • 深圳市品立方科技有限公司
  • 上海奥达科股份有限公司
  • 中山市泓升软件科技有限公司
  • 唐山天权建筑科技有限公司
  • 北京帝龙科技有限公司
  • 深圳市希立网络有限公司
  • 广州市飞帆计算机技术有限公司
  • 泉州市润海信息科技有限公司
  • 成都市彼岸里信息科技有限公司
  • 福建省山水生活服务集团有限公司

如果您的项目使用到 Furion 开发,可以告诉我们。

🍻 贡献代码

Furion 遵循 Apache-2.0 开源协议,欢迎大家提交 PRIssue

如果要为项目做出贡献,请查看贡献指南。

🍍 捐赠列表

注:排序按捐赠顺序书写

捐赠人昵称捐赠金额(元)附语
🤴 爱吃油麦菜100感谢您的开源项目!
👳‍♂️ 麦壳饼200感谢您的开源项目!
👨 Sun100感谢您的开源项目!
👶 d61761720感谢您的开源项目!
👦 Diqiguoji00816.66见贤思齐
👲 nodyang100感谢您的开源项目!
👳‍♀️ mictxd100吹过的牛都实现。
🧓 欧流全10希望将来超越 Spring
👨‍⚕️ lionkon10...看了框架感觉拿来学习是很不错的...
😤 好人!10Nice 的小僧,我们的 dotnetchina 马上火起来了
😮 木木 Woody10感谢您的开源项目!
😚 Joker HouQQ 超级会员一个月
🤠 ccdfzQQ 专属红包 199
🌝 天夫李总支付宝 6666Furion 非常有意思,持续关注
😝 六尘子微信红包 199公司已经使用,小小敬意
🤠 ccdfzQQ 专属红包 200赞助一根内存条
🤑 邓亮灯28.88感谢您的开源项目!
😬 天道酬勤微信二维码 188小小心意
🥰 却月居士QQ 专属红包 100恭喜发财
🤩 鲁旭100感谢您的开源项目!
😬 散客行微信二维码 666终于找到一个不错的框架
😌 本心100项目功能很强大
🙆‍♂️ 毕业生100请你喝杯咖啡
🦹‍♀️ 猪鼻子微信二维码 668
🧟‍♂️ 明年·今日200使用的框架里最爽的,最理想的!加油
👨‍🎓 过去的过去50感谢您的开源项目!
👨‍🔧 万里兮100新公司的第一个项目从 Furion 开始
👴 Muphalem20很热心很亲切的开发者,加油!
💂‍♂️ 吃锅巴的码农微信二维码 500就冲你的文档写得好!
🤴 三重罗生门微信红包 200下次烤鱼你请!

非常感谢您们的支持,正是因为您们,中国开源才可以越走越远,Furion 越走越远。

🥔 QQ 交流群

🧆 友情链接

👉 Furion 👉 SqlSugar 👉 Layx 👉 t-io 👉 ThinkPHP 👉 Hutool 👉 BootstrapAdmin 👉 BootstrapBlazor 👉 IoTSharp 👉 Anno.Core 👉 WaterCloud

+

Furion 介绍

dotnet中国

dotnet中国

为中国 .NET 开发者提供优质的资讯和技术分享。

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

🌭 开源地址

🍿 Docker 镜像

  • Docker Hub 线上镜像
docker run --name furion -p 5000:80 monksoul/furion:v1.4.3
  • 手动 打包镜像

打开 CMD/Shell/PowerShell 进入 Furion 项目根目录打包 Furion 镜像:

docker build -t furion:v1.4.3 .

打包成功后,直接 docker run

docker run --name furion -p 5000:80 furion:v1.4.3

🥥 Furion 官方包

包类型名称版本描述
nugetFurionnugetFurion 总包
nugetFurion.Extras.Authentication.JwtBearernugetFurion Jwt 拓展包
nugetFurion.Extras.DependencyModel.CodeAnalysisnugetFurion 动态反射 拓展包

🍄 Furion 脚手架

模板类型名称版本描述
nugetFurion.Template.MvcnugetMvc 模板
nugetFurion.Template.ApinugetWebApi 模板
nugetFurion.Template.AppnugetMvc/WebApi 模板
nugetFurion.Template.RazornugetRazorPages 模板
nugetFurion.Template.RazorWithWebApinugetRazorPages/WebApi 模板
nugetFurion.Template.BlazornugetBlazor 模板
nugetFurion.Template.BlazorWithWebApinugetBlazor/WebApi 模板

如何使用脚手架

🍎 框架特点

  • 全新面貌:基于 .NET 5 平台,没有历史包袱
  • 极易入门:只需要一个 Inject() 即可完成配置
  • 极速开发:内置丰富的企业应用开发功能
  • 极少依赖:框架只依赖三个第三方包
  • 极其灵活:轻松面对多变复杂的需求
  • 极易维护:采用独特的架构思想,只为长久维护设计
  • 完整文档:提供完善的开发文档

🥞 架构设计

正在整理中...

🥝 功能模块

🥐 框架依赖

Furion 为了追求极速入门,极致性能,尽可能的不使用或减少第三方依赖。目前 Furion 仅集成了以下三个依赖:

麻雀虽小五脏俱全。Furion 即使只集成了这三个依赖,但是主流的 依赖注入/控制反转AOP 面向切面编程,事件总线数据验证数据库操作 等等一个都不少。

🥗 环境要求

  • Visual Studio 2019 16.8 +
  • .NET 5 SDK +
  • .Net Standard 2.1 +

🥪 支持平台

  • 运行环境
    • Windows
    • Linux
    • MacOS
    • Docker/K8S/K3S/Rancher
    • Xamarin/MAUI
  • 数据库
    • SqlServer
    • Sqlite
    • Azure Cosmos
    • MySql
    • MariaDB
    • PostgreSQL
    • InMemoryDatabase
    • Oracle(并未完全适配
    • Firebird
    • 达梦数据库
  • 应用部署
    • Kestrel
    • Nginx
    • Jexus
    • IIS
    • Apache
    • PM2
    • Supervisor
    • 单文件
    • 容器(Docker/K8S/K3S/Rancher)

🍖 关于性能

Furion 目前采用 Visual Studio 2019 16.8 自带性能测试和 JMeter 进行测试,由于篇幅有限,只贴部分测试图,测试结果如下:


🍚 关于作者

一个拥有 12 年开发经验 .NETer。喜欢分享,喜欢新技术,在互联网多个技术领域皆有涉猎,dotNET China MIP,同时多次获得开源中国 Gitee 授予 GVP 证书。

🍤 项目成员

🎈 欢迎更多的开发者加入 Furion 大家庭。

🍝 他们都在用

  • 百签科技(广东)有限公司
  • 码为科技(广州)有限公司
  • 广州启顺国际货运代理有限公司
  • 森丰供应链服务(广州)有限公司
  • 中山赢友网络科技有限公司
  • 中山模思软件科技有限公司
  • 珠海市恒泰新软件有限责任公司
  • 珠海思诺锐创软件有限公司
  • 深圳市易胜科技有限公司
  • 重庆虫儿飞科技有限公司
  • 重庆林木森科技有限公司
  • 深圳市品立方科技有限公司
  • 上海奥达科股份有限公司
  • 中山市泓升软件科技有限公司
  • 唐山天权建筑科技有限公司
  • 北京帝龙科技有限公司
  • 深圳市希立网络有限公司
  • 广州市飞帆计算机技术有限公司
  • 泉州市润海信息科技有限公司
  • 成都市彼岸里信息科技有限公司
  • 福建省山水生活服务集团有限公司
  • 安徽宝典网络科技有限公司

如果您的项目使用到 Furion 开发,可以告诉我们。

🍻 贡献代码

Furion 遵循 Apache-2.0 开源协议,欢迎大家提交 PRIssue

如果要为项目做出贡献,请查看贡献指南。

🍍 捐赠列表

注:排序按捐赠顺序书写

捐赠人昵称捐赠金额(元)附语
🤴 爱吃油麦菜100感谢您的开源项目!
👳‍♂️ 麦壳饼200感谢您的开源项目!
👨 Sun100感谢您的开源项目!
👶 d61761720感谢您的开源项目!
👦 Diqiguoji00816.66见贤思齐
👲 nodyang100感谢您的开源项目!
👳‍♀️ mictxd100吹过的牛都实现。
🧓 欧流全10希望将来超越 Spring
👨‍⚕️ lionkon10...看了框架感觉拿来学习是很不错的...
😤 好人!10Nice 的小僧,我们的 dotnetchina 马上火起来了
😮 木木 Woody10感谢您的开源项目!
😚 Joker HouQQ 超级会员一个月
🤠 ccdfzQQ 专属红包 199
🌝 天夫李总支付宝 6666Furion 非常有意思,持续关注
😝 六尘子微信红包 199公司已经使用,小小敬意
🤠 ccdfzQQ 专属红包 200赞助一根内存条
🤑 邓亮灯28.88感谢您的开源项目!
😬 天道酬勤微信二维码 188小小心意
🥰 却月居士QQ 专属红包 100恭喜发财
🤩 鲁旭100感谢您的开源项目!
😬 散客行微信二维码 666终于找到一个不错的框架
😌 本心100项目功能很强大
🙆‍♂️ 毕业生100请你喝杯咖啡
🦹‍♀️ 猪鼻子微信二维码 668
🧟‍♂️ 明年·今日200使用的框架里最爽的,最理想的!加油
👨‍🎓 过去的过去50感谢您的开源项目!
👨‍🔧 万里兮100新公司的第一个项目从 Furion 开始
👴 Muphalem20很热心很亲切的开发者,加油!
💂‍♂️ 吃锅巴的码农微信二维码 500就冲你的文档写得好!
🤴 三重罗生门微信红包 200下次烤鱼你请!

非常感谢您们的支持,正是因为您们,中国开源才可以越走越远,Furion 越走越远。

🥔 QQ 交流群

🧆 友情链接

👉 Furion 👉 SqlSugar 👉 Layx 👉 t-io 👉 ThinkPHP 👉 Hutool 👉 BootstrapAdmin 👉 BootstrapBlazor 👉 IoTSharp 👉 Anno.Core 👉 WaterCloud

- + @@ -36,6 +36,6 @@ - + \ No newline at end of file diff --git a/handbook/build/d3c206bc.816569fe.js b/handbook/build/d3c206bc.a5d72d34.js similarity index 99% rename from handbook/build/d3c206bc.816569fe.js rename to handbook/build/d3c206bc.a5d72d34.js index 497dba5af5a..482bc1ed679 100644 --- a/handbook/build/d3c206bc.816569fe.js +++ b/handbook/build/d3c206bc.a5d72d34.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[64],{129:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return b})),n.d(t,"metadata",(function(){return c})),n.d(t,"rightToc",(function(){return l})),n.d(t,"default",(function(){return p}));var r=n(3),a=n(7),o=(n(0),n(154)),i=n(156),b={slug:"welcome",title:"Furion \u4ecb\u7ecd",author:"dotnet\u4e2d\u56fd",author_title:"\u4e3a\u4e2d\u56fd .NET \u5f00\u53d1\u8005\u63d0\u4f9b\u4f18\u8d28\u7684\u8d44\u8baf\u548c\u6280\u672f\u5206\u4eab\u3002",author_url:"https://furion.pro",author_image_url:"https://i.loli.net/2020/10/01/94AxjHp21aPKQWd.png",tags:["furion","furos",".net",".netcore",".net5"]},c={permalink:"/furion/blog/welcome",editUrl:"https://gitee.com/monksoul/Furion/tree/master/handbook/blog/2020-08-19-welcome.mdx",source:"@site/blog\\2020-08-19-welcome.mdx",description:"=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=a.a.createContext({}),u=function(e){var t=a.a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):b(b({},t),e)),n},p=function(e){var t=u(e.components);return a.a.createElement(l.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.a.createElement(a.a.Fragment,{},t)}},m=a.a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,O=p["".concat(i,".").concat(m)]||p[m]||s[m]||o;return n?a.a.createElement(O,b(b({ref:t},l),{},{components:n})):a.a.createElement(O,b({ref:t},l))}));function O(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var b={};for(var c in t)hasOwnProperty.call(t,c)&&(b[c]=t[c]);b.originalType=e,b.mdxType="string"==typeof e?e:r,i[1]=b;for(var l=2;l=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=a.a.createContext({}),u=function(e){var t=a.a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):b(b({},t),e)),n},p=function(e){var t=u(e.components);return a.a.createElement(l.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.a.createElement(a.a.Fragment,{},t)}},m=a.a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,i=e.parentName,l=c(e,["components","mdxType","originalType","parentName"]),p=u(n),m=r,O=p["".concat(i,".").concat(m)]||p[m]||s[m]||o;return n?a.a.createElement(O,b(b({ref:t},l),{},{components:n})):a.a.createElement(O,b({ref:t},l))}));function O(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var b={};for(var c in t)hasOwnProperty.call(t,c)&&(b[c]=t[c]);b.originalType=e,b.mdxType="string"==typeof e?e:r,i[1]=b;for(var l=2;l 29.1 常见问题 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/appstartup/index.html b/handbook/build/docs/appstartup/index.html index cf1bbdc4872..ef1c89f478c 100644 --- a/handbook/build/docs/appstartup/index.html +++ b/handbook/build/docs/appstartup/index.html @@ -6,7 +6,7 @@ 3. 应用启动 | Furion - + @@ -52,7 +52,7 @@
namespace Furion.Web.Entry
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
}
}
}
Startup.cs 代码迁移

只需要将 ConfigureServicesConfigure 方法代码迁移到 Furion.Web.Core.Startup.cs 中即可,而 Startup.cs 中两个方法留空即可。

非常简单吧。我们后续创建任何 MVCRazorPagesBlazor 项目只需要添加 Furion.Web.Core 引用和调用 Inject() 即可。

3.6 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/auth-control/index.html b/handbook/build/docs/auth-control/index.html index f990006558c..3894940cf37 100644 --- a/handbook/build/docs/auth-control/index.html +++ b/handbook/build/docs/auth-control/index.html @@ -6,7 +6,7 @@ 14. 安全鉴权 | Furion - + @@ -31,7 +31,7 @@
/// <summary>
/// 检查权限
/// </summary>
/// <param name="httpContext"></param>
/// <returns></returns>
private static bool CheckAuthorzie(DefaultHttpContext httpContext)
{
// 获取权限特性
var securityDefineAttribute = httpContext.GetMetadata<SecurityDefineAttribute>();
if (securityDefineAttribute == null) return true;
return App.GetService<IAuthorizationManager>().CheckSecurity(securityDefineAttribute.ResourceId);
}
}
}

之后注册 JwtHandler 即可:

services.AddJwt<JwtHandler>();

14.4 授权特性及全局授权

默认情况下,所有的路由都是允许匿名访问的,所以如果需要对某个 ActionController 设定授权访问,只需要在 ActionController[AppAuthorize][Authorize] 特性即可。

如果需要对特定的 ActionController 允许匿名访问,则贴 [AllowAnonymous] 即可。

14.4.1 全局授权

services.AddJwt<JwtHandler>(enableGlobalAuthorize:true);

14.4.2 匿名访问

如果需要对特定的 ActionController 允许匿名访问,则贴 [AllowAnonymous] 即可。

14.5 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 鉴权授权 知识可查阅 ASP.NET Core - 安全和标识 章节。

- + diff --git a/handbook/build/docs/author/index.html b/handbook/build/docs/author/index.html index 1f4b0bb6112..aafcec5a694 100644 --- a/handbook/build/docs/author/index.html +++ b/handbook/build/docs/author/index.html @@ -6,7 +6,7 @@ 1.2 关于作者 | Furion - + @@ -25,7 +25,7 @@

1.2 关于作者

互联网账号

  • 百小僧
  • Monk/MonkSoul

技术能力

自 2008 年 接触 IT 这个行业也有十余年了,在 后端(.NET/.NET Core/Java/PHP)、移动端(Xamarin/小程序/Java/Objective-C)、桌面端(WinForm/WPF/Electron)、前端(React/Vue/Angular/Node)等主流领域略知一二。

同时在技术培训领域也多有涉足。dotNET China MIP,同时多次获得开源中国 Gitee 授予 GVP 证书。

职业情况

自 2012 年 06 月 29 日创办一家高科技软件公司到至今,主要销售自主研发的家具 ERP 产品和港澳台及国外服务外包业务。

吃不起饭的时候也会接国内外包项目。

兴趣爱好

是个吃货,迷恋纹身文化,喜欢看抖音,看动漫,看美剧,看博客园、看开源中国、看 Github/Gitee。

对新技术颇感兴趣,喜欢开源事业,喜欢分享技术。

个人主页

https://gitee.com/monksoul

https://github.com/monksoul

- + diff --git a/handbook/build/docs/cache/index.html b/handbook/build/docs/cache/index.html index 1cc99e83201..36022f65270 100644 --- a/handbook/build/docs/cache/index.html +++ b/handbook/build/docs/cache/index.html @@ -6,7 +6,7 @@ 13. 分布式缓存 | Furion - + @@ -45,7 +45,7 @@
await _cache.SetAsync("cachedTimeUTC", encodedCurrentTimeUTC, options);
return RedirectToPage();
}
}

13.6 分布式缓存建议

确定 IDistributedCache 最适合你的应用的实现时,请考虑以下事项:

  • 现有基础结构
  • 性能要求
  • 成本
  • 团队经验

缓存解决方案通常依赖于内存中的存储以快速检索缓存的数据,但是,内存是有限的资源,并且很昂贵。 仅将常用数据存储在缓存中。

通常,Redis 缓存提供比 SQL Server 缓存更高的吞吐量和更低的延迟。 但是,通常需要进行基准测试来确定缓存策略的性能特征。

SQL Server 用作分布式缓存后备存储时,对缓存使用同一数据库,并且应用的普通数据存储和检索会对这两种情况的性能产生负面影响。 建议使用分布式缓存后备存储的专用 SQL Server 实例。

13.7 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 分布式缓存 知识可查阅 ASP.NET Core - 分布式缓存 章节。

- + diff --git a/handbook/build/docs/configuration/index.html b/handbook/build/docs/configuration/index.html index c3f3b01054a..dfe24bb5832 100644 --- a/handbook/build/docs/configuration/index.html +++ b/handbook/build/docs/configuration/index.html @@ -6,7 +6,7 @@ 4.1 配置 | Furion - + @@ -27,7 +27,7 @@
namespace Furion.Web.Entry.Controllers
{
[Route("api/[controller]")]
public class DefaultController : ControllerBase
{
[HttpGet]
public string Get()
{
return $@"名称:{App.Configuration["AppInfo:Name"]},
版本:{App.Configuration["AppInfo:Version"]},
公司:{App.Configuration["AppInfo:Company"]}";
}
}
}
依赖注入的方式

通过依赖注入注入实例有几种方式:

  • 构造函数注入方式
private readonly IConfiguration _configuration;
public DefaultController(IConfiguration configuration)
{
_configuration = configuration;
}
  • 参数注入方式 [FromServices]
public string Get([FromServices] IConfiguration configuration)
{
}
  • 属性注入方式
public IConfiguration Configuration { get; set; }

想了解更多关于《ASP.NET Core - 依赖注入》 知识

4.1.2.3 如何选择读取方式

  • 在可依赖注入类中,依赖注入 IConfiguration 读取
  • 在静态类/非依赖注入类中,选择 App.Configuration[jsonKey] 读取

4.1.3 路径符 查找节点

ASP.NET Core 中,配置采用 : 分隔符来读取分层配置数据。如上述例子中的 AppInfo:Name。如有更多层级数据则只需要通过 : 进入下一层节点即可。

假设我们有以下配置信息:

{
"AppInfo": {
"Name": "Furion",
"Version": "1.0.0",
"Company": {
"Name": "Baiqian",
"Address": {
"City": "中国",
"Province": "广东省",
"Detail": "中山市东区紫马公园西门"
}
}
}
}
var companyName = App.Configuration["AppInfo:Name"]; // => Furion

4.1.4 自定义配置文件

大多情况下,我们的配置只需要在 appsettings.json 中配置即可,但一些特殊情况下,我们希望某些组件或功能拥有独立的配置,这个时候就需要用到自定义配置,Furion 目前支持 .json.xml 两种方式配置,如:

Furion.Web.Entry/emailsetting.json
{
"outlook": {
"smtp": {
"server": "smtp.office365.com",
"port": "587",
"ssl": "STARTTLS"
},
"pop": {
"server": "outlook.office365.com",
"port": "995",
"ssl": "TLS"
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<MyKey>MyXMLFile Value</MyKey>
<Position>
<Title>Title from MyXMLFile</Title>
<Name>Name from MyXMLFile</Name>
</Position>
<Logging>
<LogLevel>
<Default>Information</Default>
<Microsoft>Warning</Microsoft>
</LogLevel>
</Logging>
</configuration>
xml 配置事项

如果采用 xml 配置,那么文件名必须以 .config.xml 结尾(不区分大小写)。

特别说明

Furion 框架会在启动时自动扫描每一个项目层根目录下的 *.json*.xml 文件加入配置中,所以无需手工配置。

新增 *.json*.xml 文件的属性复制到输出目录设置为始终复制,否则不会载入。另外配置文件不能出现重名,也就是保证整个项目中配置文件名字唯一。

同时 Furion 提供了非常灵活的方式支持自定义配置文件读取,如:

4.1.4.1 读取 emailsetting.json 配置

读取自定义配置文件和读取 appsettings.json 一致,系统会自动从多个配置文件中读取输入,如:

var smtpServer = App.Configuration["outlook:smtp:server"]; // => smtp.office365.com

4.1.4.2 排除特定配置文件

有些时候,我们不需要 .json.xml 自定载入配置中,我们只需要在启动层 appsettings.json 中添加 IgnoreConfigurationFiles 节点即可:

{
"IgnoreConfigurationFiles": ["runtime.json"]
}

4.1.5 不同环境读取

在实际应用开发中,我们可能会根据不同的环境加载不同的配置文件,如 数据库连接字符串

这时我们只需要遵循特定命名规范 {name}.{Environment}.json 即可。如:

  • appsettings.Development.json
  • appsettings.Staging.json
  • appsettings.Production.json
  • emailsetting.Development.json
  • emailsetting.Staging.json
  • emailsetting.Production.json

这时,ASP.NET Core 会在应用启动时自动加载不同环境的配置文件。

4.1.6 配置更改通知(热更新

.NET Core 应用程序中,配置支持更改通知,也就是热更新操作。一旦监听到 appsetting.json 或自定义配置文件发生变动,就会触发 OnChange 方法。代码如下:

var appInfoConfiguration = App.Configuration["AppInfo"];
ChangeToken.OnChange(() => appInfoConfiguration.GetReloadToken(), () =>
{
var name = appInfoConfiguration["Name"]; // 实时的最新值
var version = appInfoConfiguration["Version"]; // 实时的最新值
});

4.1.7 配置的优缺点

  • 优点

    • 能够在系统运行时快速读取
    • 无需额外配置
  • 缺点

    • 存在重复读取
    • 通过硬编码字符串读取,容易出错
    • 不能设置默认值
    • 不能在运行环境中动态配置
    • 不能验证配置有效性
    • 不支持更改通知

4.1.8 配置使用场景

如果只需要一次性读取配置信息,则使用配置,否则应该使用 《4.2 选项》代替。

4.1.9 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 配置 知识可查阅 ASP.NET Core - 配置 章节。

- + diff --git a/handbook/build/docs/contribute/index.html b/handbook/build/docs/contribute/index.html index 92a65275cdf..9830b534538 100644 --- a/handbook/build/docs/contribute/index.html +++ b/handbook/build/docs/contribute/index.html @@ -6,7 +6,7 @@ 28. 贡献指南 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/cors/index.html b/handbook/build/docs/cors/index.html index 537efeb9f58..9b7cc71158f 100644 --- a/handbook/build/docs/cors/index.html +++ b/handbook/build/docs/cors/index.html @@ -6,7 +6,7 @@ 15. CORS 跨域 | Furion - + @@ -30,7 +30,7 @@
app.UseCorsAccessor();
// ...
}
}
}
特别注意

services.AddCorsAccessor(); 需在 services.AddControllers() 之前注册。

app.UseCorsAccessor(); 需在 app.UseRouting();app.UseAuthentication(); 之间注册。

15.4.2 配置允许跨域域名

小提醒

默认情况下,Furion 允许所有域名来源访问,也就是无需配置任何来源域名,另外前端也需要设置请求参数:withCredentials:false

如果需要指定特定域名,则添加以下配置即可:

{
"CorsAccessorSettings": {
"PolicyName": "自定义跨域策略名",
"WithOrigins": ["http://localhost:4200", "https://furion.pro"]
}
}

15.5 CorsAccessorSettings 配置

  • CorsAccessorSettings
    • PolicyName:跨域策略名,字符串类型,必填,默认 FurCorsAccessor
    • WithOrigins:允许跨域的域名列表,字符串数组类型,默认 [ "http://localhost:4200" ]
    • WithHeaders:请求表头,没有配置则允许所有表头,字符串数组类型
    • WithExposedHeaders:响应标头,字符串数组类型
    • WithMethods:设置跨域允许请求谓词,没有配置则允许所有,字符串数组类型
    • AllowCredentials:跨域请求中的凭据,bool 类型
    • SetPreflightMaxAge:设置预检过期时间,int 类型

15.6 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 跨域请求 知识可查阅 ASP.NET Core - 启用跨域请求 章节。

- + diff --git a/handbook/build/docs/data-validation/index.html b/handbook/build/docs/data-validation/index.html index 69137a53a0c..03e85307337 100644 --- a/handbook/build/docs/data-validation/index.html +++ b/handbook/build/docs/data-validation/index.html @@ -6,7 +6,7 @@ 8. 数据校验 | Furion - + @@ -77,7 +77,7 @@
namespace Furion.Application
{
public class FurAppService : IDynamicApiController
{
[TypeFilter(typeof(DataValidationFilter))]
public TestDto Post(TestDto testDto)
{
return testDto;
}
}
}

8.9.4 [ApiController] 控制器范围验证

[ApiController]Mvc 提供的控制器范围(含所有动作方法)的验证。

using Microsoft.AspNetCore.Mvc;
namespace Furion.Web.Entry.Controllers
{
[ApiController]
public class MvcController : Controller
{
public IActionResult Index()
{
return View();
}
}
}

8.10 MiniProfiler 查看

如下图所示:

8.11 多语言支持

文档整理中...

8.12 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-Interceptor/index.html b/handbook/build/docs/dbcontext-Interceptor/index.html index 22846d99d8b..6193378a316 100644 --- a/handbook/build/docs/dbcontext-Interceptor/index.html +++ b/handbook/build/docs/dbcontext-Interceptor/index.html @@ -6,7 +6,7 @@ 9.24 数据库操作拦截器 | Furion - + @@ -58,7 +58,7 @@
// 提交数据库失败
public override void SaveChangesFailed(DbContextErrorEventData eventData)
{
base.SaveChangesFailed(eventData);
}
// 提交数据库失败(异步)
public override Task SaveChangesFailedAsync(DbContextErrorEventData eventData, CancellationToken cancellationToken = default)
{
return base.SaveChangesFailedAsync(eventData, cancellationToken);
}
}
}

9.24.2.4 SavedChangesEvent 拦截

Furion 框架中为所有 AppDbContext 子类都提供了三个可重写的方法,这三个方法分别由三个事件触发:

  • 提交更改之前 SavingChanges 事件:触发 void SavingChangesEvent(object sender, SavingChangesEventArgs e) 方法
  • 提交更改之后 SavedChanges 事件:触发 void SavedChangesEvent(object sender, SavedChangesEventArgs e) 方法
  • 提交更改失败 SaveChangesFailed 事件:触发 void SaveChangesFailedEvent(object sender, SaveChangesFailedEventArgs e) 方法

通过这三个事件我们可以在数据库做增、删、改时候做拦截,比如设置创建时间、更新时间或其他默认操作

如自动添加租户Id:

protected override void SavingChangesEvent(object sender, SavingChangesEventArgs e)
{
// 获取当前事件对应上下文
var dbContext = sender as FurDbContext;
// 获取所有新增和更新的实体
var entities = dbContext.ChangeTracker.Entries()
.Where(u => u.State == EntityState.Added || u.State == EntityState.Modified);
foreach (var entity in entities)
{
switch (entity.State)
{
// 自动设置租户Id
case EntityState.Added:
entity.Property(nameof(Entity.TenantId)).CurrentValue = GetTenantId();
break;
// 排除租户Id
case EntityState.Modified:
entity.Property(nameof(Entity.TenantId)).IsModified = false;
break;
}
}
}

9.24.3 注册自定义过滤器

定义好过滤器之后,我们需要在数据库上下文中注册:

services.AddSqlitePool<FurDbContext>(interceptors: new IInterceptor[] {
new SqlConnectionProfilerInterceptor(),
new DbContextSaveChangesInterceptor(),
new SqlCommandProfilerInterceptor()
});

9.24.4 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-add-or-update/index.html b/handbook/build/docs/dbcontext-add-or-update/index.html index 0fa0ebfe827..12ebeb0fd70 100644 --- a/handbook/build/docs/dbcontext-add-or-update/index.html +++ b/handbook/build/docs/dbcontext-add-or-update/index.html @@ -6,7 +6,7 @@ 9.7 新增或更新操作 | Furion - + @@ -103,7 +103,7 @@
// 示例七
await user.InsertOrUpdateExcludeNowAsync(new[] { u=>u.Name, u=>u.Age});
// 示例八
await user.InsertOrUpdateExcludeNowAsync(new[] {"Age", "Name"});

9.5.7 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-add/index.html b/handbook/build/docs/dbcontext-add/index.html index 5a8e296dc69..17d30deba50 100644 --- a/handbook/build/docs/dbcontext-add/index.html +++ b/handbook/build/docs/dbcontext-add/index.html @@ -6,7 +6,7 @@ 9.5 新增操作 | Furion - + @@ -54,7 +54,7 @@
// 示例二
await repository.InsertNowAsync(new List<User> { user, user2 });
// 示例三
await repository.InsertNowAsync(new[] {user, user2 });
小知识

所有带 Now 结尾的表示立即提交到数据库,也就是立即调用 SaveChangesSaveChangesAsync

9.5.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-audit/index.html b/handbook/build/docs/dbcontext-audit/index.html index 7bee75b3976..7ad69f33bf8 100644 --- a/handbook/build/docs/dbcontext-audit/index.html +++ b/handbook/build/docs/dbcontext-audit/index.html @@ -6,7 +6,7 @@ 9.22 审计日志 | Furion - + @@ -38,7 +38,7 @@
object oldValue = null;
// 如果是新增数据,则 databaseValues 为空,所以需要判断一下
if (databaseValues != null)
{
oldValue = databaseValues[propName];
}
// 插入审计日志表
dbContext.Audits.Add(new Audit
{
Table = entityType.Name, // 表名
Column = propName, // 更新的列
NewValue = newValue, // 新值
OldValue = oldValue, // 旧值
CreatedTime = DateTime.Now, // 操作时间
UserId = userId, // 操作人
Operate = entity.State.ToString(); // 操作方式:新增、更新、删除
});
}
}
}
}
}
小知识

如果对性能有所要求,那么建议审计日志通过 日志组件 写入数据库,如,通过 Nlog、Log4Net 这些等:

// 插入审计日志表
dbContext.Audits.Add(new Audit
{
Table = entityType.Name, // 表名
Column = propName, // 更新的列
newValue = newValue, // 新值
OldValue = oldValue, // 旧值
CreatedTime = DateTime.Now, // 操作时间
UserId = userId, // 操作人
Operate = entity.State.ToString(); // 操作方式:新增、更新、删除
});

替换为:

logger.Information(JsonConvert.SerializeObject(new Audit
{
Table = entityType.Name, // 表名
Column = propName, // 更新的列
newValue = newValue, // 新值
OldValue = oldValue, // 旧值
CreatedTime = DateTime.Now, // 操作时间
UserId = userId, // 操作人
Operate = entity.State.ToString(); // 操作方式:新增、更新、删除
}));

通过上面的例子,我们就可以对数据库所有的新增、更新、删除进行监控了。

9.22.4 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-batch/index.html b/handbook/build/docs/dbcontext-batch/index.html index 649f1936e78..3ca3e7d1dfc 100644 --- a/handbook/build/docs/dbcontext-batch/index.html +++ b/handbook/build/docs/dbcontext-batch/index.html @@ -6,7 +6,7 @@ 9.9 批量操作 | Furion - + @@ -33,7 +33,7 @@
// 根据条件批量更新
repository.Where(a => a.ItemId <= 500).BatchUpdate(a => new Item { Quantity = a.Quantity + 100 });
repository.Where(a => a.ItemId <= 500).BatchUpdate(new Item { Description = "Updated" });
await repository.Where(a => a.ItemId <= 500).BatchUpdateAsync(new Item { Description = "Updated" });
// 批量更新指定列
var updateColumns = new List<string> { nameof(Item.Quantity) };
var q = repository.Where(a => a.ItemId <= 500);
int affected = q.BatchUpdate(new Item { Description = "Updated" }, updateColumns);

9.9.3 批量操作性能

Operations\Rows100,000 EF100,000 EFBulk1,000,000 EFBulk
Insert38.98 s2.10 s17.99 s
Update109.25 s3.96 s31.45 s
Delete7.26 s2.04 s12.18 s
---------------------------------------------------------------
Together70.70 s5.88 s56.84 s

9.9.4 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 EFCore.BulkExtensions 知识可查阅 EFCore.BulkExtensions 开源仓库

- + diff --git a/handbook/build/docs/dbcontext-code-first/index.html b/handbook/build/docs/dbcontext-code-first/index.html index a97886766b0..198bf975158 100644 --- a/handbook/build/docs/dbcontext-code-first/index.html +++ b/handbook/build/docs/dbcontext-code-first/index.html @@ -6,7 +6,7 @@ 9.20 模型生成数据库 | Furion - + @@ -29,7 +29,7 @@
/// <summary>
/// 年龄
/// </summary>
public int Age { get; set; }
/// <summary>
/// 住址
/// </summary>
public string Address { get; set; }
}
}
实体约定

所有数据库实体必须直接或间接继承 IEntity 接口。

9.20.2.2 打开 程序包管理控制台

9.20.2.3 切换默认项目

程序包管理控制台 默认项目设置为 Furion.Database.Migrations

9.20.2.4 创建模型版本

Add-Migration v1.0.0
特别说明

v1.0.0 是此处数据库更改的版本号,可以写任何字符串,但推荐写版本号,每次 +1

最终命令如下:

PM> Add-Migration v1.0.0
Build started...
Build succeeded.
Microsoft.EntityFrameworkCore.Model.Validation[10400]
Sensitive data logging is enabled. Log entries and exception messages may include sensitive application data, this mode should only be enabled during development.
Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 5.0.0-rc.1.20451.13 initialized 'FurDbContext' using provider 'Microsoft.EntityFrameworkCore.Sqlite' with options: SensitiveDataLoggingEnabled DetailedErrorsEnabled MaxPoolSize=100 MigrationsAssembly=Furion.Database.Migrations
To undo this action, use Remove-Migration.
PM>

生成成功后,Furion.Database.Migrations 项目下会新增 Migrations 文件夹(如果没有),同时本次的架构生成文件,如:

9.20.2.5 更新到数据库

Update-Database

执行该命令后,数据库就会自动根据模型生成对于的表。

小知识

如果 Update-Database 后面带字符串参数,则会自动还原数据库到指定版本,如:

Update-Database v0.0.3

将数据库还原到 v0.0.3 版本

9.20.3 更新模型

如果模型改变了,重复上面操作即可,如:

Add-Migration v1.0.1
Update-Database

9.20.4 导出 Sql

有些时候,我们没有直接更新数据库的权限,或者怕出问题,我们都会先生成 Sql 看看,这时候只需要通过 Script-Migration 导出即可,如:

Script-Migration

9.20.5 VS Code 方式

9.20.5.1 安装 dotnet ef

dotnet tool install --global dotnet-ef --version 5.0.0-rc.2.20475.6

9.20.5.2 cd 目录

通过 VS Code 打开 .sln 所在的目录,如:framework

之后进入 Furion.Database.Migrations 目录

cd Furion.Database.Migrations

9.20.5.3 执行命令

dotnet ef migrations add v1.0.0 -s "../Furion.Web.Entry"
dotnet ef database update -s "../Furion.Web.Entry"

9.20.6 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 正向工厂 知识可查阅 EF Core - 管理数据库架构 章节。

- + diff --git a/handbook/build/docs/dbcontext-db-first/index.html b/handbook/build/docs/dbcontext-db-first/index.html index 472e98ab5a9..4e10a452232 100644 --- a/handbook/build/docs/dbcontext-db-first/index.html +++ b/handbook/build/docs/dbcontext-db-first/index.html @@ -6,7 +6,7 @@ 9.19 数据库生成模型 | Furion - + @@ -62,7 +62,7 @@
}
}
Furion Tools v1.0.0 全部实体生成成功!
PM>

9.13.4 命令参数配置

Furion Tools Cli 支持多个参数配置,使用方法只需要在命令后面添加即可,如:

&"../tools/cli.ps1" -Context 数据库上下文名 -ConnectionName 连接字符串Key

支持参数如下:

  • -Tables:配置要生成的数据库表,数组类型,如果为空,则生成数据库所有表和视图。如:-Tables Person,PersonDetails
  • -Context:配置数据库上下文,默认 FurDbContext,如果有多个数据库上下文,则此参数必须配置
  • -ConnectionName:配置数据库连接字符串,对于 appsetting.json 中的 Key
  • -OutputDir:生成实体代码输出目录,默认为:./Furion.Core/Entities/
  • -DbProvider:数据库提供器,默认是 Microsoft.EntityFrameworkCore.SqlServer,其他数据库请指定对应程序集
    • SqlServerMicrosoft.EntityFrameworkCore.SqlServer
    • SqliteMicrosoft.EntityFrameworkCore.Sqlite
    • CosmosMicrosoft.EntityFrameworkCore.Cosmos
    • InMemoryDatabaseMicrosoft.EntityFrameworkCore.InMemory
    • MySqlPomelo.EntityFrameworkCore.MySql
    • PostgreSQLNpgsql.EntityFrameworkCore.PostgreSQL
    • OracleCitms.EntityFrameworkCore.Oracle
    • DmMicrosoft.EntityFrameworkCore.Dm
  • -EntryProject:Web 启用项目层名,默认 Furion.Web.Entry
  • -CoreProject:实体项目层名,默认 Furion.Core
  • -DbContextLocators:多数据库上下文定位器,默认 MasterDbContextLocator,支持多个,如:MasterDbContextLocator,MySqlDbContextLocator
  • -Product:解决方案默认前缀,如 Furion
  • -UseDatabaseNames:是否保持生成和数据库、表一致的名称

9.13.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-delete/index.html b/handbook/build/docs/dbcontext-delete/index.html index 3f4d44d7851..d16a51d5608 100644 --- a/handbook/build/docs/dbcontext-delete/index.html +++ b/handbook/build/docs/dbcontext-delete/index.html @@ -6,7 +6,7 @@ 9.8 删除操作 | Furion - + @@ -70,7 +70,7 @@
// 示例五
await entity.FakeDeleteAsync();
// 示例六
await repository.UpdateIncludeAsync(user, u => u.IsDeleted);

9.8.9 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-entitytrigger/index.html b/handbook/build/docs/dbcontext-entitytrigger/index.html index a35dde7dc91..e4c6e18d174 100644 --- a/handbook/build/docs/dbcontext-entitytrigger/index.html +++ b/handbook/build/docs/dbcontext-entitytrigger/index.html @@ -6,7 +6,7 @@ 9.25. 实体数据监听器 | Furion - + @@ -32,7 +32,7 @@
/// <summary>
/// 监听数据改变之后(仅支持EFCore操作)
/// </summary>
/// <param name="entity"></param>
/// <param name="dbContext"></param>
/// <param name="dbContextLocator"></param>
/// <param name="state"></param>
void OnChanged(TEntity entity, DbContext dbContext, Type dbContextLocator, EntityState state);
/// <summary>
/// 监听数据改变失败(仅支持EFCore操作)
/// </summary>
/// <param name="entity"></param>
/// <param name="dbContext"></param>
/// <param name="dbContextLocator"></param>
/// <param name="state"></param>
void OnChangeFailed(TEntity entity, DbContext dbContext, Type dbContextLocator, EntityState state) { }
}

9.29.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-filter/index.html b/handbook/build/docs/dbcontext-filter/index.html index 15adc33bfbe..0204b8957c9 100644 --- a/handbook/build/docs/dbcontext-filter/index.html +++ b/handbook/build/docs/dbcontext-filter/index.html @@ -6,7 +6,7 @@ 9.23 实体/全局查询筛选器 | Furion - + @@ -37,7 +37,7 @@
// 创建表达式元素
var parameter = Expression.Parameter(metadata.ClrType, "u");
var properyName = Expression.Constant(nameof(Entity.IsDeleted));
var propertyValue = Expression.Constant(false);
// 构建表达式 u => EF.Property<bool>(u, "IsDeleted") == false
var expressionBody = Expression.Equal(Expression.Call(typeof(EF), nameof(EF.Property), new[] { typeof(bool) }, parameter, properyName), propertyValue);
var expression = Expression.Lambda(expressionBody, parameter);
return expression;
}
}
}
小建议

如果对动态构建 LambdaExpression 不熟悉的朋友,可以使用 System.Linq.Dynamic.Corehttps://github.com/zzzprojects/System.Linq.Dynamic.Core

9.23.3 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-function/index.html b/handbook/build/docs/dbcontext-function/index.html index 901a2b0fbaa..43530e93cd6 100644 --- a/handbook/build/docs/dbcontext-function/index.html +++ b/handbook/build/docs/dbcontext-function/index.html @@ -6,7 +6,7 @@ 9.14 函数操作 | Furion - + @@ -49,7 +49,7 @@
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity(typeof(F_Person)).HasNoKey();
modelBuilder.HasDbFunction(() => GetPersons(default));
}
}
}

9.14.5.4 在 Linq 中使用

IQueryable<F_Person> query = _repository.DynamicDbContext.GetPersons(1);
var result = query.Where(u => u.Name.Equals("Furion")).ToList();

最终生成 Sql

SELECT [g].Id, [g].Name, [g].Age, [g].Address
FROM dbo.GetPersons(1) AS [g]
WHERE [g].Name == N'Furion';

9.14.6 在 EF Core 内置函数

EF Core 为我们提供了很多常用的内置函数,可以在 Lambda 条件中使用,主要是通过 EF.Functions 调用,如:

_repository.Where(u => EF.Functions.DateDiffHour(u.CreatedDt, DateTime.Now) > 8).FirstOrDefault();

这个语句使用了 EF.Functions.DateDiffHour 最终生成的 Sql 如下:

SELECT TOP(1) [a].*
FROM [dbo].[TEST] AS [a]
WHERE DATEDIFF(HOUR, [a].[CREATED_DT], GETDATE()) > 8

EF Core 内置函数就不一一列出了,可以通过 EF.Functions 查看更多,如果不能满足自己的需求,那么可以自定义 Linq 标量函数

9.14.7 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-hight-query/index.html b/handbook/build/docs/dbcontext-hight-query/index.html index dbc51dd6f86..5cdfb4f7e3c 100644 --- a/handbook/build/docs/dbcontext-hight-query/index.html +++ b/handbook/build/docs/dbcontext-hight-query/index.html @@ -6,7 +6,7 @@ 9.11 高级查询操作 | Furion - + @@ -71,7 +71,7 @@
namespace Furion.Core
{
public class Person : Entity, IEntityTypeBuilder<Person>
{
public string Name { get; set; }
/// <summary>
/// 配置实体关系
/// </summary>
/// <param name="entityBuilder"></param>
/// <param name="dbContext"></param>
/// <param name="dbContextLocator"></param>
public void Configure(EntityTypeBuilder<City> entityBuilder, DbContext dbContext, Type dbContextLocator)
{
entityBuilder.ToSqlQuery(
@"select * from dbo.person.2020-09-19
union all
select * from dbo.person.2020-09-20");
}
}
}
var posts = repository.Where(u => u.Id > 10).ToList();

9.11.14 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-locator/index.html b/handbook/build/docs/dbcontext-locator/index.html index e712fbdba26..b955d9b5e03 100644 --- a/handbook/build/docs/dbcontext-locator/index.html +++ b/handbook/build/docs/dbcontext-locator/index.html @@ -6,7 +6,7 @@ 9.2 数据库上下文定位器 | Furion - + @@ -27,7 +27,7 @@
namespace Furion.Core
{
public sealed class FurDbContextLocator : IDbContextLocator
{
}
}

9.2.4 默认数据库上下文定位器

Furion 框架中已经提供了 MasterDbContextLocator 默认数据库上下文定位器,所以默认数据库上下文只需继承 AppDbContext<TDbContext> 即可。

AppDbContext<TDbContext> 定义代码如下:

using Furion.DependencyInjection;
using Microsoft.EntityFrameworkCore;
namespace Furion.DatabaseAccessor
{
/// <summary>
/// 默认应用数据库上下文
/// </summary>
/// <typeparam name="TDbContext">数据库上下文</typeparam>
[NonBeScan]
public abstract class AppDbContext<TDbContext> : AppDbContext<TDbContext, MasterDbContextLocator>
where TDbContext : DbContext
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="options"></param>
public AppDbContext(DbContextOptions<TDbContext> options) : base(options)
{
}
}
}

9.2.5 数据库上下文定位器支持对象

目前数据库上下文支持以下多个对象:

  • AppDbContext<TEntity, TDbContextLocator>:数据上下文
  • IRepository<TEntity, TDbContextLocator:实体仓储
  • ISqlRepository<TDbContextLocator>: Sql 操作仓储
  • Func<Type, DbContext>:依赖注入获取数据库上下文
  • Entity<Tkey, TDbContextLocator> :实体配置
  • EntityBase<Tkey, TDbContextLocator1, ... TDbContextLocator8>:实体配置
  • EntityNotKey<TDbContextLocator1, ... TDbContextLocator8>:无键实体配置
  • IEntitySeedData<TEntity, TDbContextLocator1, ... TDbContextLocator8>:种子数据配置
  • IEntityTypeBuilder<TEntity, TDbContextLocator1, ... TDbContextLocator8>:实体类型构建器
  • IModelBuilderFilter<TDbContextLocator1, ... TDbContextLocator8>:模型构建筛选器
  • [QueryableFunction(DbContextLocators=Type[])]:查询函数

9.2.6 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-multi-database/index.html b/handbook/build/docs/dbcontext-multi-database/index.html index 5f15c8a4092..06d796694ef 100644 --- a/handbook/build/docs/dbcontext-multi-database/index.html +++ b/handbook/build/docs/dbcontext-multi-database/index.html @@ -6,7 +6,7 @@ 9.18 多数据库操作 | Furion - + @@ -42,7 +42,7 @@
// 支持一个数据库
public class Person: IEntity<MySqlDbContextLocator>
{
// ....
}
// 支持多个数据库
public class Person: IEntity<MySqlDbContextLocator, SqliteDbContextLocator>
{
// ....
}
小知识

所有的 实体依赖接口或抽象类 都支持泛型方式 指定 数据库上下文定位器,最多支持 8 个。

9.18.3.5 Linq 函数方式

public static class QueryFunctions
{
[QueryableFunction("FN_GetId", "dbo", typeof(MySqlDbContextLocator), typeof(SqliteDbContextLocator))]
public static int GetId(int id) => throw new NotSupportedException();
}

9.18.4 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-proc/index.html b/handbook/build/docs/dbcontext-proc/index.html index cefffb09ad5..c2ddedf929b 100644 --- a/handbook/build/docs/dbcontext-proc/index.html +++ b/handbook/build/docs/dbcontext-proc/index.html @@ -6,7 +6,7 @@ 9.13 存储过程操作 | Furion - + @@ -120,7 +120,7 @@
// 获取 RETURN 返回值
var reval = result.ReturnValue;
// 获取返回结果集
var (list1,list2) = result.Result;
关于异步

Furion 框架每一个数据库操作都支持异步方式,由于篇幅有限,就不列举异步方式了。

9.13.3 关于 [DbParameter]

[DbParameter] 特性是用来标注 Sql函数存储过程 参数的,可配置属性:

  • Direction:设置参数方向,ParameterDirection 枚举类型,默认 ParameterDirection.Input
  • DbType:设置参数类型,DbType 枚举类型,无默认
  • Size:设置参数长度的,int 类型

其中 Direction 属性是默认构造函数参数。

9.13.4 关于 ProcedureOutputResult

ProcedureOutputResultProcedureOutputResult<TResult> 是复杂存储过程执行返回模型类,有以下属性:

  • OutputValues:多个输出值,ProcedureOutputValue 类型
  • ReturnValue:返回值,object 类型
  • Result:结果集,非泛型版本是 DataSet类型,否则是 泛型类型

9.13.5 存储过程参数

所有 sql 参数都支持四种方式:

  • DbParameter[]:数组类型
  • new {}:匿名类型
  • new Class{}:强类型类型(支持复杂存储过程参数)
  • Dictionary<string,object> 类型

9.13.6 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-query/index.html b/handbook/build/docs/dbcontext-query/index.html index b3bc6dad80e..dcb91dfc193 100644 --- a/handbook/build/docs/dbcontext-query/index.html +++ b/handbook/build/docs/dbcontext-query/index.html @@ -6,7 +6,7 @@ 9.10 查询操作 | Furion - + @@ -137,7 +137,7 @@
// 示例二
_testRepository.Where(u => u.Name.EndWith("Furion"));
// 示例三
_testRepository.Where(u => u.Name.Contains("Furion"));

9.10.6.9 Case When

数据库中的 Case When 实际上对应的是我们程序中的 三元表达式 ,也就是使用 三元表达式 即可自动生成 Case When 语句。

9.10.7 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-read-write/index.html b/handbook/build/docs/dbcontext-read-write/index.html index dbf775e672d..e677ad38240 100644 --- a/handbook/build/docs/dbcontext-read-write/index.html +++ b/handbook/build/docs/dbcontext-read-write/index.html @@ -6,7 +6,7 @@ 9.27 读写分离/主从复制 | Furion - + @@ -37,7 +37,7 @@
/// <summary>
/// 查询走从库
/// </summary>
/// <returns></returns>
public List<Person> Get()
{
return _msRepository.Slave1<Person>().AsEnumerable();
}
}
}

9.27.3 主从复制

主从复制:是一种数据备份的方案。

简单来说,是使用两个或两个以上相同的数据库,将一个数据库当做主数据库,而另一个数据库当做从数据库。在主数据库中进行相应操作时,从数据库记录下所有主数据库的操作,使其二者一模一样。

9.27.4 主从复制几种方式

9.27.4.1 同步复制

所谓的同步复制,意思是 Master 的变化,必须等待 Slave-1,Slave-2,...,Slave-n 完成后才能返回。 这样,显然不可取,比如,在 Web 前端页面上,用户增加了条记录,需要等待很长时间。

9.27.4.2 异步复制

如同 AJAX 请求一样。Master 只需要完成自己的数据库操作即可。至于 Slaves 是否收到二进制日志,是否完成操作,不用关心。(推荐方式)

9.27.4.3 半同步复制

Master 只保证 Slaves 中的一个操作成功,就返回,其他 Slave 不管。

下面将使用 SqlServer 简单配置主从复制功能。

9.27.5 SqlServer 主库配置

9.27.5.1 添加 本地发布

9.27.5.2 选择 分发服务器

9.27.5.3 启用 代理

9.27.5.4 发布数据库

9.27.5.5 快照发布

具体选择何种发布类型,视具体业务场景而定。

9.27.5.6 选择发布项目

9.27.5.7 配置分发计划

9.27.5.8 配置安全设置

9.27.5.9 完成配置

9.27.6 SqlServer 从库配置

9.27.6.1 添加 本地订阅

9.27.6.2 选择 分发服务器

9.27.6.3 选择 分发代理位置

9.27.6.4 选择 订阅数据库

9.27.6.5 选择 分发安全设置

9.27.6.6 选择 同步计划

9.27.6.7 完成订阅

9.27.7 分发定义监视

9.27.8 查看主从复制结果

特别特性

主从复制有一定迟延性,所以系统设计要有一定“容忍性"。

9.27.9 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-repository/index.html b/handbook/build/docs/dbcontext-repository/index.html index 9c69196b6bb..6e2866d5c0a 100644 --- a/handbook/build/docs/dbcontext-repository/index.html +++ b/handbook/build/docs/dbcontext-repository/index.html @@ -6,7 +6,7 @@ 9.4 仓储模式 | Furion - + @@ -32,7 +32,7 @@
// 其他更多数据库一样的操作

另外任何仓储或实体配置都支持多个数据库同时操作

仓储方式

IRepository<Person, MsSqlDbContextLocator> mssqlRepository
ISqlRepository<MsSqlDbContextLocator> mssqlRepository;

动态 sql 方式

"select * from person".Change<MsSqlDbContextLocator>().SqlQuery();

实体配置方式

public class User:Entity<MsSqlDbContextLocator, MySqlDbContextLocator>
{
}

Sql 代理方式

[SqlFunction("funcName", DbContextLocator = typeof(MySqlDbContextLocator))]
int GetAge(int id);

Linq 中方式

[QueryableFunction("funcName","dbo", DbContextLocator = typeof(MySqlDbContextLocator))]
string GetName()=> throw Oops.Oh("不支持该数据库操作");

9.4.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-seed-data/index.html b/handbook/build/docs/dbcontext-seed-data/index.html index ac30e98d4fb..42dbd1d7e33 100644 --- a/handbook/build/docs/dbcontext-seed-data/index.html +++ b/handbook/build/docs/dbcontext-seed-data/index.html @@ -6,7 +6,7 @@ 9.21 实体种子数据 | Furion - + @@ -31,7 +31,7 @@
namespace Furion.Application
{
public class PersonSeedData : IEntitySeedData<Person>
{
// 配置种子数据
public IEnumerable<Person> HasData(DbContext dbContext, Type dbContextLocator)
{
return new List<Person>
{
new Person { Id = 1, Name = "百小僧", Address = "广东省中山市" },
new Person { Id = 2, Name = "新生帝", Address = "广东省珠海市" }
};
}
}
}

9.21.3 导航属性

通常我们的实体有 一对多多对多等外键关系,那么我们需要单独为每一个实体添加数据种子,而不是直接写在主表中。

9.21.4 多个数据库种子数据

Furion 提供泛型的方式支持多个数据库种子数据设定,如:

using Furion.DatabaseAccessor;
using System.Collections.Generic;
namespace Furion.Application
{
public class PersonSeedData : IEntitySeedData<Person, MySqlDbContextLocator, SqliteDbContextLocator>
{
// 配置种子数据
public IEnumerable<Person> HasData(DbContext dbContext, Type dbContextLocator)
{
return new List<Person>
{
new Person { Id = 1, Name = "百小僧", Address = "广东省中山市" },
new Person { Id = 2, Name = "新生帝", Address = "广东省珠海市" }
};
}
}
}

上面的例子表示同时为 MySqlDbContextSqliteDbContext 创建种子数据。

9.21.5 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 数据种子 知识可查阅 EF Core - 数据种子设定 章节。

- + diff --git a/handbook/build/docs/dbcontext-sql-proxy/index.html b/handbook/build/docs/dbcontext-sql-proxy/index.html index 8271d73fd5a..85684786b77 100644 --- a/handbook/build/docs/dbcontext-sql-proxy/index.html +++ b/handbook/build/docs/dbcontext-sql-proxy/index.html @@ -6,7 +6,7 @@ 9.17 Sql 高级代理 | Furion - + @@ -75,7 +75,7 @@
namespace Furion.Application
{
public interface ISql : ISqlDispatchProxy
{
[SqlFunction("FN_Name")] // 标量函数
string GetValue(MyParam dto);
[SqlProcedure("FN_Name")] // 表值函数
List<Person> GetPersons(int id);
}
}
补充说明

Sql 代理会自动判断返回值然后自动执行特定函数类型。

9.17.6 为什么用它?

通过上面的例子大家就可以了解,这种方式操作 sql 非常简单,而且极易维护。大家不用去关系返回值,关心用哪个方法,所有东西会自动给你处理好。

所以,如果需要用 Sql 操作,推荐使用 Sql 高级代理。

9.17.7 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-sql-template/index.html b/handbook/build/docs/dbcontext-sql-template/index.html index b1910f22de0..955c65a37ec 100644 --- a/handbook/build/docs/dbcontext-sql-template/index.html +++ b/handbook/build/docs/dbcontext-sql-template/index.html @@ -6,7 +6,7 @@ 9.16 Sql 模板 | Furion - + @@ -27,7 +27,7 @@
// 懒人方式
var users = "#(Select.User)".SqlQuery<User>(new { id = 1});
// Sql 代理方式
[SqlExecute("#(Select.User)")]
List<User> GetUser(int id);

9.16.3.2 高级嵌套

var users = repository.SqlQuery<User>(
@"select * from user u
left join #(User.Detail) d on u.Id = d.UserId
where id > @id");

9.16.4 Sql 模板配置

9.16.4.1 普通模式

{
"Select.User": "select * from User"
}

9.16.4.2 更多配置

{
"Select.User": {
"Sql": "select * from User where id > @id and Name = @name",
"Params": [
{
"Name": " Id",
"Value": "1",
"DbType": "Int16",
"Size": 10
},
{
"Name": " Name",
"Value": "百小僧",
"DbType": "String",
"Size": 10
}
]
}
}

9.16.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-sql/index.html b/handbook/build/docs/dbcontext-sql/index.html index 6c15c4b6c14..f3171112f90 100644 --- a/handbook/build/docs/dbcontext-sql/index.html +++ b/handbook/build/docs/dbcontext-sql/index.html @@ -6,7 +6,7 @@ 9.15 Sql 操作 | Furion - + @@ -172,7 +172,7 @@
// 不再举例子。。。
补充说明

不管是那种方式操作 Sql ,方法名参数都是一致的,如:

  • SqlQuery
  • SqlQueryAsync
  • SqlQueries
  • SqlQueriesAsync
  • SqlNonQuery
  • SqlNonQueryAsync
  • SqlScalar
  • SqlScalarAsync
  • SqlProcedureQuery
  • SqlProcedureQueryAsync
  • SqlProcedureQueries
  • SqlProcedureQueriesAsync
  • SqlProcedureScalar
  • SqlProcedureScalarAsync
  • SqlProcedureNonQuery
  • SqlProcedureNonQueryAsync
  • SqlProcedureOutput
  • SqlProcedureOutputAsync
  • SqlFunctionScalar
  • SqlFunctionScalarAsync
  • SqlFunctionQuery
  • SqlFunctionQuery

9.15.6 IRepository 操作

IRepository 也能操作 sql,调用方法也是和上面一致的,如:

var dataTable = repository.Sql().SqlQuery("select * from person");
特别说明

由于篇幅有限,不再列举所有例子。

9.15.7 IRepository<TEntity> 操作

IRepository<TEntity> 也能操作 sql,调用方法也是和上面一致的,如:

var dataTable = personRepository.SqlQuery("select * from person");
特别说明

由于篇幅有限,不再列举所有例子。

9.15.8 关于 Sql 参数

所有 sql存储过程函数 参数都支持四种方式:

  • DbParameter[]:数组类型
  • new {}:匿名类型
  • new Class{}:强类型类型(支持复杂存储过程参数)
  • Dictionary<string,object> 类型
小知识

建议除了复杂的存储过程(带 OUTPUT/RETURN)的以外,所有参数建议使用 new {} 匿名类型,如果需要动态参数,则可以使用 Dictionary<string,object> 类型。

9.15.9 多数据库 Sql 操作 💯 💛

Furion 框架拥有非常灵活的多数据库操作方式,只需通过多数据库上下文定位器即可动态切换数据库。

9.15.9.1 懒人无敌 🐮 方式

var dataTable = "select * from person".Change<MySqlDbContextLocator>().SqlQuery();
var persons = "select * from person whre id > @id".Change<SqliteDbContextLocator>().SqlQuery<Person>();
补充说明

懒人方式 只需要通过 Change<TDbContextLocator> 方式即可动态切换数据库。

9.15.9.2 ISqlRepository 方式

只需要通过 ISqlRepository<TDbContextLocator> 注入或通过 sqlRepository.Change<TDbContextLocator>() 切换。

9.15.9.3 IRepository 方式

只需要通过 repository.Change<TDbContextLocator>() 获取即可。

9.15.9.4 IRepository<TEntity> 方式

只需要通过 IRepository<TEntity, TDbContextLocator> 注入或通过 personRepository.Change<TEntity, TDbContextLocator>() 切换。

9.15.10 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-update/index.html b/handbook/build/docs/dbcontext-update/index.html index 00bc1d60397..6386c4c73ae 100644 --- a/handbook/build/docs/dbcontext-update/index.html +++ b/handbook/build/docs/dbcontext-update/index.html @@ -6,7 +6,7 @@ 9.6 更新操作 | Furion - + @@ -197,7 +197,7 @@
// 示例二
await repository.UpdateNowAsync(new List<User> { user, user2 });
// 示例三
await repository.UpdateNowAsync(new[] {user, user2 });
小知识

所有带 Now 结尾的表示立即提交到数据库,也就是立即调用 SaveChangesSaveChangesAsync

9.6.15 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext-view/index.html b/handbook/build/docs/dbcontext-view/index.html index e667bc88d1e..421fb38cbd1 100644 --- a/handbook/build/docs/dbcontext-view/index.html +++ b/handbook/build/docs/dbcontext-view/index.html @@ -6,7 +6,7 @@ 9.12 视图操作 | Furion - + @@ -33,7 +33,7 @@
public FurService(IRepository<V_Person> repository)
{
// 初始化只读仓储
_readableRepository = repository.Constraint<IReadableRepository<V_Person>>();
}
/// <summary>
/// 读取视图
/// </summary>
/// <returns></returns>
public async Task<List<V_Person>> GetVPerson()
{
var list = await _readableRepository.AsAsyncEnumerable();
return list;
}
}
}
小知识

通过 .Constraint<TEntity,TDbContextLocator> 方法可以将仓储约束为特定仓储,如只读仓储,可读可写仓储,只新增仓储等。

9.12.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/dbcontext/index.html b/handbook/build/docs/dbcontext/index.html index 80bd1d1d842..64f383f727c 100644 --- a/handbook/build/docs/dbcontext/index.html +++ b/handbook/build/docs/dbcontext/index.html @@ -6,7 +6,7 @@ 9.1 数据库上下文 | Furion - + @@ -36,7 +36,7 @@
options.AddDbPool<SecondDbContext, SecondDbContextDbContextLocator>(DbProvider.SqlServer); // 第二个数据库
options.AddDbPool<ThirdDbContext, ThirdDbContextDbContextLocator>(DbProvider.SqlServer); // 第三个数据库

9.1.8 动态数据库上下文对象

Furion 框架中,数据库上下文是定义在 Furion.EntityFramework.Core 项目层,并且该层不被 Furion.ApplicationFurion.Core 等层引用。

所以就不能直接在 Furion.Application 项目层直接使用 Furion.EntityFramework.Core 定义的数据库上下文。

Furion 为了解决这个问题,提供了两种方式处理:

  • respository.DbContext :当前数据库上下文对象,返回是 DbContext 抽象类型
  • respository.DynamicDbContext:当前数据库上下文对象,返回的是 dynamic 类型

如果你只是想使用 DbContext 的功能,直接使用 respository.DbContext 即可,如:

respository.DbContext.SaveChanges();

如果你想能够获取具体的数据库上下文类型,如 MyDbContext,那么使用 respository.DynamicDbContext 就可以获取到具体的 MyDbContext 类型。如:

var persons = respository.DynamicDbContext.Persons.Find(1);
var users = respository.DynamicDbContext.Users;

这样就可以直接操作 MyDbContext 定义的属性和方法了。

9.1.9 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 数据库上下文 知识可查阅 EF Core - 配置 DbContext 章节。

- + diff --git a/handbook/build/docs/dependency-injection/index.html b/handbook/build/docs/dependency-injection/index.html index c7eee0dc4aa..9327629f3c4 100644 --- a/handbook/build/docs/dependency-injection/index.html +++ b/handbook/build/docs/dependency-injection/index.html @@ -6,7 +6,7 @@ 11. 依赖注入/控制反转 | Furion - + @@ -58,7 +58,7 @@
Console.WriteLine("SayHello 方法返回值:" + result);
return result;
}
}
}

之后我们只需要为 TestService 增加 [Injection] 特性即可,如:

[Injection(Proxy = typeof(LogDispatchProxy))]
public class TestService: ITestService, ITransient
{
public string SayHello(string word)
{
return $"Hello {word}";
}
}

之后 SayHello 方法被调用的时候就可以实现动态拦截了,比如这里写日志。

11.12.1 全局Aop拦截

Furion 框架也提供了全局拦截的方式,只需要在 Startup.cs 中注册即可:

service.AddServiceProxy<LogDispatchProxy>();

这样就会拦截所有的 Service,当然也可以通过给特定类贴 [SkipProxy] 跳过全局拦截操作。

拦截优先级

[SkipProxy] > [Injection(Proxy = typeof(LogDispatchProxy))] > 全局拦截

11.12.2 AOP 的作用

这种面向切面的能力(动态拦截/代理)可以实现很多很多功能,如:

  • 动态日志记录
  • 动态修改参数
  • 动态修改返回值
  • 动态方法重定向
  • 动态修改代码逻辑
  • 动态实现异常监听

还可以做更多更多的事情。

11.13 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/deploy/index.html b/handbook/build/docs/deploy/index.html index 563209d5262..b2a76183d4d 100644 --- a/handbook/build/docs/deploy/index.html +++ b/handbook/build/docs/deploy/index.html @@ -6,7 +6,7 @@ 25. 托管部署 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/devops/index.html b/handbook/build/docs/devops/index.html index 24eb062656b..3912a1ac0b5 100644 --- a/handbook/build/docs/devops/index.html +++ b/handbook/build/docs/devops/index.html @@ -6,7 +6,7 @@ 26. 持续部署集成 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/dynamic-api-controller/index.html b/handbook/build/docs/dynamic-api-controller/index.html index 2d6054f393c..aa292de2bc9 100644 --- a/handbook/build/docs/dynamic-api-controller/index.html +++ b/handbook/build/docs/dynamic-api-controller/index.html @@ -6,7 +6,7 @@ 5. 动态 WebAPI | Furion - + @@ -81,7 +81,7 @@
namespace Furion.Web.Entry.Controllers
{
public class MvcController : ControllerBase
{
public string Get()
{
return nameof(Furion);
}
}
}
注意事项

启用该配置后,如果 Mvc 控制器 没有任何 [Route] 特性,但是贴了 [ApiController] 特性将会报错。原因是 [ApiController] 特性内部做了路由特性检测。所以建议使用 [ApiDataValidation] 代替。

查看 ASP.NET Core - ApiBehaviorApplicationModelProvider 源码

5.11 关于 AOP 拦截

动态WebAPI 支持 Controller 的所有过滤器/筛选器拦截,也就是可以通过 ActionFilterResultFilter 进行拦截操作。如:

public class SampleAsyncActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context,ActionExecutionDelegate next)
{
var resultContext = await next();
}
}

5.12 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/entity/index.html b/handbook/build/docs/entity/index.html index 90d2d5e66a9..4fec32d0b55 100644 --- a/handbook/build/docs/entity/index.html +++ b/handbook/build/docs/entity/index.html @@ -6,7 +6,7 @@ 9.3 数据库实体 | Furion - + @@ -38,7 +38,7 @@
// 配置数据库实体
public void Configure(EntityTypeBuilder<User> entityBuilder, DbContext dbContext, Type dbContextLocator)
{
entityBuilder.HasKey(u => u.Id);
entityBuilder.HasIndex(u => u.Name);
}
}
}

9.3.3.2 在任何实例类中配置

using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
namespace Furion.Core
{
public class SomeClass : IEntityTypeBuilder<User>
{
public void Configure(EntityTypeBuilder<User> entityBuilder, DbContext dbContext, Type dbContextLocator)
{
entityBuilder.HasKey(u => u.Id);
entityBuilder.HasIndex(u => u.Name);
}
}
}

如,上面例子,通过 SomeClass 配置 User 数据库实体。

9.3.4 数据库实体配置说明

Furion 框架会自动扫描所有继承 IEntity 接口的类进行 DbSet<TEntity> 注册,也就是实现自动配置 DbContextOnModelCreating

如果需要跳过自动注册,只需要贴 [NonAutomatic][SkipScan] 特性即可。一旦贴了此特性,那么就需要手动配置 DbContextOnModelCreating

9.3.5 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/errors/index.html b/handbook/build/docs/errors/index.html index c82466cb070..14c19ff5507 100644 --- a/handbook/build/docs/errors/index.html +++ b/handbook/build/docs/errors/index.html @@ -6,7 +6,7 @@ 29.2 常见错误 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/event-bus/index.html b/handbook/build/docs/event-bus/index.html index 9e571425214..6dc23905272 100644 --- a/handbook/build/docs/event-bus/index.html +++ b/handbook/build/docs/event-bus/index.html @@ -6,7 +6,7 @@ 18. 事件总线 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/friendly-exception/index.html b/handbook/build/docs/friendly-exception/index.html index 5457adceed7..1a565c22a5c 100644 --- a/handbook/build/docs/friendly-exception/index.html +++ b/handbook/build/docs/friendly-exception/index.html @@ -6,7 +6,7 @@ 7. 友好异常处理 | Furion - + @@ -63,7 +63,7 @@
namespace Furion.Application
{
public class LogExceptionHandler : IGlobalExceptionHandler, ISingleton
{
public Task OnExceptionAsync(ExceptionContext context)
{
// 写日志
return Task.CompletedTask;
}
}
}

7.15 FriendlyExceptionSettings 配置

  • HideErrorCode:隐藏错误码,bool 类型,默认 false
  • DefaultErrorCode:默认错误码,string 类型
  • DefaultErrorMessage:默认错误消息,string 类型

配置示例

{
"FriendlyExceptionSettings": {
"DefaultErrorMessage": "系统异常,请联系管理员"
}
}

7.16 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/get-start/index.html b/handbook/build/docs/get-start/index.html index daedc377bdd..da77060772a 100644 --- a/handbook/build/docs/get-start/index.html +++ b/handbook/build/docs/get-start/index.html @@ -6,7 +6,7 @@ 2.1 一分钟入门 | Furion - + @@ -36,7 +36,7 @@
// 添加这一行,如果是 MVC和API共存项目,无需添加 string.Empty
app.UseInject(string.Empty);
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
小提醒

如果 app.UseInject() 不输入参数,则默认地址为 /api,如果输入 string.Empty 则为 / 目录。

2.4 启动浏览器

启动浏览器查看效果。

说好一分钟入门,你们用了多长时间。😁

- + diff --git a/handbook/build/docs/gooduse/index.html b/handbook/build/docs/gooduse/index.html index 1ffea51a949..e19fe7f3367 100644 --- a/handbook/build/docs/gooduse/index.html +++ b/handbook/build/docs/gooduse/index.html @@ -6,7 +6,7 @@ 29.3 最佳实践 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/grpc/index.html b/handbook/build/docs/grpc/index.html index 14b72360623..aae4d0800c5 100644 --- a/handbook/build/docs/grpc/index.html +++ b/handbook/build/docs/grpc/index.html @@ -6,7 +6,7 @@ 24. Grpc 服务 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/http/index.html b/handbook/build/docs/http/index.html index 648aab3dd46..0459aa32d9a 100644 --- a/handbook/build/docs/http/index.html +++ b/handbook/build/docs/http/index.html @@ -6,7 +6,7 @@ 20. 网络请求 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/index.html b/handbook/build/docs/index.html index 096a6285094..49714cfd713 100644 --- a/handbook/build/docs/index.html +++ b/handbook/build/docs/index.html @@ -6,7 +6,7 @@ 1.1 介绍 | Furion - + @@ -19,13 +19,13 @@ - +
-

1.1 介绍

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

🌭 开源地址

🍿 Docker 镜像

  • Docker Hub 线上镜像
docker run --name furion -p 5000:80 monksoul/furion:v1.4.3
  • 手动 打包镜像

打开 CMD/Shell/PowerShell 进入 Furion 项目根目录打包 Furion 镜像:

docker build -t furion:v1.4.3 .

打包成功后,直接 docker run

docker run --name furion -p 5000:80 furion:v1.4.3

🥥 Furion 官方包

包类型名称版本描述
nugetFurionnugetFurion 总包
nugetFurion.Extras.Authentication.JwtBearernugetFurion Jwt 拓展包
nugetFurion.Extras.DependencyModel.CodeAnalysisnugetFurion 动态反射 拓展包

🍄 Furion 脚手架

模板类型名称版本描述
nugetFurion.Template.MvcnugetMvc 模板
nugetFurion.Template.ApinugetWebApi 模板
nugetFurion.Template.AppnugetMvc/WebApi 模板
nugetFurion.Template.RazornugetRazorPages 模板
nugetFurion.Template.RazorWithWebApinugetRazorPages/WebApi 模板
nugetFurion.Template.BlazornugetBlazor 模板
nugetFurion.Template.BlazorWithWebApinugetBlazor/WebApi 模板

如何使用脚手架

🍎 框架特点

  • 全新面貌:基于 .NET 5 平台,没有历史包袱
  • 极易入门:只需要一个 Inject() 即可完成配置
  • 极速开发:内置丰富的企业应用开发功能
  • 极少依赖:框架只依赖三个第三方包
  • 极其灵活:轻松面对多变复杂的需求
  • 极易维护:采用独特的架构思想,只为长久维护设计
  • 完整文档:提供完善的开发文档

🥞 架构设计

正在整理中...

🥝 功能模块

🥐 框架依赖

Furion 为了追求极速入门,极致性能,尽可能的不使用或减少第三方依赖。目前 Furion 仅集成了以下三个依赖:

麻雀虽小五脏俱全。Furion 即使只集成了这三个依赖,但是主流的 依赖注入/控制反转AOP 面向切面编程,事件总线数据验证数据库操作 等等一个都不少。

🥗 环境要求

  • Visual Studio 2019 16.8 +
  • .NET 5 SDK +
  • .Net Standard 2.1 +

🥪 支持平台

  • 运行环境
    • Windows
    • Linux
    • MacOS
    • Docker/K8S/K3S/Rancher
    • Xamarin/MAUI
  • 数据库
    • SqlServer
    • Sqlite
    • Azure Cosmos
    • MySql
    • MariaDB
    • PostgreSQL
    • InMemoryDatabase
    • Oracle(并未完全适配
    • Firebird
    • 达梦数据库
  • 应用部署
    • Kestrel
    • Nginx
    • Jexus
    • IIS
    • Apache
    • PM2
    • Supervisor
    • 单文件
    • 容器(Docker/K8S/K3S/Rancher)

🍖 关于性能

Furion 目前采用 Visual Studio 2019 16.8 自带性能测试和 JMeter 进行测试,由于篇幅有限,只贴部分测试图,测试结果如下:


🍚 关于作者

一个拥有 12 年开发经验 .NETer。喜欢分享,喜欢新技术,在互联网多个技术领域皆有涉猎,dotNET China MIP,同时多次获得开源中国 Gitee 授予 GVP 证书。

🍤 项目成员

🎈 欢迎更多的开发者加入 Furion 大家庭。

🍝 他们都在用

  • 百签科技(广东)有限公司
  • 码为科技(广州)有限公司
  • 广州启顺国际货运代理有限公司
  • 森丰供应链服务(广州)有限公司
  • 中山赢友网络科技有限公司
  • 中山模思软件科技有限公司
  • 珠海市恒泰新软件有限责任公司
  • 珠海思诺锐创软件有限公司
  • 深圳市易胜科技有限公司
  • 重庆虫儿飞科技有限公司
  • 重庆林木森科技有限公司
  • 深圳市品立方科技有限公司
  • 上海奥达科股份有限公司
  • 中山市泓升软件科技有限公司
  • 唐山天权建筑科技有限公司
  • 北京帝龙科技有限公司
  • 深圳市希立网络有限公司
  • 广州市飞帆计算机技术有限公司
  • 泉州市润海信息科技有限公司
  • 成都市彼岸里信息科技有限公司
  • 福建省山水生活服务集团有限公司

如果您的项目使用到 Furion 开发,可以告诉我们。

🍻 贡献代码

Furion 遵循 Apache-2.0 开源协议,欢迎大家提交 PRIssue

如果要为项目做出贡献,请查看贡献指南。

🍍 捐赠列表

注:排序按捐赠顺序书写

捐赠人昵称捐赠金额(元)附语
🤴 爱吃油麦菜100感谢您的开源项目!
👳‍♂️ 麦壳饼200感谢您的开源项目!
👨 Sun100感谢您的开源项目!
👶 d61761720感谢您的开源项目!
👦 Diqiguoji00816.66见贤思齐
👲 nodyang100感谢您的开源项目!
👳‍♀️ mictxd100吹过的牛都实现。
🧓 欧流全10希望将来超越 Spring
👨‍⚕️ lionkon10...看了框架感觉拿来学习是很不错的...
😤 好人!10Nice 的小僧,我们的 dotnetchina 马上火起来了
😮 木木 Woody10感谢您的开源项目!
😚 Joker HouQQ 超级会员一个月
🤠 ccdfzQQ 专属红包 199
🌝 天夫李总支付宝 6666Furion 非常有意思,持续关注
😝 六尘子微信红包 199公司已经使用,小小敬意
🤠 ccdfzQQ 专属红包 200赞助一根内存条
🤑 邓亮灯28.88感谢您的开源项目!
😬 天道酬勤微信二维码 188小小心意
🥰 却月居士QQ 专属红包 100恭喜发财
🤩 鲁旭100感谢您的开源项目!
😬 散客行微信二维码 666终于找到一个不错的框架
😌 本心100项目功能很强大
🙆‍♂️ 毕业生100请你喝杯咖啡
🦹‍♀️ 猪鼻子微信二维码 668
🧟‍♂️ 明年·今日200使用的框架里最爽的,最理想的!加油
👨‍🎓 过去的过去50感谢您的开源项目!
👨‍🔧 万里兮100新公司的第一个项目从 Furion 开始
👴 Muphalem20很热心很亲切的开发者,加油!
💂‍♂️ 吃锅巴的码农微信二维码 500就冲你的文档写得好!
🤴 三重罗生门微信红包 200下次烤鱼你请!

非常感谢您们的支持,正是因为您们,中国开源才可以越走越远,Furion 越走越远。

🥔 QQ 交流群

🧆 友情链接

👉 Furion 👉 SqlSugar 👉 Layx 👉 t-io 👉 ThinkPHP 👉 Hutool 👉 BootstrapAdmin 👉 BootstrapBlazor 👉 IoTSharp 👉 Anno.Core 👉 WaterCloud

+

1.1 介绍

star fork GitHub stars GitHub forks GitHub license nuget

让 .NET 开发更简单,更通用,更流行。

💐 序言

无私奉献不是天方夜谭,有时候,我们也可以做到。

🍕 名字的由来

故事是这样子的:

自微软宣布 .NET 5 平台消息之后,就琢磨着开发一个基于 .NET 5 平台的开发框架,想做第一个吃 .NET 5 螃蟹尝鲜之人。

一开始想到了 Lazier 作为框架的名称,中文有 更懒 的意思。符合我的 “一切从简,只为了更懒” 的开发理念。

但是 更懒更烂 中文读音相近且没有特色,而且寓意也不是很好,对此换名问题苦恼了好些天。

刚好有一次在 QQ 群中无意间刷到了群友发的 “先知” 单词:Furion,就那一刻,就认定它了!

Furion 中文有 先知 的意思,恰好符合我创造框架的初衷。所以,Furion 就诞生了。

🍔 关于 LOGO

Furion 标志设计理念是借鉴著名的 袋鼠理论 设计的。

袋鼠具有长腿、育袋、自我奔跑特点。

  • 长腿:代表着 Furion 拥有稳健的双腿,走在科技的前沿,走的更远,跑的更快。
  • 育袋:小育袋、大作为。期待 Furion 能够育孕出更多 .NET 优秀开发者和生机勃勃的生态。
  • 自我奔跑Furion 自身也要不断学习、不断进步、不断创新、不断开拓。

🍯 开源案例

  • 考试君:基于 Furion 的在线考试系统
  • 园丁:基于 Furion + Blazor 的超简单后台管理系统

🍟 文档地址

目前文档正在逐步完善中。

🥦 系列教程

🌭 开源地址

🍿 Docker 镜像

  • Docker Hub 线上镜像
docker run --name furion -p 5000:80 monksoul/furion:v1.4.3
  • 手动 打包镜像

打开 CMD/Shell/PowerShell 进入 Furion 项目根目录打包 Furion 镜像:

docker build -t furion:v1.4.3 .

打包成功后,直接 docker run

docker run --name furion -p 5000:80 furion:v1.4.3

🥥 Furion 官方包

包类型名称版本描述
nugetFurionnugetFurion 总包
nugetFurion.Extras.Authentication.JwtBearernugetFurion Jwt 拓展包
nugetFurion.Extras.DependencyModel.CodeAnalysisnugetFurion 动态反射 拓展包

🍄 Furion 脚手架

模板类型名称版本描述
nugetFurion.Template.MvcnugetMvc 模板
nugetFurion.Template.ApinugetWebApi 模板
nugetFurion.Template.AppnugetMvc/WebApi 模板
nugetFurion.Template.RazornugetRazorPages 模板
nugetFurion.Template.RazorWithWebApinugetRazorPages/WebApi 模板
nugetFurion.Template.BlazornugetBlazor 模板
nugetFurion.Template.BlazorWithWebApinugetBlazor/WebApi 模板

如何使用脚手架

🍎 框架特点

  • 全新面貌:基于 .NET 5 平台,没有历史包袱
  • 极易入门:只需要一个 Inject() 即可完成配置
  • 极速开发:内置丰富的企业应用开发功能
  • 极少依赖:框架只依赖三个第三方包
  • 极其灵活:轻松面对多变复杂的需求
  • 极易维护:采用独特的架构思想,只为长久维护设计
  • 完整文档:提供完善的开发文档

🥞 架构设计

正在整理中...

🥝 功能模块

🥐 框架依赖

Furion 为了追求极速入门,极致性能,尽可能的不使用或减少第三方依赖。目前 Furion 仅集成了以下三个依赖:

麻雀虽小五脏俱全。Furion 即使只集成了这三个依赖,但是主流的 依赖注入/控制反转AOP 面向切面编程,事件总线数据验证数据库操作 等等一个都不少。

🥗 环境要求

  • Visual Studio 2019 16.8 +
  • .NET 5 SDK +
  • .Net Standard 2.1 +

🥪 支持平台

  • 运行环境
    • Windows
    • Linux
    • MacOS
    • Docker/K8S/K3S/Rancher
    • Xamarin/MAUI
  • 数据库
    • SqlServer
    • Sqlite
    • Azure Cosmos
    • MySql
    • MariaDB
    • PostgreSQL
    • InMemoryDatabase
    • Oracle(并未完全适配
    • Firebird
    • 达梦数据库
  • 应用部署
    • Kestrel
    • Nginx
    • Jexus
    • IIS
    • Apache
    • PM2
    • Supervisor
    • 单文件
    • 容器(Docker/K8S/K3S/Rancher)

🍖 关于性能

Furion 目前采用 Visual Studio 2019 16.8 自带性能测试和 JMeter 进行测试,由于篇幅有限,只贴部分测试图,测试结果如下:


🍚 关于作者

一个拥有 12 年开发经验 .NETer。喜欢分享,喜欢新技术,在互联网多个技术领域皆有涉猎,dotNET China MIP,同时多次获得开源中国 Gitee 授予 GVP 证书。

🍤 项目成员

🎈 欢迎更多的开发者加入 Furion 大家庭。

🍝 他们都在用

  • 百签科技(广东)有限公司
  • 码为科技(广州)有限公司
  • 广州启顺国际货运代理有限公司
  • 森丰供应链服务(广州)有限公司
  • 中山赢友网络科技有限公司
  • 中山模思软件科技有限公司
  • 珠海市恒泰新软件有限责任公司
  • 珠海思诺锐创软件有限公司
  • 深圳市易胜科技有限公司
  • 重庆虫儿飞科技有限公司
  • 重庆林木森科技有限公司
  • 深圳市品立方科技有限公司
  • 上海奥达科股份有限公司
  • 中山市泓升软件科技有限公司
  • 唐山天权建筑科技有限公司
  • 北京帝龙科技有限公司
  • 深圳市希立网络有限公司
  • 广州市飞帆计算机技术有限公司
  • 泉州市润海信息科技有限公司
  • 成都市彼岸里信息科技有限公司
  • 福建省山水生活服务集团有限公司
  • 安徽宝典网络科技有限公司

如果您的项目使用到 Furion 开发,可以告诉我们。

🍻 贡献代码

Furion 遵循 Apache-2.0 开源协议,欢迎大家提交 PRIssue

如果要为项目做出贡献,请查看贡献指南。

🍍 捐赠列表

注:排序按捐赠顺序书写

捐赠人昵称捐赠金额(元)附语
🤴 爱吃油麦菜100感谢您的开源项目!
👳‍♂️ 麦壳饼200感谢您的开源项目!
👨 Sun100感谢您的开源项目!
👶 d61761720感谢您的开源项目!
👦 Diqiguoji00816.66见贤思齐
👲 nodyang100感谢您的开源项目!
👳‍♀️ mictxd100吹过的牛都实现。
🧓 欧流全10希望将来超越 Spring
👨‍⚕️ lionkon10...看了框架感觉拿来学习是很不错的...
😤 好人!10Nice 的小僧,我们的 dotnetchina 马上火起来了
😮 木木 Woody10感谢您的开源项目!
😚 Joker HouQQ 超级会员一个月
🤠 ccdfzQQ 专属红包 199
🌝 天夫李总支付宝 6666Furion 非常有意思,持续关注
😝 六尘子微信红包 199公司已经使用,小小敬意
🤠 ccdfzQQ 专属红包 200赞助一根内存条
🤑 邓亮灯28.88感谢您的开源项目!
😬 天道酬勤微信二维码 188小小心意
🥰 却月居士QQ 专属红包 100恭喜发财
🤩 鲁旭100感谢您的开源项目!
😬 散客行微信二维码 666终于找到一个不错的框架
😌 本心100项目功能很强大
🙆‍♂️ 毕业生100请你喝杯咖啡
🦹‍♀️ 猪鼻子微信二维码 668
🧟‍♂️ 明年·今日200使用的框架里最爽的,最理想的!加油
👨‍🎓 过去的过去50感谢您的开源项目!
👨‍🔧 万里兮100新公司的第一个项目从 Furion 开始
👴 Muphalem20很热心很亲切的开发者,加油!
💂‍♂️ 吃锅巴的码农微信二维码 500就冲你的文档写得好!
🤴 三重罗生门微信红包 200下次烤鱼你请!

非常感谢您们的支持,正是因为您们,中国开源才可以越走越远,Furion 越走越远。

🥔 QQ 交流群

🧆 友情链接

👉 Furion 👉 SqlSugar 👉 Layx 👉 t-io 👉 ThinkPHP 👉 Hutool 👉 BootstrapAdmin 👉 BootstrapBlazor 👉 IoTSharp 👉 Anno.Core 👉 WaterCloud

- + @@ -38,6 +38,6 @@ - + \ No newline at end of file diff --git a/handbook/build/docs/job/index.html b/handbook/build/docs/job/index.html index d10450d61e7..35f3781da2a 100644 --- a/handbook/build/docs/job/index.html +++ b/handbook/build/docs/job/index.html @@ -6,7 +6,7 @@ 22. 任务调度 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/local-language/index.html b/handbook/build/docs/local-language/index.html index 95e18082bc3..8d95be7d9d3 100644 --- a/handbook/build/docs/local-language/index.html +++ b/handbook/build/docs/local-language/index.html @@ -6,7 +6,7 @@ 17. 多语言处理 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/logging/index.html b/handbook/build/docs/logging/index.html index 699dbf80ad8..b3a40e2ec5c 100644 --- a/handbook/build/docs/logging/index.html +++ b/handbook/build/docs/logging/index.html @@ -6,7 +6,7 @@ 19. 日志记录 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/object-mapper/index.html b/handbook/build/docs/object-mapper/index.html index 53dd5308e37..2de0b88d1ef 100644 --- a/handbook/build/docs/object-mapper/index.html +++ b/handbook/build/docs/object-mapper/index.html @@ -6,7 +6,7 @@ 12. 对象数据映射 | Furion - + @@ -27,7 +27,7 @@
var dto = new Dto();
dto.Id = entity.Id;
dto.Name = entity.Name;
dto.Age = entity.Age;
dto.Address = entity.Address;
dto.FullName = entity.FirstName + entity.LastName;
dto.IdCard = entity.IdCard.Replace("1234", "****");

上面的例子似乎没有任何问题,但是如果很多地方需要这样的赋值操作、或者相同的赋值操作在多个地方使用,又或者一个类中含有非常多的属性或自定义赋值操作。那么这样的操作效率极低,容易出错,且代码非常臃肿和冗余。

所以,实现自动映射赋值和支持特殊配置的需求就有了。目前 C# 平台有两个优秀的对象映射工具:MapsterAutoMapperFurion 框架中,默认集成的是 MapsterMapster 是一款极易使用且超高性能的对象映射框架。

12.3 Mapster 使用

现在,我们可以通过 Mapster 提供的对象映射方法:Adapt 方法改造上面的例子:

12.3.1 极易入门

var entity = repository.Find(1);
var dto = entity.Adapt<Dto>();

仅仅一行代码就可以实现 entity -> dto 的转换,如果涉及到赋值的复制操作,如 dto.FullNamedto.IdCard,我们只需要自定义映射规则类即可。

12.3.2 自定义映射规则

using Furion.ObjectMapper;
using Mapster;
using System;
namespace Furion.Application
{
public class Mapper : IObjectMapper
{
public void Register(TypeAdapterConfig config)
{
config.ForType<Entity, Dto>()
.Map(dest => dest.FullName, src => src.FirstName + src.LastName)
.Map(dest => dest.IdCard, src => src.IdCard.Replace("1234", "****"));
}
}
}
小知识

该映射文件 Mapper.cs 可以放在任何项目或文件夹中,Furion 会在程序启动的时候自动扫描并注入配置。

12.3.3 依赖注入方式

Mapster 除了提供 Adapt 拓展方法以外,同时还提供依赖注入的方式。

public Person(IMapper mapper)
{
var dto = _mapper.Map<Dto>(entity);
}

12.3.4 和 EFCore 配合

Mapster 还提供了 ProjectToType Linq 拓展方法减少我们手动 Select 操作,如:

正常的操作:

var destinations = context.Sources
.Select(c => new Destination {
Id = p.Id,
Name = p.Name,
Surname = p.Surname,
....
})
.ToList();

使用 Mapster 之后:

var destinations = context.Sources.ProjectToType<Destination>().ToList();

12.5 全局默认配置

Furion 提供全局默认映射配置选项 TypeAdapterConfig.GlobalSettings.Default,可在 Startup 中配置即可,如:

TypeAdapterConfig.GlobalSettings.Default
.PreserveReference(true);

12.6 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 Mapster 知识可查阅 Mapster - Wiki 文档。

- + diff --git a/handbook/build/docs/options/index.html b/handbook/build/docs/options/index.html index 2284bfabdbc..ad2f4462c08 100644 --- a/handbook/build/docs/options/index.html +++ b/handbook/build/docs/options/index.html @@ -6,7 +6,7 @@ 4.2 选项 | Furion - + @@ -55,7 +55,7 @@
public void OnListener(AppInfoOptions options, IConfiguration configuration)
{
var name = options.Name; // 实时的最新值
var version = options.Version; // 实时的最新值
}
public void PostConfigure(AppInfoOptions options, IConfiguration configuration)
{
}
}
特别说明

IConfigurableOptionsListener<TOptions> 继承自 IConfigurableOptions<TOptions>

4.2.10 选项的优缺点

  • 优点

    • 强类型配置
    • 提供多种读取方式
    • 支持热加载
    • 支持设置默认值/后期配置
    • 支持在运行环境中动态配置
    • 支持验证配置有效性
    • 支持更改通知
    • 支持命名选项
  • 缺点

    • 需要定义对应类型
    • 需要在启动时注册

4.2.11 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 选项 知识可查阅 ASP.NET Core - 选项 章节。

- + diff --git a/handbook/build/docs/performance/index.html b/handbook/build/docs/performance/index.html index d37c1a23e97..c81b65ac852 100644 --- a/handbook/build/docs/performance/index.html +++ b/handbook/build/docs/performance/index.html @@ -6,7 +6,7 @@ 27.2 性能测试 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/process-service/index.html b/handbook/build/docs/process-service/index.html index 6f4113e36e0..ed45bff4bdd 100644 --- a/handbook/build/docs/process-service/index.html +++ b/handbook/build/docs/process-service/index.html @@ -6,7 +6,7 @@ 21. 进程服务 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/reference/index.html b/handbook/build/docs/reference/index.html index 0c565af10e4..31800bcd49b 100644 --- a/handbook/build/docs/reference/index.html +++ b/handbook/build/docs/reference/index.html @@ -6,7 +6,7 @@ 2.3 框架项目引用 | Furion - + @@ -27,7 +27,7 @@
namespace Furion.Web.Entry
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.Inject()
.UseStartup<Startup>();
});
}
}
}

2.3.3 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/saas/index.html b/handbook/build/docs/saas/index.html index 7abefbcfc9e..496386ab31e 100644 --- a/handbook/build/docs/saas/index.html +++ b/handbook/build/docs/saas/index.html @@ -6,7 +6,7 @@ 10. SaaS 多租户 | Furion - + @@ -62,7 +62,7 @@
public string Name { get; set; }
public string Host { get; set; }
}
}

如果需要查询该租户信息,可通过以下代码获取,如:

var tenantDbContext = Db.GetDbContext<MultiTenantDbContextLocator>();
var myTenant = tenantDbContext.Set<MyTenant>();

10.9 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/signalr/index.html b/handbook/build/docs/signalr/index.html index 57932630b29..1b823038306 100644 --- a/handbook/build/docs/signalr/index.html +++ b/handbook/build/docs/signalr/index.html @@ -6,7 +6,7 @@ 23. 即时通讯 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/source/index.html b/handbook/build/docs/source/index.html index 9092184784f..796aa312738 100644 --- a/handbook/build/docs/source/index.html +++ b/handbook/build/docs/source/index.html @@ -6,7 +6,7 @@ 1.3 源码结构 | Furion - + @@ -57,7 +57,7 @@
#prefer fields not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_field = false:suggestion
#prefer methods not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_method = false:suggestion
#prefer properties not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_property = false:suggestion
# Add file header
file_header_template = -----------------------------------------------------------------------------\nFur 是 .NET 5 平台下企业应用开发最佳实践框架。\nCopyright © 2020 Furion, Baiqian Co.,Ltd.\n\n框架名称:Furion\n框架作者:百小僧\n框架版本:1.0.0\n源码地址:Gitee:https://gitee.com/monksoul/Furion \n Github:https://github.com/monksoul/Furion \n开源协议:Apache-2.0(http://www.apache.org/licenses/LICENSE-2.0)\n-----------------------------------------------------------------------------

1.2.4 Furion 核心层

Furion 核心层是 Furion 框架的中心,也是 Furion 能够支撑起来的必备层。

源码结构:

Furion
├─Furion.csproj
├─Furion.csproj.user
├─FurStartup.cs
├─ViewEngine
| ├─IViewEngine.cs
| ├─ViewEngine.cs
| ├─Templates
| | ├─IViewEngineCompiledTemplate.cs
| | ├─IViewEngineTemplate.cs
| | ├─ViewEngineCompiledTemplate.cs
| | └ViewEngineTemplate.cs
| ├─Options
| | └ViewEngineCompilationOptions.cs
| ├─Models
| | └AnonymousTypeWrapper.cs
| ├─Exceptions
| | ├─ViewEngineCompilationException.cs
| | └ViewEngineException.cs
| ├─Compilations
| | ├─IViewEngineCompilationOptionsBuilder.cs
| | └ViewEngineCompilationOptionsBuilder.cs
├─UnifyResult
| ├─Providers
| | ├─IUnifyResultProvider.cs
| | └RESTfulResultProvider.cs
| ├─Models
| | └RESTfulResult.cs
| ├─Filters
| | └SuccessUnifyResultFilter.cs
| ├─Extensions
| | └UnifyResultServiceCollectionExtensions.cs
├─SpecificationDocument
| ├─Options
| | └SpecificationDocumentSettingsOptions.cs
| ├─Models
| | ├─GroupOrder.cs
| | ├─SpecificationOpenApiInfo.cs
| | ├─SpecificationOpenApiSecurityRequirementItem.cs
| | └SpecificationOpenApiSecurityScheme.cs
| ├─Extensions
| | ├─SpecificationDocumentApplicationBuilderExtensions.cs
| | └SpecificationDocumentServiceCollectionExtensions.cs
| ├─Builders
| | └SpecificationDocumentBuilder.cs
| ├─Assets
| | └index-mini-profiler.html
├─ObjectMapper
| ├─Extensions
| | └ObjectMapperServiceCollectionExtensions.cs
| ├─Dependencies
| | └IObjectMapper.cs
├─LinqBuilder
| ├─Visitors
| | └ParameterReplaceExpressionVisitor.cs
| ├─Extensions
| | └LinqExtensions.cs
| ├─Builders
| | └LinqExpression.cs
├─FriendlyException
| ├─Oops.cs
| ├─Providers
| | └IErrorCodeTypeProvider.cs
| ├─Options
| | └ErrorCodeMessageSettingsOptions.cs
| ├─Models
| | └MethodIfException.cs
| ├─Filters
| | └FriendlyExceptionFilter.cs
| ├─Extensions
| | └FriendlyExceptionServiceCollectionExtensions.cs
| ├─Attributes
| | ├─ErrorCodeItemMetadataAttribute.cs
| | ├─ErrorCodeTypeAttribute.cs
| | └IfExceptionAttribute.cs
├─DynamicApiController
| ├─Penetrates.cs
| ├─Providers
| | └DynamicApiControllerFeatureProvider.cs
| ├─Options
| | └DynamicApiControllerSettingsOptions.cs
| ├─Models
| | └ParameterRouteTemplate.cs
| ├─Extensions
| | └DynamicApiControllerServiceCollectionExtensions.cs
| ├─Enums
| | └ApiSeats.cs
| ├─Dependencies
| | └IDynamicApiController.cs
| ├─Conventions
| | └DynamicApiControllerApplicationModelConvention.cs
| ├─Attributes
| | ├─ApiDescriptionSettingsAttribute.cs
| | ├─ApiSeatAttribute.cs
| | └DynamicApiControllerAttribute.cs
├─DependencyInjection
| ├─Options
| | └DependencyInjectionSettingsOptions.cs
| ├─Models
| | └ExternalService.cs
| ├─Extensions
| | └DependencyInjectionServiceCollectionExtensions.cs
| ├─Enums
| | ├─InjectionActions.cs
| | ├─InjectionPatterns.cs
| | └RegisterType.cs
| ├─Dependencies
| | ├─IPrivateDependency.cs
| | ├─IScoped.cs
| | ├─ISingleton.cs
| | ├─ITransient.cs
| | ├─Proxies
| | | └IDispatchProxy.cs
| ├─Attributes
| | ├─InjectionAttribute.cs
| | └SkipScanAttribute.cs
├─DataValidation
| ├─Validators
| | └DataValidator.cs
| ├─Providers
| | └IValidationMessageTypeProvider.cs
| ├─Options
| | └ValidationTypeMessageSettingsOptions.cs
| ├─Models
| | └DataValidationResult.cs
| ├─Filters
| | └DataValidationFilter.cs
| ├─Extensions
| | ├─DataValidationExtensions.cs
| | └DataValidationServiceCollectionExtensions.cs
| ├─Enums
| | ├─ValidationPattern.cs
| | └ValidationTypes.cs
| ├─Attributes
| | ├─DataValidationAttribute.cs
| | ├─NonValidationAttribute.cs
| | ├─ValidationItemMetadataAttribute.cs
| | ├─ValidationMessageAttribute.cs
| | ├─ValidationMessageTypeAttribute.cs
| | └ValidationTypeAttribute.cs
├─DataEncryption
| ├─AESEncryption.cs
| ├─DESCEncryption.cs
| └MD5Encryption.cs
├─DatabaseAccessor
| ├─UnitOfWork
| | ├─Filters
| | | └UnitOfWorkFilter.cs
| | ├─Attributes
| | | ├─NonTransactAttribute.cs
| | | └UnitOfWorkAttribute.cs
| ├─Repositories
| | ├─EFCoreRepository.cs
| | ├─IMSRepository.cs
| | ├─IRepository.cs
| | ├─ISqlRepository.cs
| | ├─MSRepository.cs
| | ├─SqlRepository.cs
| | ├─Implantations
| | | ├─DeletableRepository.cs
| | | ├─InsertableRepository.cs
| | | ├─OperableRepository.cs
| | | ├─ReadableRepository.cs
| | | ├─SqlExecutableRepository.cs
| | | ├─SqlReaderRepository.cs
| | | ├─UpdateableRepository.cs
| | | └WritableRepository.cs
| | ├─Dependencies
| | | ├─IDeletableRepository.cs
| | | ├─IInsertableRepository.cs
| | | ├─IOperableRepository.cs
| | | ├─IReadableRepository.cs
| | | ├─IRepositoryDependency.cs
| | | ├─ISqlExecutableRepository.cs
| | | ├─ISqlReaderRepository.cs
| | | ├─IUpdateableRepository.cs
| | | └IWritableRepository.cs
| ├─Pools
| | ├─DbContextPool.cs
| | └IDbContextPool.cs
| ├─MultiTenants
| | ├─Locators
| | | └MultiTenantDbContextLocator.cs
| | ├─Enums
| | | └MultiTenantOptions.cs
| | ├─Entities
| | | └Tenant.cs
| | ├─Dependencies
| | | ├─IMultiTenantOnDatabase.cs
| | | ├─IMultiTenantOnSchema.cs
| | | ├─IMultiTenantOnTable.cs
| | | └IPrivateMultiTenant.cs
| ├─Models
| | ├─DbProvider.cs
| | ├─PagedList.cs
| | ├─ProcedureOutputResult.cs
| | ├─ProcedureOutputValue.cs
| | ├─SqlTemplate.cs
| | └SqlTemplateParameter.cs
| ├─Locators
| | ├─IDbContextLocator.cs
| | └MasterDbContextLocator.cs
| ├─Interceptors
| | ├─DbContextSaveChangesInterceptor.cs
| | ├─SqlCommandProfilerInterceptor.cs
| | └SqlConnectionProfilerInterceptor.cs
| ├─Helpers
| | └DbHelpers.cs
| ├─Extensions
| | ├─DatabaseAccessorServiceCollectionExtensions.cs
| | ├─PagedQueryableExtensions.cs
| | ├─Repositories
| | | ├─IEntityExtensions.cs
| | | ├─IEntityWithDbContextLocatorExtensions.cs
| | | └SqlExtensions.cs
| | ├─DatabaseProvider
| | | ├─DatabaseProviderServiceCollectionExtensions.cs
| | | └Penetrates.cs
| | ├─DatabaseFacade
| | | ├─DbDataConvertExtensions.cs
| | | ├─DbObjectExtensions.cs
| | | └SqlAdoNetExtensions.cs
| ├─Enums
| | ├─DbFunctionType.cs
| | ├─EFCoreErrorCodes.cs
| | └ManualOptions.cs
| ├─Entities
| | ├─Dependencies
| | | ├─Entity.cs
| | | ├─EntityBase.cs
| | | ├─EntityNotKey.cs
| | | ├─IEntity.cs
| | | └IEntityNotKey.cs
| | ├─Configures
| | | ├─IEntitySeedData.cs
| | | ├─IEntityTypeBuilder.cs
| | | ├─IModelBuilderFilter.cs
| | | └IPrivateModelBuilder.cs
| | ├─Attributes
| | | ├─FakeDeleteAttribute.cs
| | | ├─NonAutomaticAttribute.cs
| | | └QueryableFunctionAttribute.cs
| ├─DynamicModels
| | ├─DynamicModelCacheKeyFactory.cs
| | └IEntityMutableTable.cs
| ├─Contexts
| | ├─AppDbContext.cs
| | ├─Builders
| | | ├─AppDbContextBuilder.cs
| | | ├─Models
| | | | └DbContextCorrelationType.cs
| | ├─Attributes
| | | └AppDbContextAttribute.cs
| ├─Attributes
| | └DbParameterAttribute.cs
| ├─Advances
| | ├─Proxies
| | | └SqlDispatchProxy.cs
| | ├─Models
| | | └SqlProxyMethod.cs
| | ├─Dependencies
| | | └ISqlDispatchProxy.cs
| | ├─Attributes
| | | ├─SqlExecuteAttribute.cs
| | | ├─SqlFunctionAttribute.cs
| | | ├─SqlProcedureAttribute.cs
| | | ├─Basics
| | | | ├─SqlObjectProxyAttribute.cs
| | | | ├─SqlProxyAttribute.cs
| | | | └SqlSentenceProxyAttribute.cs
├─CorsAccessor
| ├─Options
| | └CorsAccessorSettingsOptions.cs
| ├─Extensions
| | ├─CorsAccessorApplicationBuilderExtensions.cs
| | └CorsAccessorServiceCollectionExtensions.cs
├─ConfigurableOptions
| ├─Options
| | └IConfigurableOptions.cs
| ├─Extensions
| | └ConfigurableOptionsServiceCollectionExtensions.cs
| ├─Attributes
| | └OptionsSettingsAttribute.cs
├─Authorization
| ├─Penetrates.cs
| ├─Requirements
| | └AuthorizePolicyRequirement.cs
| ├─Providers
| | └AuthorizePolicyProvider.cs
| ├─Options
| | └JWTSettingsOptions.cs
| ├─Handlers
| | └AuthorizePolicyHandler.cs
| ├─Extensions
| | └PolicyAuthorizationServiceCollectionExtensions.cs
| ├─Attributes
| | └AuthorizePolicyAttribute.cs
├─App
| ├─App.cs
| ├─Startups
| | ├─AppStartup.cs
| | └HostingStartup.cs
| ├─Options
| | └AppSettingsOptions.cs
| ├─Filters
| | └StartupFilter.cs
| ├─Extensions
| | ├─AppApplicationBuilderExtensions.cs
| | ├─AppServiceCollectionExtensions.cs
| | ├─WebHostBuilderExtensions.cs
| | ├─Types
| | | └ObjectExtensions.cs
| ├─Attributes
| | └AppStartupAttribute.cs

1.2.5 Furion.Application 业务应用层

Furion.Application 业务应用层是最常用的层,几乎所有的业务代码都在这个层中编写。

源码结构:

Furion.Application
├─Furion.Application.Core.csproj
├─Furion.Application.Core.xml
└FurApplicationStartup.cs

1.2.6 Furion.Core 仓储实体层

Furion.Core 主要是存储自定义仓储和定义实体的层。

源码结构:

Furion.Core
├─Furion.Core.csproj
└FurCoreStartup.cs

1.2.7 Furion.Database.Migrations 数据库架构维护层

Furion.Database.Migrations 主要是用来存放 Database FirstCode First 生成的维护文件。

源码结构:

Furion.Database.Migrations
└Furion.Database.Migrations.csproj

1.2.8 Furion.EntityFramework.Core 数据库上下文配置层

Furion.EntityFramework.Core 主要是用来配置数据库上下文和其他数据库相关配置信息的。

源码结构:

Furion.EntityFramework.Core
└Furion.EntityFramework.Core.csproj

1.2.9 Furion.Web.Core 应用核心层

Furion.Web.Core 主要是用来配置 Web 入口一些代码,如 FilterMiddlewares 等。

源码结构:

Furion.Web.Core
├─Furion.Web.Core.xml
└FurWebCoreStartup.cs

1.2.10 Furion.Web.Entry 应用入口层

Furion.Web.Entry 是我们的应用层,也就是我们的 Web 项目层,发布层。

源码结构:

Furion.Web.Entry
├─appsettings.Development.json
├─appsettings.json
├─Furion.Web.Entry.csproj
├─Furion.Web.Entry.csproj.user
├─Furion.Web.Entry.xml
├─Program.cs
├─Startup.cs
├─wwwroot
| └README.md
├─Properties
| └launchSettings.json
├─Controllers
- + diff --git a/handbook/build/docs/specification-document/index.html b/handbook/build/docs/specification-document/index.html index 2eb38057a66..46c25fadb20 100644 --- a/handbook/build/docs/specification-document/index.html +++ b/handbook/build/docs/specification-document/index.html @@ -6,7 +6,7 @@ 6. 规范化接口文档 | Furion - + @@ -59,7 +59,7 @@
/// <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,
Successed = false,
Data = null,
Errors = "401 Unauthorized",
Extras = UnifyResultContext.Take()
}, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonSerializerUtility.EnabledPascalPropertyNaming ? null : JsonNamingPolicy.CamelCase
});
break;
// 处理 403 状态码
case StatusCodes.Status403Forbidden:
await context.Response.WriteAsJsonAsync(new RESTfulResult<object>
{
StatusCode = StatusCodes.Status403Forbidden,
Successed = false,
Data = null,
Errors = "403 Forbidden",
Extras = UnifyResultContext.Take()
}, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonSerializerUtility.EnabledPascalPropertyNaming ? null : JsonNamingPolicy.CamelCase
});
break;
default:
break;
}
}
}
}

之后在 Startup.cs 中注册即可:

services.AddControllers()
.AddInjectWithUnifyResult<RESTfulResultProvider>();

6.8 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/split-db/index.html b/handbook/build/docs/split-db/index.html index 6c0f96fbccf..641181da25f 100644 --- a/handbook/build/docs/split-db/index.html +++ b/handbook/build/docs/split-db/index.html @@ -6,7 +6,7 @@ 9.28 分表分库 | Furion - + @@ -29,7 +29,7 @@
// 通过数据库上下文定位器切换
repository.Change<Entity, MyDbContextLocator2>();

如需跨库查询,需用到数据库技术,如 SqlServer 链接服务器或同义词。

  • 动态切换数据库表
// 直接改变表,会有多线程操作bug,同时无法刷新模型
repository.ChangeTable("数据库表");
// 创建新的 DbContext,然后刷新 OnModelCreating(推荐方式)
var dynamicDbContextResolve = App.GetService<Func<Type, IScoped, DbContext>>();
var dynamicDbContext = dynamicDbContextResolve(typeof(MyDbContextLocator), default);
// 重新调用 OnModelCreating,在 OnModelCreating 中配置 ToTable("动态表") 即可。
DynamicModelCacheKeyFactory.RebuildModels();
var persons= dynamicDbContext.Set<Person>();
persons.Add(new Person{});
了解更多

想了解更多 DynamicModelCacheKeyFactory 知识可查阅 EF Core - 多个模型之间交替 章节。

9.28.7 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/docs/template/index.html b/handbook/build/docs/template/index.html index b7e1482ec24..0ec6e4d991c 100644 --- a/handbook/build/docs/template/index.html +++ b/handbook/build/docs/template/index.html @@ -6,7 +6,7 @@ 2.2 官方脚手架 | Furion - + @@ -25,7 +25,7 @@

2.2 官方脚手架

2.2.1 脚手架

Furion 官方提供了多种 Web 应用类型的脚手架,方便大家快速创建多层架构项目。目前支持以下应用脚手架:

模板类型名称版本关键词描述
nugetFurion.Template.Mvcnuget👉 furionmvcMvc 模板
nugetFurion.Template.Apinuget👉 furionapiWebApi 模板
nugetFurion.Template.Appnuget👉 furionappMvc/WebApi 模板
nugetFurion.Template.Razornuget👉 furionrazorRazorPages 模板
nugetFurion.Template.RazorWithWebApinuget👉 furionrazorapiRazorPages/WebApi 模板
nugetFurion.Template.Blazornuget👉 furionblazorBlazor 模板
nugetFurion.Template.BlazorWithWebApinuget👉 furionblazorapiBlazor/WebApi 模板

2.2.2 安装脚手架

打开 CMDPowershell 执行模板安装命令:

dotnet new --install Furion.Template.Mvc::1.1.1

2.2.3 使用脚手架

dotnet new furionmvc -n 项目名称

这样就可以生成项目代码了,生成之后推荐将所有的 nuget 包更新到最新版本。

特别提醒

furionmvc 对应的是上面列表的 关键字,我们也可以通过 dotnet new --list 查看。

想了解更多可以使用 dotnet new 关键字 --help 查看更多参数。

2.2.4 脚手架更新

只需要重新安装最新版替换即可,如:

dotnet new --install Furion.Template.Mvc::1.x.x

不带版本号总是安装最新的版本。

2.2.5 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 模板知识 知识可查阅 dotnet-new 模板 章节。

- + diff --git a/handbook/build/docs/tran/index.html b/handbook/build/docs/tran/index.html index fdb424e2dfc..5958a66554a 100644 --- a/handbook/build/docs/tran/index.html +++ b/handbook/build/docs/tran/index.html @@ -6,7 +6,7 @@ 9.26 事务和工作单元 | Furion - + @@ -37,7 +37,7 @@
// 框架封装的仓储
_testRepository.Insert(new Blog { Url = "http://blogs.msdn.com/dotnet" });
_testRepository.SaveChanges();
// 提交事务
scope.Complete();
}
catch (System.Exception)
{
// 自动回滚
}
}
}

9.26.4 工作单元特性说明

9.26.4.1 [UnitOfWork]

[UnitOfWork] 特性用来标记事务信息,如作用范围,隔离级别等。

  • Enabled:是否启动工作单元,默认 true
  • ScopeOption:定义事务范围行为,默认 TransactionScopeOption.Required
  • IsolationLevel:设置事务隔离级别,默认 IsolationLevel.ReadCommitted;
  • AsyncFlowOption:允许跨线程连续任务的事务流,如有异步操作需开启该选项,默认开启
特别注意

一旦方法贴了 [UnitOfWork(false)] 特性后,那么该方法不再启用工作单元模式,也就是不包含事务,也不会自动提交数据库。慎用!

9.26.5 反馈与建议

与我们交流

给 Furion 提 Issue


了解更多

想了解更多 事务 知识可查阅 EF Core - 使用事务 章节。

- + diff --git a/handbook/build/docs/unittest/index.html b/handbook/build/docs/unittest/index.html index 71a88177381..d4e4de38d08 100644 --- a/handbook/build/docs/unittest/index.html +++ b/handbook/build/docs/unittest/index.html @@ -6,7 +6,7 @@ 27.1 单元测试 | Furion - + @@ -25,7 +25,7 @@
- + diff --git a/handbook/build/docs/view-engine/index.html b/handbook/build/docs/view-engine/index.html index 8570ccb2c10..3290e32ca2e 100644 --- a/handbook/build/docs/view-engine/index.html +++ b/handbook/build/docs/view-engine/index.html @@ -6,7 +6,7 @@ 16. 视图引擎 | Furion - + @@ -30,7 +30,7 @@
var template = _viewEngine.Compile<CustomModel>(content);
var result = template.Run(instance =>
{
instance.A = 10;
instance.B = "Alex";
});

结果:

Hello 10, Alex, -=123=-

16.5 IViewEngine 接口

IViewEngine 提供了简单方便的 RunCompile 方法,也提供了最原始化的 CompileRun 方法。

通过原始的 CompileRun 方法可以实现很多复杂的逻辑和自定义指令集。

/// <summary>
/// 编译模板
/// </summary>
/// <param name="content"></param>
/// <param name="builderAction"></param>
/// <returns></returns>
IViewEngineTemplate Compile(string content, Action<IViewEngineOptionsBuilder> builderAction = null);
/// <summary>
/// 编译模板
/// </summary>
/// <param name="content"></param>
/// <param name="builderAction"></param>
/// <returns></returns>
Task<IViewEngineTemplate> CompileAsync(string content, Action<IViewEngineOptionsBuilder> builderAction = null);
/// <summary>
/// 编译模板
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="content"></param>
/// <param name="builderAction"></param>
/// <returns></returns>
IViewEngineTemplate<T> Compile<T>(string content, Action<IViewEngineOptionsBuilder> builderAction = null)
where T : IViewEngineModel;
/// <summary>
/// 编译模板
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="content"></param>
/// <param name="builderAction"></param>
/// <returns></returns>
Task<IViewEngineTemplate<T>> CompileAsync<T>(string content, Action<IViewEngineOptionsBuilder> builderAction = null)
where T : IViewEngineModel;

16.6 反馈与建议

与我们交流

给 Furion 提 Issue

- + diff --git a/handbook/build/index.html b/handbook/build/index.html index cc52492159b..20e05b4a9d5 100644 --- a/handbook/build/index.html +++ b/handbook/build/index.html @@ -6,7 +6,7 @@ 让 .NET 开发更简单,更通用,更流行。 Furion | Furion - + @@ -21,7 +21,7 @@

Your Docusaurus site did not load properly.

A very common reason is a wrong site baseUrl configuration.

Current configured baseUrl = /furion/

We suggest trying baseUrl =

让 .NET 开发更简单,更通用,更流行。

[object Object]

.NET 5 新起点

.NET 5 是 .NET 的重要且令人兴奋的新方向。你会看到 .NET 变得更加简单,但也有更广泛的功能和实用程序。所有新的开发和功能都将是 .NET 5 的一部分,包括新的 C# 版本

[object Object]

“六极” 架构

Furion 在设计之初就秉承着 “六极” :极易入门、极速开发、极少依赖、极少配置、极其灵活、极易维护 的设计思想,在架构设计上做了大量的优化,支持各个能力阶层技术员极速上手。

[object Object]

冲一杯咖啡的时间

Furion 除了独具创新的设计理念和灵活的架构设计以外,同时还结合了主流的敏捷开发模式打造的一款极速开发框架。只需冲制一杯咖啡的时间便可完成工作

- + diff --git a/handbook/build/runtime~main.45113da2.js b/handbook/build/runtime~main.46b3fd00.js similarity index 78% rename from handbook/build/runtime~main.45113da2.js rename to handbook/build/runtime~main.46b3fd00.js index 2e9fceac175..ea421b507f8 100644 --- a/handbook/build/runtime~main.45113da2.js +++ b/handbook/build/runtime~main.46b3fd00.js @@ -1 +1 @@ -!function(e){function c(c){for(var f,r,t=c[0],n=c[1],o=c[2],u=0,l=[];u