首页 > 编程语言 >ASP.NET Core使用承载启动(HostingStartup)程序集

ASP.NET Core使用承载启动(HostingStartup)程序集

时间:2022-09-25 08:55:17浏览次数:79  
标签:Core ASP ASPNETCORE 配置 程序 HostingStartup using public

概念#

    在ASP.NET Core中我们可以使用一种机制来增强启动时的操作,它就是HostingStartup。如何叫"增强"操作,相信了解过AOP概念的同学应该都非常的熟悉。我们常说AOP使用了关注点分离的方式,增强了对现有逻辑的操作。而我们今天要说的HostingStartup就是为了"增强"启动操作,这种"增强"的操作甚至可以对现有的程序可以做到无改动的操作。例如,外部程序集可通过HostingStartup实现为应用提供配置服务、注册服务或中间件管道操作等。

使用方式#

    HostingStartup属性表示要在运行时激活的承载启动程序集。大致分为两种情况,一种是自动扫描当前Web程序集中通过HostingStartup指定的类,另一种是手动添加配置hostingstartupassembles指定外部的程序集中通过HostingStartup指定的类。第一种方式相对简单,但是对Web程序本身有入侵,第二种方式稍微复杂一点点,但是可以做到对现有代码无入侵操作,接下来我们分别演示这两种使用方式。

ASP.NET Core中直接定义#

首先是在ASP.NET Core程序中直接使用HostingStartup,这种方式比较简单首先在Web程序中随便定义一个类,然后实现IHostingStartup接口,最后别忘了在程序集中添加HostingStartupAttribute指定要启动的类的类型,具体代码如下所示

using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
//通过HostingStartup指定要启动的类型
[assembly: HostingStartup(typeof(HostStartupWeb.HostingStartupInWeb))]
namespace HostStartupWeb
{
    public class HostingStartupInWeb : IHostingStartup
    {
        public void Configure(IWebHostBuilder builder)
        {
            //程序启动时打印依据话,代表执行到了这里
            Debug.WriteLine("Web程序中HostingStartupInWeb类启动");

            //可以添加配置
            builder.ConfigureAppConfiguration(config => {
                //模拟添加一个一个内存配置
                var datas = new List<KeyValuePair<string, string>>
                {
                    new KeyValuePair<string, string>("ServiceName", "HostStartupWeb")
                };
                config.AddInMemoryCollection(datas);
            });

            //可以添加ConfigureServices
            builder.ConfigureServices(services=> {
                //模拟注册一个PersonDto
                services.AddScoped(provider=>new PersonDto { Id = 1, Name = "yi念之间", Age = 18 });
            });

            //可以添加Configure
            builder.Configure(app => {
                //模拟添加一个中间件
                app.Use(async (context, next) =>
                {
                    await next();
                });
            });
        }
    }
}

仅仅使用上面所示的这些代码,便可在Web程序启动的时候去自动执行HostingStartupInWeb的Configure方法,在这里面我们几乎可以使用所有针对ASP.NET Core程序配置的操作,而且不需要在Web程序中额外添加别的代码就可以自动调用HostingStartupInWeb的Configure方法。

外部程序集引入#

我们之前也说过,上面的方式虽然使用起来相对简单一点,仅仅是一点,那就是省去了指定启动程序集的逻辑。但是,上面的方式需要在Web程序中添加,这样的话还是会修改代码。而且,可能更多的时候我们是在外部的程序集中编写HostingStartup逻辑,这时候就需要使用另一种方式在将外部程序集中引入HostingStartup。首先我们要在自定义的程序集中至少引入Microsoft.AspNetCore.Hosting包才能使用HostingStartup

<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />

如果你不需要使用注册中间件的逻辑那么仅仅引入Microsoft.AspNetCore.Hosting.Abstractions即可

<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />

如果需要使用其他功能包,可以自行在定义的程序集中引入。比如我们定义了一个名为HostStartupLib的Standard类库,并创建了名为HostStartupLib的类

using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
[assembly: HostingStartup(typeof(HostStartupLib.HostingStartupInLib))]
namespace HostStartupLib
{
    public class HostingStartupInLib : IHostingStartup
    {
        public void Configure(IWebHostBuilder builder)
        {
            Debug.WriteLine("Lib程序中HostingStartupInLib类启动");

            //添加配置
            builder.ConfigureAppConfiguration((context, config) => {
                var datas = new List<KeyValuePair<string, string>>
                {
                    new KeyValuePair<string, string>("ServiceName", "HostStartupLib")
                };
                config.AddInMemoryCollection(datas);
            });

            //添加ConfigureServices
            builder.ConfigureServices(services=> {
                services.AddScoped(provider=>new PersonDto { Id = 2, Name = "er念之间", Age = 19 });
            });

            //添加Configure
            builder.Configure(app => {
                app.Use(async (context, next) =>
                {
                    await next();
                });
            });

        }
    }
}

