asp.net core入门之Startup

转自:饭勺oO

cnblogs.com/fanshaoO/p/17577568.html

Startup介绍#

Startup是Asp.net Core的应用启动入口。在.NET5及之前一般会使用startup.cs类进行程序初始化构造。如下:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }


    public IConfiguration Configuration { get; }


    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }


    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }


        app.UseHttpsRedirection();
        app.UseStaticFiles();


        app.UseRouting();


        app.UseAuthorization();


        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }
}

并在Program中使用IHostBuilder构造Host程序:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }


    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

在.NET5之后的版本中,简化了这一操作(当然也可以继续保留这种方式),我们可以直接在Program的程序入口Main函数中直接构造配置我们的Startup,或者直接使用顶级语句的方式,在Program类中直接编写。

var builder = WebApplication.CreateBuilder(args);


// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();


var app = builder.Build();


// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}


app.UseHttpsRedirection();
app.UseStaticFiles();


app.UseAuthorization();


app.MapGet("/hi", () => "Hello!");


app.MapDefaultControllerRoute();
app.MapRazorPages();


app.Run();

对比之下,很容易发现,其中在var app = builder.Build();之前的代码这是做我们应用的初始化,比如依赖注入,配置加载等等操作,相当于Startup.cs中的ConfigureServices方法。
对应的,下面的操作就是我们的中间件配置,对应Startup.cs中的Configure方法。
同时我们可以发现,在新版的中间件配置中,少了UseRouting和UseEndpoints用来注册路由的中间件,是因为使用最小托管模型时,终结点路由中间件会包装整个中间件管道,因此无需显式调用 UseRouting 或 UseEndpoints 来注册路由。UseRouting 仍可用于指定进行路由匹配的位置,但如果应在中间件管道开头匹配路由,则无需显式调用 UseRouting。
app.MapRazorPages(); 就相当于
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});


扩展Startup#

在asp.net core中有一个IStartupFilter的接口,用于扩展Startup。
IStartupFilter 在不显式注册默认中间件的情况下将默认值添加到管道的开头。
IStartupFilter 实现 Configure,即接收并返回 Action。IApplicationBuilder 定义用于配置应用请求管道的类。
每个 IStartupFilter 可以在请求管道中添加一个或多个中间件。筛选器按照添加到服务容器的顺序调用。筛选器可在将控件传递给下一个筛选器之前或之后添加中间件,从而附加到应用管道的开头或末尾。

我们来实践一下,首先创建一个空的asp.net core模板很简单,只有一个Program文件。
9bedcf10722d9340fddb42a0887296b7.png

再来添加一个IStartupFilter的实现,只用于控制台输出执行内容。

using Microsoft.AspNetCore.Hosting;


namespace LearnStartup
{
    public class StartupFilterOne : IStartupFilter
    {
        public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
        {
            return builder => 
            {
                builder.Use(async (httpContext, _next) => 
                {
                    Console.WriteLine("-----StartupFilterOne-----");
                    await _next(httpContext);
                });
                next(builder);
            };
        }
    }
}

在Program中添加一行代码注册StartupFilterOne

using LearnStartup;


var builder = WebApplication.CreateBuilder(args);


builder.Services.AddTransient<IStartupFilter, StartupFilterOne>(); //注入StartupFilterOne


var app = builder.Build();


app.MapGet("/", () => "Hello World!");


app.Run();

启动程序,可以看到如下结果,中间件正常执行:
463937c54307f4a9d22e34cd89cf1628.png

当我们有多个IStartupFilter时,我们怎么控制中间件执行顺序呢?上面所说,跟我们注入的顺序有关。
新增一个StartupFilterTwo,在修改一下Program

using LearnStartup;


var builder = WebApplication.CreateBuilder(args);


builder.Services.AddTransient<IStartupFilter, StartupFilterTwo>();
builder.Services.AddTransient<IStartupFilter, StartupFilterOne>();


var app = builder.Build();


app.MapGet("/", () => "Hello World!");


app.Run();

