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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OrchardCore 如何实现模块化( Modular )和 Multi-Tenancy

發布時間:2023/12/4 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OrchardCore 如何实现模块化( Modular )和 Multi-Tenancy 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、概述

通常我們會在?Startup?類通過?void ConfigureServices(IServiceCollection services)?配置應用的服務。常見的形如 AddXXX 的方法,實際上調用的都是?IServiceCollection?或直接說是?ServiceCollection?的 AddSingleton 等方法。調用ApplicationBuilder?的?RequestDelegate Build()?方法會調用?IServiceCollection?的擴展方法?BuildServiceProvider?會創建并返回一個 ServiceProvider 對象。
還會在?Startup?類通過?void Configure(IApplicationBuilder app, IHostingEnvironment env)?配置請求管道,在該方法內進行的主要操作是添加中間件。常見的形如 UseMiddleware 或 UseXXX 的方法,實際上調用的都是?IApplicationBuilder?或直接說是?ApplicationBuilder?的?IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)?方法,Use 方法并不是馬上將中間件配置入請求管道,而是將“實例化中間件的方式”保存到 ApplicationBuilder 內部一個列表的操作。調用ApplicationBuilder?的?RequestDelegate Build()?方法會實例化中間件并把各個中間件串聯起來。

OrchardCore?通過將服務和中間件放在不同的程序集以支持模塊化。各個模塊提供類似于 ConfigureServices 和 Configure 的方法供運行時調用。