然后我们将自定义的HostStartupLib这个Standard类库引入Web项目中,运行Web程序,发现HostingStartupInLib的Configure方法并不能被调用。其实我们上面说过了,将HostingStartup从外部程序集引入的话需要手动指定启动程序集的名称。指定启动程序集的方式有两种,一种是指定IWebHostBuilder的扩展UseSetting指定

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    //通过UseSetting的方式指定程序集的名称
                    webBuilder.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "HostStartupLib");
                    //如果HostingStartup存在多个程序集中可以使用;分隔,比如HostStartupLib;HostStartupLib2
                    //webBuilder.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "HostStartupLib;HostStartupLib2");
                    webBuilder.UseStartup<Startup>();
                });

另一种通过添加环境变量ASPNETCORE_HOSTINGSTARTUPASSEMBLIES的方式,可以通过设置launchSettings.json中

"environmentVariables": {
        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "HostStartupLib"
        //如果HostingStartup存在多个程序集中可以使用;分隔,比如HostStartupLib;HostStartupLib2
        //"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "HostStartupLib;HostStartupLib2"
}

    可以引入多个包含HostingStartup的程序集,在设置WebHostDefaults.HostingStartupAssembliesKey或者ASPNETCORE_HOSTINGSTARTUPASSEMBLIES指定多个程序集名称可以使用英文分号(;)隔开程序集名称。虽然是两种形似指定,但是其实本质是一样的那就是设置配置key为hostingStartupAssemblie配置的值,下面我们会详细讲解。
    通过在程序中设置环境变量的方式等同于Window系统中Set的方式设置环境变量,或Linux系统中export的方式设置环境变量,亦或是直接设置系统环境变量,效果都是一致的。指定完成启动程序集之后,再次运行程序便可以看到HostingStartupInLib的Configure方法被调用到了。在这里我们可以看到如果是使用的环境变量的方式去指定启动程序集的话,对现有代码可以做到完全无入侵。

源码探究#

在上面我们简单的介绍了HostingStartup的概念及基本的使用方式,基于这些我们产生了几个疑问

  • 首先是关于HostingStartup的基本工作方式是什么
  • 其次是为什么HostingStartup在Web程序中不需要配置程序集信息就可以被调用到,而通过外部程序集引入HostingStartup需要手动指定程序集
  • 最后是通过外部程序集引入HostingStartup的指定方式为何只能是UseSetting和环境变量的方式
    基于以上几个疑问,我们来探索一下HostingStartup的相关源码,来揭开它的神秘面纱。首先废话不多说直接找到源码位置[点击查看源码

    标签:
    Core,ASP,ASPNETCORE,配置,程序,HostingStartup,using,public
    From: https://www.cnblogs.com/hjwcore/p/16727224.html

相关文章

  • ASP.NET Core – Try Preview
    前言.NET7已经来到RC阶段了.通常RC就是我们(写库的人)要入场的时候了.有发现Bug要尽可能在这段期间提交.不然后患无穷.这篇主要就是来讲讲如果测试RC版本......
  • coredump快速定位
    https://utcc.utoronto.ca/~cks/space/blog/linux/KernelSegfaultMessageMeaningWhattheLinuxkernel'smessagesaboutsegfaultingprogramsmeanon64-bitx86Feb......
  • TAD calling 之 insulation score 分析
    1.导读本文主要对insulationscore的提出与计算方法进行简要的介绍,并展示一个计算insulationscore的过程。2.定义insulationscore是dekker实验室在2015年发表于N......
  • net core 使用 Npoi 生成 Word文档
    需求:按数据层级生成WORD文件,要有目录,目录里要有真实的页码,附件内容用表格显示,大标题 做为封面当独显示一页,PDF内容大标题,目录(里有对应的页码)正文 里有表格重点:NPOI......
  • <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs&
    https://www.cnblogs.com/ChineseMoonGod/archive/2013/06/07/3123907.html<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="Default.aspx.cs"Inherits="_Defa......
  • NetCore Swagger 多版本
    1.版本枚举///<summary>///swagger多版本枚举///</summary>publicenumSwaggerVersionEnum{///<summary>///V1版本,......
  • CAP事件总线在NetCore中的应用
    在前面的文章中,我们介绍过Abp自带的本地事件总线,但它有几点不足1:缺乏失败重试机制,即若发布事件失败或者订阅事件处理失败,他没有重试机制,导致业务和数据异常。2:缺乏对存......
  • EFCore——想查关联数据,不使用外键的实现方式
    EFCore中如何移除主外键关系-走看看(zoukankan.com)EFCore迁移命令移除外键-i没昵称-博客园(cnblogs.com)......
  • .NET Core Web APi类库如何内嵌运行?
    话题我们知道在.NETFramework中可以嵌入运行WebAPi,那么在.NETCore(.NET6+称之为.NET)中如何内嵌运行WebApi呢,在实际项目中这种场景非常常见,那么我们本节以.NET6.0作为......
  • 黑苹果OpenCore 卡
     建议拔掉USB设备,制作好的苹果安装盘放到USB2.0上启动遇到卡在这块是因为我本机插了一个罗技的USB鼠标,拔掉之后就过去了(甚至不用重启系统)具体错误信息:...GTrace......