日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OrchardCore 如何动态加载模块?

發(fā)布時(shí)間:2023/12/4 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OrchardCore 如何动态加载模块? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
【導(dǎo)讀】今天,我們再次討論下OrchardCore,通過初期調(diào)研,我們項(xiàng)目采用OrchardCore底層設(shè)施支持模塊化,同時(shí)根據(jù)業(yè)務(wù)場景,額外還需支持二次開發(fā),于是有了本文,若有不同解決方案,歡迎留言探討

若對OrchardCore有所了解的童鞋應(yīng)該知道,OrchardCore本身定位于CMS系統(tǒng),同時(shí)整個(gè)架構(gòu)并非前后分離,采用MVC模式開發(fā),基于此,由于內(nèi)置需要預(yù)編譯視圖以及考慮其他等等原因,不支持動態(tài)加載模塊,本文給出我所想到的動態(tài)加載模塊方案

OrchardCore基本使用示例

OrchardCore采用包管理各個(gè)模塊,所以有自建NuGet,我們提前配置好OrchardCore程序包源

項(xiàng)目采用前后分離,所以我們創(chuàng)建WebAPi應(yīng)用程序,為支持模塊化開發(fā),如上圖下載模塊開發(fā)應(yīng)用程序包

緊著在Startup文件中,添加OrchardCore服務(wù)以及使用其中間件,如下圖

至此一個(gè)基本的模塊化項(xiàng)目就創(chuàng)建完畢,接下來我們創(chuàng)建模塊,官方提供模塊包模板引擎

通過對應(yīng)命令將模板引擎下載至本地

?dotnet?new?-i?OrchardCore.ProjectTemplates::1.0.0-rc2-16113?--nuget-source?https://nuget.cloudsmith.io/orchardcore/preview/v3/index.json

然后我們在項(xiàng)目解決方案下,繼續(xù)通過CLI將下載至本地模板引擎來創(chuàng)建模塊項(xiàng)目,并引入到項(xiàng)目解決方案中

dotnet?new?ocmodulecms?-n?Test

由于我們用不到視圖,所以將視圖文件夾以及對應(yīng)默認(rèn)安裝包刪除,只需保留如下模塊包就好

OrchardCore.Module.Targets

同時(shí)也一并將項(xiàng)目文件中支持MVC配置給刪除,否則會生成視圖程序集,猜測應(yīng)該會引起模塊加載依賴需額外加載視圖dll

我們將模塊默認(rèn)創(chuàng)建控制器修改為訪問接口形式,方便接下來測試驗(yàn)證

那么接下來我們應(yīng)該如何將開發(fā)好的模塊進(jìn)行加載呢?

OrchardCore動態(tài)加載模塊(前后分離)

了解OrchardCore基本原理的我們應(yīng)該知道,默認(rèn)情況下,主項(xiàng)目添加模塊引用時(shí),會通過MSBuild在對應(yīng)模塊程序集中,添加模塊標(biāo)識,如下:

如上圖所示,一個(gè)是模塊標(biāo)識,一個(gè)是對應(yīng)文件路徑標(biāo)識

當(dāng)啟動主項(xiàng)目時(shí),會找到對應(yīng)程序集模塊標(biāo)識,并注冊服務(wù)以及其他操作,如此看來,我們只需深入了解源碼中是否存在存儲對應(yīng)模塊信息的接口呢?

查看底層模塊設(shè)施源碼,得知對外暴露其接口即IModuleNamesProvider

好家伙,我們將生成模塊dll放在主項(xiàng)目程序啟動modules目錄下,接下來我們實(shí)現(xiàn)該接口,如下:

public?class?DynamicModuleNamesProvider?:?IModuleNamesProvider {private?readonly?List<string>?_moduleNames?=?new?List<string>();public?DynamicModuleNamesProvider(){var?baseDirectory?=?AppContext.BaseDirectory;var?location?=?Path.Combine(baseDirectory,?"modules");if?(!Directory.Exists(location)){return;}foreach?(var?file?in?Directory.EnumerateFiles(location)){var?assemblyPath?=?Path.Combine(location,?file);var?assembly?=?Assembly.LoadFrom(assemblyPath);_moduleNames.AddRange(assembly.GetCustomAttributes<ModuleMarkerAttribute>().Select(m?=>?m.Name));}}public?IEnumerable<string>?GetModuleNames(){return?_moduleNames;} }

將其以單例形式注入,如下

services.AddSingleton<IModuleNamesProvider,?DynamicModuleNamesProvider>();

我們啟動主項(xiàng)目驗(yàn)證確認(rèn),模塊已然進(jìn)行加載,如下:

但是訪問控制器接口卻顯示404

并未繼續(xù)深入查看源碼,至少可知,通過動態(tài)加載內(nèi)置僅僅只注冊了相關(guān)服務(wù),猜測是和移除對應(yīng)視圖包有關(guān)導(dǎo)致并未激活控制器、視圖等等

OrchardCore動態(tài)加載模塊激活控制器

由于控制器、視圖、TagHelper等等相關(guān)FeatureProvider并未激活,所以我們借助AssemblyPart來實(shí)現(xiàn),將其作為應(yīng)用程序的一部分,通過掃描模塊,將對應(yīng)控制器等激活,如下:

var?builders?=?services.AddControllers();builders.ConfigureApplicationPartManager(apm?=> {var?baseDirectory?=?AppContext.BaseDirectory;var?location?=?Path.Combine(baseDirectory,?"modules");if?(!Directory.Exists(location)){return;}foreach?(var?file?in?Directory.EnumerateFiles(location)){var?assemblyPath?=?Path.Combine(location,?file);var?assembly?=?AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyPath);var?assemblyPart?=?new?AssemblyPart(assembly);apm.ApplicationParts.Add(assemblyPart);} });

?????雖然官方并未提供動態(tài)加載模塊示例,但我們依然可以借用其對外暴露接口來實(shí)現(xiàn),理論上若是采用MVC模式,應(yīng)該也可以進(jìn)行動態(tài)加載

總結(jié)

以上是生活随笔為你收集整理的OrchardCore 如何动态加载模块?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。