首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从ASP.NET内核的扩展方法中使用中间件配置

从ASP.NET内核的扩展方法中使用中间件配置
EN

Stack Overflow用户
提问于 2018-02-05 08:10:21
回答 2查看 3K关注 0票数 1

我已经开发了一段ASP.NET核心中间件。我在这篇文章中简化了中间件,以使问题变得更清楚。

中间件在Startup.cs中配置如下:

代码语言:javascript
运行
复制
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
    app.UseMyMiddleware(42);
    ...
}

整数(42)存储在中间件实例中,一切都很好。

现在,我想创建一些助手方法作为扩展方法:

代码语言:javascript
运行
复制
public static int Add(this int i)
{
    return i + TODO;
}

我希望方法将i的值添加到发送到中间件的值(42)中。

目前,我已经在中间件内部的公共静态变量中保存了42的值,并通过扩展方法访问了这个值:

代码语言:javascript
运行
复制
public static int Add(this int i)
{
    return i + MyMiddleware.Value;
}

由于种种原因,我不喜欢这个解决方案。对于如何以更好的方式解决这一问题,我们将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-05 08:53:04

通常情况下,扩展方法不适用于此。扩展方法是静态的,因此只能访问其他静态成员。然而,ASP.NET核心在设计上不使用任何静力学,并且广泛使用依赖注入来管理对象的生存期和访问依赖项。

因此,通常情况下,正确的方法是将扩展方法移动到某种非静态助手对象中,然后将其注入到需要访问它的位置。当然,这将不允许您在需要时轻松地调用它,而是要求您显式地依赖它(这是依赖注入的点之一)。

话虽如此,你的明确案例有点不同。从您的链接拉请求中可以看到,您的扩展方法如下所示(注意,我在这里合并了两个方法,以表明这一点):

代码语言:javascript
运行
复制
public static async Task ShipAsync(this Exception exception, HttpContext context)
{
    await MessageShipper.ShipAsync(
        ElmahIoMiddleware.ApiKey.AssertApiKeyInMiddleware(),
        ElmahIoMiddleware.LogId.AssertLogIdInMiddleware(),
        exception.Message, context, new ElmahIoSettings(), exception);
}

这有什么关系?因为你要通过HttpContext。HTTP上下文允许我们访问依赖注入。因此,我们实际上可以从依赖项注入容器中解决问题:

代码语言:javascript
运行
复制
public static async Task ShipAsync(this Exception exception, HttpContext context)
{
    var elmahIoConfig = context.RequestServices.GetService<ElmahIoConfiguration>();

    await MessageShipper.ShipAsync(
        elmahIoConfig.ApiKey,
        elmahIoConfig.LogId,
        exception.Message, context, new ElmahIoSettings(), exception);
}

现在,您只需要确保在注册中间件时ElmahIoConfiguration得到了正确的填充。请注意,我在这里不请求中间件实例,因为中间件通常不通过依赖项注入注册。引入一个单独的对象更有意义,然后您可以将该对象注入中间件并在那里进行初始化。

在您的示例中,您确实应该将中间件配置移到您的应用程序设置中,并使用IOptions<>模式在ConfigureServices级别配置它。在Configure中将中间件添加到管道中时,配置中间件不再是ASP.NET Core 2中的常见模式。

票数 2
EN

Stack Overflow用户

发布于 2018-02-05 08:22:04

为什么不使用appsettings.json来存储这些信息,然后使用内置的DI将其注入到中间件中呢?

appsettings.json

代码语言:javascript
运行
复制
{
    "MiddlewareConfiguration":
    {
        "MiddlewareValue":42,
    }
}

Startup.cs

代码语言:javascript
运行
复制
public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.Configure<MiddlewareConfiguration>(configuration.GetSection("MiddlewareConfiguration"));
}

MiddlewareConfiguration.cs

代码语言:javascript
运行
复制
public class MiddlewareConfiguration
{
    public int MiddlewareValue { get; set; }
}

然后,您可以将其插入到中间件中,例如:

代码语言:javascript
运行
复制
public async Task Invoke(HttpContext context, IOptions<MiddlewareConfiguration> config)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48618160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档