可以看到是先执行StartupFilterTwo中的中间件,然后再执行StartupFilterOne的中间件。
1236514ee8b4cecca4f1a37cb1eafb0b.png
以上写法都是把中间件注册在中间件管道头部,那么如何让他在尾部执行呢?
在IStartupFilter.Configure(Action next)中的参数next,本质其实就是Startup中的Configure(感兴趣可以翻源码查看),只要调整next的执行顺序即可。
我们调整一下StartupFilterTwo的代码

public class StartupFilterTwo : IStartupFilter
    {
        public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
        {
            return builder =>
            {
                next(builder);
                builder.Use(async (httpContext, _next) => 
                {
                    Console.WriteLine("-----StartupFilterTwo-----");
                    await _next(httpContext);
                });
            };
        }
    }

将next(builder)放在前面执行,我们来看看效果
367770c0eaf2a345639810783540b4b5.png

此时,发现我们StartupFilterTwo并没有执行,那是因为app.MapGet("/", () => "Hello World!");是一个终结点中间件,而StartupFilterTwo注册到了中间件末尾,执行到这个中间件时就直接返回没有继续执行下一个中间件。
当我们修改Url路径为/test时,没有匹配到HelloWorld的中间件,StartupFilterTwo中的内容成功输出。
d9576e78451d625962ef72077e685bad.png

浅谈一下IStartupFilter的应用场景#

IStartupFilter可以用于模块化开发的方案,在各自类库中加载对应的中间件。
在请求头部管道做一些请求的校验or数据处理。
在请求管道尾部时,如上图404,无法匹配到路由,我们可以做哪些处理。


注意事项:#

IStartupFilter只能注册在中间件管道头部或者尾部,请确保中间件的使用顺序。
若中间件需要在管道中间插入使用,请使用正常的app.use在startup中正确配置。


IHostingStartup#

可在启动时从应用的 Program.cs 文件之外的外部程序集向应用添加增强功能,比如我们一些0代码侵入的扩展服务,在SkyApm中的.NET实现就是基于这种方式。
我们新建一个StartupHostLib类库,添加一下Microsoft.AspNetCore.Hosting的nuget包
然后新增一个Startup类库实现IHostingStartup。
注意,必须需要添加标记,否则无法识别HostingStartup
[assembly: HostingStartup(typeof(LearnStartup.OneHostingStartup))]

using Microsoft.AspNetCore.Hosting;


[assembly: HostingStartup(typeof(LearnStartup.OneHostingStartup))]
namespace StartupHostLib
{


    public class OneHostingStartup : IHostingStartup
    {
        public void Configure(IWebHostBuilder builder)
        {
            builder.ConfigureAppConfiguration((config) => 
            {
                Console.WriteLine("ConfigureAppConfiguration");
            });


            builder.ConfigureServices(services =>
            {


                Console.WriteLine("ConfigureServices");
            });


            builder.Configure(app =>
            {
                Console.WriteLine("Configure");
            });
        }
    }
}

在LearnStartup中引用项目,并在launchSettings的环境变量中添加
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "StartupHostLib"
然后启动项目
8bdb630f06bf1c2266d4ae5803326976.png

这里可以发现,HostingStartup的执行顺序是优于应用的。
但是出现一个问题,发现原本的HelloWorld中间件消失了,但是我们依赖注入加载的中间件依旧生效。我们注释builder.Configure方法之后再启动程序。

public void Configure(IWebHostBuilder builder)
{
    builder.ConfigureAppConfiguration((config) => 
    {
        Console.WriteLine("ConfigureAppConfiguration");
    });


    builder.ConfigureServices(services =>
    {


        Console.WriteLine("ConfigureServices");
    });


    //builder.Configure(app =>
    //{
    //    Console.WriteLine("Configure");
    //});
}

fed3d6958bfd3357d3384a5653a6d61b.png

可以发现,应用中间件正常了。说明HostingStartup中配置中间件和应用的中间件配置冲突,并覆盖应用中间件。
我们将StartupFilterOne和StartupFilterTwo放到OneHostingStartup中去配置依赖注入,再次启动项目观察。

