【问题标题】:Accessing IOptions and DbContext within ConfigureServices在 ConfigureServices 中访问 IOptions 和 DbContext
【发布时间】:2020-08-30 03:36:20
【问题描述】:

我已经开始在我的 .NET Core Web API 中实施健康检查。有两种运行状况检查,一种用于检查 SQL Server 是否有任何挂起的迁移,另一种用于检查另一个 API 是否处于活动状态。两者都添加在 ConfigureServicesStartup 类中。

为了进行迁移检查,我需要使用 AddDbContext 访问已经添加到 DI 的 DbContext 并检查 API,我需要从已经存在的配置中获取 API 基本 url DI 使用services.Configure<>。我使用以下代码访问DbContext

我正在使用AspNetCore.HealthChecks.Uris 包来使用AddUrlGroup 健康检查。

var sp = services.BuildServiceProvider();
var dbContext = sp.GetService<AppDbContext>();
var apis = sp.GetService<IOptions<InternalServicesConfiguration>>().Value;

services.AddHealthChecks().AddCheck("Database", new SqlDatabaseHealthCheck(dbContext), tags: new[] { "ready" })
            .AddUrlGroup(new Uri(new Uri(apis.Api1BaseUri), "/health/live"), HttpMethod.Get, "API 1", HealthStatus.UnHealthy, new []{"ready"});

services.BuildServiceProvider() 显示以下警告:

从应用程序代码中调用“BuildServiceProvider”会导致创建一个额外的单例服务副本。考虑将依赖注入服务等替代方案作为“配置”的参数

我可以使用

获取 api 基本网址
_configuration.GetSection("InternalServicesConfiguration").Get(typeof(InternalServicesConfiguration));

但我想不出另一种访问DbContext 的方法。

非常感谢任何帮助。

【问题讨论】:

    标签: c# asp.net-core


    【解决方案1】:

    您可以像这样注册您的健康检查:

    services.AddHealthChecks()
        .AddCheck<ExampleHealthCheck>("Database");
    

    然后只需将您的DbContext 注入ExampleHealthCheck 类,该类必须实现IHealthCheck 接口

    【讨论】:

    • 感谢@kebek,这行得通。关于访问IOptions(请参阅更新的健康检查)。除了使用_configuration.GetSection("").Get&lt;&gt;() 获取它之外,还有其他方法吗?
    • 我添加了另一个答案,所以这个问题更清楚
    【解决方案2】:

    官方docs有一些健康检查可以直接用于EF 但是,如果您想编写任何自定义或更复杂的检查,最好的办法可能是创建一个实现 IHealthCheck 接口的类,您可以在其中注入任何您想要的东西。

    同样来自docs about Custom health checks,一个例子:

    public class ExampleHealthCheck : IHealthCheck
    {
        public Task<HealthCheckResult> CheckHealthAsync(
            HealthCheckContext context,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var healthCheckResultHealthy = true;
    
            if (healthCheckResultHealthy)
            {
                return Task.FromResult(
                    HealthCheckResult.Healthy("A healthy result."));
            }
    
            return Task.FromResult(
                HealthCheckResult.Unhealthy("An unhealthy result."));
        }
    }
    

    正如 kebek alerady 回答的那样,您将像这样注册

    services.AddHealthChecks()
        .AddCheck<ExampleHealthCheck>("example_health_check");
    

    【讨论】:

    • 感谢您的回答 Sotiris,我已经如上所述设置了数据库健康检查,但我正在寻找如何将 DbContext 注入其中而无需构建服务提供程序。
    【解决方案3】:

    关于访问 IOptions(请参阅更新的健康检查)。除了使用 _configuration.GetSection("").Get()

    获取它之外,还有其他方法吗

    您可以通过以下方式注册这些选项(在 ConfigureServices 中):

    services.Configure<InternalServicesConfiguration>(Configuration.GetSection("InternalServicesConfiguration"));
    
    

    要获得这些选项,只需在您的类中注入 IOptions&lt;InternalServicesConfiguration&gt; options,其中 options.Value 属性是配置值

    【讨论】:

      猜你喜欢
      • 2021-01-06
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      • 2019-02-14
      • 1970-01-01
      • 2020-11-06
      • 1970-01-01
      相关资源
      最近更新 更多