我们怎样才能在我们的应用程序中使用ASP.NET Core中的类似中间件?

时间:2016-08-17 04:44:17

标签: c# asp.net-core

我想知道如何在我的应用程序中使用像asp.net core这样的中间件架构?

这个目标需要哪种模式?

是否有任何类似设计的参考资料可用于添加新功能和...?

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseStaticFiles();

    app.UseIdentity();

    // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

使用非常简单的Configure方法,我们可以向应用程序添加新功能他们如何实现这样的功能?

1 个答案:

答案 0 :(得分:8)

我要做的第一件事是阅读Middleware - Asp.Net Documentation

这将有助于了解中间件的使用方式以及实施自定义中间件所需遵循的实践。

直接从文档

获取
  

中间件是组装成一个的软件组件   应用程序管道来处理请求和响应。每个组件   选择是否将请求传递给中的下一个组件   管道,并可以在下一个之前和之后执行某些操作   在管道中调用组件。请求代表习惯了   构建请求管道。请求委托处理每个HTTP   请求。

现在,这表明它允许组件处理请求和响应。中间件按照添加到应用程序中间件集合的顺序执行。

app.UseStaticFiles();添加了middlware来处理静态文件(图像,CSS,脚本等)。

现在说你希望在管道中添加自己的处理,你可以创建一个中间件类作为下面的示例。

public class GenericMiddleware
{
    public GenericMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    readonly RequestDelegate _next;

    public async Task Invoke(HttpContext context, IHostingEnvironment hostingEnviroment)
    {
        //do something

        await _next.Invoke(context);
    }
}

这里有一些有趣的观点。首先,构造函数需要一个RequestDelegate,它基本上(但不完全是)将被调用的下一个中间件对象。

接下来,我们实现自己的Invoke方法。此方法应将HttpContext作为参数,并允许从IoC容器中注入其他依赖项(在我的示例中为IHostingEnvironment实例)。

然后,此方法执行需要执行的代码,然后调用执行await _next.Invoke(context);的{​​{1}}来调用下一个中间件类。

现在将其添加到应用程序中间件中,您只需调用

即可 在RequestDelegate文件的app.UseMiddleware<GenericMiddleware>();方法中

Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

或者创建一个简单的扩展方法。

startup.cs

然后将其称为public static class GenericMiddlewareExtensions { public static IApplicationBuilder UseGenericMiddleware(this IApplicationBuilder app) { app.UseMiddleware<GenericMiddleware>(); return app; } }

现在,您实现自己的中间件的方式和原因取决于您。但是如上所述,由中间件调用下一个app.UseGenericMiddleware();如果它没有,那么它会停止请求。

以下是我的一个项目中的示例,该项目检查数据库是否已安装。如果它没有将请求重定向回安装页面。

RequestDelegate

正如您可以看到public class InstallationMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public InstallationMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) { _next = next; _logger = loggerFactory.CreateLogger<InstallationMiddleware>(); } public async Task Invoke(HttpContext context) { _logger.LogInformation("Handling request: " + context.Request.Path); if (context != null && !DatabaseHelper.IsDatabaseInstalled()) { if (!context.Request.Path.ToString().ToLowerInvariant().StartsWith("/installation")) { context.Response.Redirect("/installation"); return; } } await _next.Invoke(context); _logger.LogInformation("Finished handling request."); } } 我们是否重定向了回复,但却没有调用!DatabaseHelper.IsDatabaseInstalled() _next

文档再次说明了一切。