public void Configure(IWebHostBuilder builder)
{
    builder.ConfigureAppConfiguration((config) => 
    {
        Console.WriteLine("ConfigureAppConfiguration");
    });
    builder.ConfigureServices(services =>
    {
        services.AddTransient<IStartupFilter, StartupFilterTwo>();
        services.AddTransient<IStartupFilter, StartupFilterOne>();
        Console.WriteLine("ConfigureServices");
    });


    //builder.Configure(app =>
    //{
    //    Console.WriteLine("Configure");
    //});
}

53d9512673e2e165cf8bdb97cb8d1d82.png可以发现,依赖注入中加载的中间件是生效的。


浅谈IHostingStartup应用场景#

由上面表现可以发现
IHostingStartup执行顺序由于应用执行顺序。
IHostingStartup中配置中间件管道会覆盖应用中间件管道。
依赖注入中IStartupFilter配置中间件可以正常使用不覆盖应用中间件。
所以我们使用HostingStartup的场景可以为:
对代码0侵入的场景,比如AOP数据收集(如SkyApm)。
没有中间件的场景OR符合IStartupFilter中间件的场景。
想深入了解的可以自行翻看源码,本文浅尝即止。

版权声明:本文来源于网友收集或网友供稿,仅供学习交流之用,如果有侵权,请转告小编或者留言,本公众号立即删除。

- EOF -

技术群:添加小编微信dotnet999

公众号:Dotnet讲堂

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ASP.NET Core Web 项目中使用 Vue.js,您可以按照以下步骤进行操作: 1. 首先,确保您的开发环境中已安装 Node.js。您可以从 Node.js 官方网站(https://nodejs.org)下载并安装适合您操作系统的版本。 2. 创建 ASP.NET Core Web 项目:使用您选择的方法创建一个新的 ASP.NET Core Web 项目或打开现有项目。 3. 在项目根目录中初始化 Vue CLI:打开命令行界面,导航到您的项目根目录,并运行以下命令来初始化 Vue CLI: ``` vue create clientApp ``` 此命令将在项目根目录下创建一个名为 `clientApp` 的文件夹,并初始化 Vue CLI 项目。 4. 配置 Vue CLI:运行上述命令后,Vue CLI 会引导您进行一些配置选项的选择。您可以根据需求选择不同的配置,例如选择需要的特性和插件。 5. 开发 Vue 组件:在 `clientApp` 文件夹中,您可以开始编写 Vue 组件。您可以使用单文件组件 (SFC) 的方式编写组件,或者使用其他适合您的方式。 6. 集成 Vue.js 到 ASP.NET Core Web 项目:在 ASP.NET Core Web 项目中的 Razor 页面或视图中,引入 Vue.js 和您编写的 Vue 组件。您可以使用 `<script>` 标签引入 Vue.js 运行时或开发版本,使用 `<link>` 或 `<style>` 标签引入样式文件。 7. 配置 ASP.NET Core Web 项目以处理 Vue CLI 生成的文件:在 ASP.NET Core Web 项目中的 `Startup.cs` 文件中,确保在 `Configure` 方法中添加以下配置: ```csharp app.UseStaticFiles(new StaticFileOptions { RequestPath = "/clientApp", FileProvider = new PhysicalFileProvider( Path.Combine(Directory.GetCurrentDirectory(), "clientApp/dist") ) }); ``` 这将配置 ASP.NET Core Web 项目以提供 Vue CLI 生成的文件。 8. 运行项目:运行 ASP.NET Core Web 项目,并访问包含 Vue 组件的页面。您应该能够看到 Vue 组件在浏览器中正常运行。 通过上述步骤,您就可以在 ASP.NET Core Web 项目中使用 Vue.js,并开发和管理您的 Vue 组件。这样做可以让您更方便地利用 Vue.js 的功能和特性,与 ASP.NET Core Web 项目进行集成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值