OrchardCore?還支持?Multi-Tenancy。Tenant?有如下特性:

  • 多個 Tenant 運行在同一個應用程序域中,每個 Tenant 幾乎可以看做是獨立的網站;

  • 根據 Host 、Port 和 Path 的各種組合匹配不同的 Tenant(ModularTenantContainerMiddleware);

  • 延遲激活,第一次請求 Tenant 才會激活(ModularTenantContainerMiddleware);

  • 每個 Tenant 有不同的 DI 容器(ModularTenantContainerMiddleware);

  • 每個 Tenant 有不同的請求管道,可以共享中間件,還可以使用特定中間件(ModularTenantRouterMiddleware)。

  • 二、模塊定義

    模塊是依賴于?OrchardCore.Modules.Targets?程序集的程序集,可以有各自的配置、選項、DI 服務和中間件等,還可以有各自的路由、視圖、控制器、 Filter 和 ModelBinder 等,看起來像是一個 MVC?Area。
    模塊包含 0 或多個?Feature?。Feature 是功能的邏輯組合,可單獨開啟或禁用。
    Feature 之間可有依賴關系,并且支持跨模塊的依賴。

    備注:
    OrchardCore 中,一個程序集只包含一個模塊。
    模塊可以看做是特殊的 Feature 。
    用于定義?Theme?的?OrchardCore.Theme.Targets?程序集也依賴于?OrchardCore.Modules.Targets?程序集。

    1、Mainifest.cs 文件

    模塊有個以程序集特性的形式嵌入程序集中的?Mainifest?,用于描述模塊的基本信息、擁有的?Feature?和依賴的其他?Feature?等。一般寫在?Mainifest.cs?文件中,比如:


    using OrchardCore.Modules.Manifest;
    [assembly: Module(
    ?Name = "XML-RPC",
    ?Author = "The Orchard Team",
    ?Website = "http://orchardproject.net",
    ?Version = "2.0.0"
    )]
    [assembly: Feature(
    ?Id = "OrchardCore.XmlRpc",
    ?Name = "XML-RPC",
    ?Description = "The XML-RPC module enables creation of contents from client applications such as Open Live Writer.",
    ?Category = "Infrastructure"
    )]
    [assembly: Feature(
    ?Id = "OrchardCore.RemotePublishing",
    ?Name = "Remote Publishing",
    ?Description = "The remote publishing feature enables creation of contents from client applications such as Open Live Writer.",
    ?Dependencies = new [] { "OrchardCore.XmlRpc" },
    ?Category = "Infrastructure"
    )]

    在運行時可將 Mainifest 讀取至?MainifestInfo?對象中。
    ModuleAttribure?用于描述模塊基本信息,只能用于程序集并且只能使用一次,在運行時可讀取至 ModuleInfo 對象中。
    一個模塊可以包含 0 或多個 Feature 。FeatureAttribure?用于描述模塊提供的 Feature,只能用于程序集并且可以使用多次,在運行時可讀取至 FeatureInfo 對象中。

    備注:ModuleAttribute 繼承自 FeatureAttribute ,都位于OrchardCore.Abstractions程序集、OrchardCore.Modules.Manifest命名空間中。

    從類或對象來看,1 個 MainifestInfo 對象包含1個 ModuleInfo 對象,1 個 ModuleInfo 對象包含 0 或多個 FeatureInfo 對象。

    2、ManifestInfo 和 FeatureInfo 類

    ExtensionManager類用于獲取 Mainifest ,并將相關數據反序列化入 ManifestInfo 和 FeatureInfo對象中。

    3、ModuelNameAttribute 類

    如果一個項目引用了一些模塊,MSBuild 在生成項目時會針對每個模塊添加一個程序集級的 ModuleNameAttrbute ,用于保存引用的模塊名稱。
    AssemblyAttributeModuleNamesProvider 類的?IEnumerable<string> GetModuleNames()?方法能夠收集到 ModuleNameAttrbute 。

    備注:AssemblyAttributeModuleNamesProvider 位于OrchardCore.Abstractions程序集、OrchardCore.Modules命名空間中。

    4、ModuleMarkerAttribute 類

    MSBuild 在生成模塊的項目時會自動添加程序集級的 ModuleMarkerAttribute 。ModuleMarkerAttribute 繼承 ModuleAttribute),位于OrchardCore.Abstractions程序集、OrchardCore.Modules.Manifest命名空間中

    5、ModuleAssetAttribute類

    MSBuild 在生成模塊的項目時會自動添加程序集級的 ModuleAssetAttribute。ModuleAssetAttribute繼承 ModuleAttribute),位于OrchardCore.Abstractions程序集、OrchardCore.Modules.Manifest命名空間中

    6、Module 類

    在創建 Module 對象時,傳入模塊程序集的名稱,構造函數會通過 Assembly.Load 加載模塊程序集,并且收集模塊的 ModuleAttribute、ModuleAssetAttribute 和 ModuleMarkerAttribute 放入自身屬性中。

    注意:這里說的是 Module 類不是 ModuleAttribute 類。

    備注:ModularApplicationContext 位于 OrchardCore.Abstractions程序集、OrchardCore.Modules命名空間中。

    7、IStartup 接口

    每個模塊可能需要注冊一些服務至 DI 容器中,也可能需要注冊一些中間件。OrchardCore 定義了一個?OrchardCore.Modules.IStartup, OrchardCore.Modules.Abstractions?接口,以及實現了該接口的?OrchardCore.Module s.StartupBase, sOrchardCore.Modules.Abstractions?抽象類。OrchardCore 模塊通常有一個?Startup.cs?文件,實現了繼承自?SetupBase?抽象類的名為?Startup?的具體類。

    注意:OrchardCore 的?Startup?類不是指通常 ASP.NET Core 中的那個類,IStartup?接口也不是通常 ASP.NET Core 中的那個接口,盡管它們的確很相似。

    通常,對于 ASP.NET Core 應用的 Startup 類我們不直接實現 IStartup 接口,而采用更靈活的基于方法名約定的方式。另外,通過 IHostingStartup(承載啟動)實現,在啟動時從外部程序集向應用添加增強功能。但是使用 IHostingStartup 無法控制各個模塊注冊服務和添加中間件的順序,也不支持延遲加載。
    OrchardCore.Modules.IStartup,OrchardCore.Modules.Abstractions?相較于?Microsoft.AspNetCore.Hosting.IStartup,Microsoft.AspNetCore.Hosting.Abstractions?多了個?Order?屬性,并且前者的 Configure 方法簽名為void Configure(IApplicationBuilder app, IRouteBuilder routes, IServiceProvider serviceProvider),后者為?void Configure(IApplicationBuilder app)。因為模塊通常位于不同的程序集, Order 屬性的作用是控制向 DI 容器注冊服務、添加中間件、添加配置和添加路由的順序。

    備注:void Configure(IApplicationBuilder app, IRouteBuilder routes, IServiceProvider serviceProvider)?的 routes 和 serviceProvier 是為了支持模塊化和?Multi-Tenancy。

    三、模塊引擎

    事實上沒有一種明確的組件叫模塊引擎。OrchardCore 提供了一些由于支持模塊的基礎設施,并提供將分散于各個模塊的服務收集起來注冊至 DI 容器,以及中間件添加至請求管道的機制。

    1、AddOrchardCore

    AddOrchardCore 不準確地說就是將服務注冊至 DI 容器中以及將中間件添加至請求管道的,并返回一個 OrchardCoreBuilder 對象。
    OrchardCoreBuilder 嚴格來說不是生成器模式,它類似于 Startup 類有 ConfigureServices 和 Configure方法。但是當調用這兩類方法時,并不是直接將服務注冊到 DI 容器中或注冊中間件,而是將注冊的方式通過委托保存在集合中(通過 StartupAction )。這樣做的目的是為了將來給每個 Tenant 注冊這些服務和中間件。


    /// <summary>
    /// Adds OrchardCore services to the host service collection.
    /// </summary>
    public static OrchardCoreBuilder AddOrchardCore(this IServiceCollection services)
    {
    ? ?// If an instance of OrchardCoreBuilder exists reuse it,
    ? ?// so we can call AddOrchardCore several times.
    ? ?var builder = services
    ? ? ? ?.LastOrDefault(d => d.ServiceType == typeof(OrchardCoreBuilder))?
    ? ? ? ?.ImplementationInstance as OrchardCoreBuilder;
    ? ?if (builder == null)
    ? ?{
    ? ? ? ?builder = new OrchardCoreBuilder(services);
    ? ? ? ?services.AddSingleton(builder);

    ? ? ? ?AddDefaultServices(services);
    ? ? ? ?AddShellServices(services);
    ? ? ? ?AddExtensionServices(builder);

    ? ? ? ?AddStaticFiles(builder);

    ? ? ? ?AddAntiForgery(builder);
    ? ? ? ?AddAuthentication(builder);
    ? ? ? ?AddDataProtection(builder);

    ? ? ? ?// Register the list of services to be resolved later on
    ? ? ? ?services.AddSingleton(services);
    ? ?}
    ? ?return builder;
    }

    ① AddDefaultServices

    添加默認服務,比如 Logging、Localization 和 Web Encoders (Web Encoders 是指 Html、Url 和 Javascript 的編碼器)。
    重要的是添加 Routing 服務。IServiceCollection 的擴展方法 AddMvc/AddMvcCore 會添加 Routing 服務。就算不是 MVC 應用也可以是使用路由,并且 OrchardCore 的路由可配置在不同的模塊,所以在這里注冊是因為后續會使用 Routing 相關服務。

    ② AddShellServices

    添加用于支持 Tenant 的相關服務。Shell 涉及眾多的類,這里暫時不分析。

    ③ AddExtensionServices

    添加用于支持模塊化的相關服務。主要是?AssemblyAttributeModuleNamesProvider : IModuleNamesProvider?和?ModularApplicationContext : IApplicationContext?。
    AssemblyAttributeModuleNamesProvider 提供了一種從程序集的 Attribute 獲取模塊名稱的方式。
    ModularApplicationContext 提供了一個?OrchardCore.Modules.Application?對象,可在某些情況下指代應用。使用 ModularApplicationContext 的屬性 Application 時,會觸發 Application 對象的構造過程。

    ④ AddStaticFiles

    添加靜態文件服務中間件,主要是增加 ModuleEmbeddedStaticFileProvider 的支持。

    ⑤ AddAntiForgery

    主要是提供對 Multi-Tenancy 的支持。為不同的 Tenant 的 Antiforgery Cookie 設置的名稱和路徑。

    ⑥ AddAuthentication

    主要是提供對 Multi-Tenancy 的支持。

    ⑦ AddDataProtection

    主要是提供對 Multi-Tenancy 的支持。

    2、AddMvc

    AddMvc 主要作用是添加和 Mvc 相關的中間件。請注意這是 OrchardBuilder 而不是 IServiceCollection 的擴展方法。
    類似的方法 AddNancy 用于提供對?Nancy?的支持。

    3、UseOrchardCore

    UseOrchardCore?是一個?IApplicationBuilder?的擴展方法,主要作用是添加中間件 ModularTenantContainerMiddleware 和 ModularTenantRouterMiddleware 。


    namespace Microsoft.AspNetCore.Builder
    {
    ?public static class ApplicationBuilderExtensions
    ?{
    ? ? ? /// <summary>
    ? ? ? /// Enables multi-tenant requests support for the current path.
    ? ? ? /// </summary>
    ? ? ? public static IApplicationBuilder UseOrchardCore(this IApplicationBuilder app, Action<IApplicationBuilder> configure = null)
    ? ? ? {
    ? ? ? ? ? var env = app.ApplicationServices.GetRequiredService<IHostingEnvironment>();
    ? ? ? ? ? var appContext = app.ApplicationServices.GetRequiredService<IApplicationContext>();
    ? ? ? ? ? env.ContentRootFileProvider = new CompositeFileProvider(
    ? ? ? ? ? ? ? new ModuleEmbeddedFileProvider(appContext),
    ? ? ? ? ? ? ? env.ContentRootFileProvider);
    ? ? ? ? ? app.UseMiddleware<PoweredByMiddleware>();
    ? ? ? ? ? // Ensure the shell tenants are loaded when a request comes in
    ? ? ? ? ? // and replaces the current service provider for the tenant's one.
    ? ? ? ? ? app.UseMiddleware<ModularTenantContainerMiddleware>();
    ? ? ? ? ? configure?.Invoke(app);
    ? ? ? ? ? app.UseMiddleware<ModularTenantRouterMiddleware>();
    ? ? ? ? ? return app;
    ? ? ? }
    ?}
    }

    四、Multi-Tenancy

    在 ModularTenantContainerMiddleware 中間件中,根據 Host 、Port 和 Path 的各種組合匹配不同的 Tenant 。Tenant 的激活延遲性的,在第一次請求 Tenant 才會激活。每個 Tenant 可以有不同的 DI 容器。

    在 ModularTenantRouterMiddleware 中間件中,為當前 Tenant 配置單獨的請求管道。

    五、服務和中間件注冊點

    總結一下目前為止遇見的服務和中間件注冊點。

    1、服務注冊點

    包含名為 ConfigureServices 或類似的方法的接口和類:

    類/接口程序集命名空間備注
    IStartupMicrosoft.AspNetCore.Hosting.AbstractionsMicrosoft.AspNetCore.Hosting接口。
    IStartupMicrosoft.AspNetCore.Hosting.AbstractionsMicrosoft.AspNetCore.Hosting接口。
    Startup自定義自定義定義于應用。不繼承任何接口或類,實現 Configure 和 ConfigureServices 等方法。
    IWebHostBuilderMicrosoft.AspNetCore.Hosting.Abstractions接口。
    WebHostBuilder : IWebHostBuilderMicrosoft.AspNetCore.HostingMicrosoft.AspNetCore.HostingConfigureServices 不會進行實際的服務注冊操作,當調用 Build 方法時才注冊。
    IStartupOrchardCore.Modules.AbstractionsOrchardCore.Modules接口。
    StartupBase: IStartupOrchardCore.Modules.AbstractionsOrchardCore.Modules抽象類。
    Startup: SetupBase自定義自定義定義于 OrchareCore 模塊。
    OrchardCoreBuilderOrchardCore .Modules.AbstractionsMicrosoft.Extensions.DependencyInjection注冊 Tenant 服務和中間件。
    StartupActionsOrchardCore.Modules.AbstractionsMicrosoft.Extensions.DependencyInjection包含 ConfigureServicesActions 屬性,而非方法。

    2、中間件注冊點

    包含名為 Configure 或類似方法的接口和類:

    類/接口程序集命名空間備注
    IStartupMicrosoft.AspNetCore.Hosting.AbstractionsMicrosoft.AspNetCore.Hosting接口。
    IHostingStartupMicrosoft.AspNetCore.Hosting.AbstractionsMicrosoft.AspNetCore.Hosting接口。
    HostingStartup:IHostingStartup自定義自定義定義于應用。
    Startup自定義自定義定義于應用。不繼承任何接口或類,實現 Configure 和 ConfigureServices 等方法。
    IWebHostBuilderMicrosoft.AspNetCore.Hosting.Abstractions接口。
    WebHostBuilder : IWebHostBuilderMicrosoft.AspNetCore.HostingMicrosoft.AspNetCore.HostingConfigure 不會進行實際的添加注冊操作,當調用 Build 方法時才注冊。
    IStartupOrchardCore.Modules.AbstractionsOrchardCore.Modules接口。
    StartupBase: IStartupOrchardCore.Modules.AbstractionsOrchardCore.Modules抽象類。
    Startup: SetupBase自定義自定義定義于 OrchareCore 模塊。
    OrchardCoreBuilderOrchardCore .Modules.AbstractionsMicrosoft.Extensions.DependencyInjection注冊 Tenant 服務和中間件。
    StartupActionsOrchardCore.Modules.AbstractionsMicrosoft.Extensions.DependencyInjection包含 ConfigureActions 屬性,而非方法。
    IStartupFilterMicrosoft.AspNetCore.Hosting.AbstractionsMicrosoft.AspNetCore.Hosting定義于應用或 OrchareCore 模塊。需注冊為服務。

    參考資料

    https://orchardcore.readthedocs.io/en/latest/
    http://docs.orchardproject.net/en/latest/
    https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/startup?view=aspnetcore-2.1
    https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/host/platform-specific-configuration?view=aspnetcore-2.1
    https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/host/web-host?view=aspnetcore-2.1

    原文地址: https://www.cnblogs.com/alby/p/orchardcore-modular-and-multi-tenancy.html


    .NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com

    總結

    以上是生活随笔為你收集整理的OrchardCore 如何实现模块化( Modular )和 Multi-Tenancy的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。