首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET核心HealthCheck -添加带有依赖注入和参数的HealthCheck

.NET核心HealthCheck -添加带有依赖注入和参数的HealthCheck
EN

Stack Overflow用户
提问于 2020-06-26 09:55:30
回答 2查看 3.9K关注 0票数 4

我有不同的类,它们继承一个基类。基类实现接口IHealthCheck。每个类都有一个构造函数,根据类需要一个记录器和参数。例如:

代码语言:javascript
复制
public ConnectionHealthCheck(ILogger logger, string address)
        : base(logger)
    {
         Address = address;
    }

我有一个appSettings.json,它允许我在健康检查服务中配置几个要做的诊断。

我在App.xaml.cs中获得诊断信息列表,并试图将它们添加到HealthCheck列表中。

问题是,我不能用它旁边的参数进行依赖注入,而且我不知道什么是最好的解决方案。

这是我的代码的一些部分。

OnStartup方法:

代码语言:javascript
复制
protected override void OnStartup(StartupEventArgs e)
    {
        var a = Assembly.GetExecutingAssembly();
        using var stream = a.GetManifestResourceStream("appsettings.json");

        Configuration = new ConfigurationBuilder()
            .AddJsonStream(stream)
            .Build();

        var host = new HostBuilder()
            .ConfigureHostConfiguration(c => c.AddConfiguration(Configuration))
                .ConfigureServices(ConfigureServices)
                .ConfigureLogging(ConfigureLogging)
                .Build();
       [...] }

configureService方法:

代码语言:javascript
复制
private void ConfigureServices(IServiceCollection serviceCollection)
    {
        // create and add the healthCheck for each diag in the appSettings file
        List<DiagnosticConfigItem> diagnostics = Configuration.GetSection("AppSettings:Diagnostics").Get<List<DiagnosticConfigItem>>();
        diagnostics.ForEach(x => CreateHealthCheck(serviceCollection, x)); 
        [...] }

CreateHealthCheck方法的问题是:

代码语言:javascript
复制
private void CreateHealthCheck(IServiceCollection serviceCollection, DiagnosticConfigItem configItem)
    {
        EnumDiagType type;

        try
        {
            type = (EnumDiagType)Enum.Parse(typeof(EnumDiagType), configItem.Type, true);
        }
        catch (Exception)
        {
            throw new Exception("Diagnostic type not supported");
        }

        switch (type)
        {
            case EnumDiagType.Connection:
                serviceCollection.AddHealthChecks().AddCheck(nameof(ConnectionHealthCheck), new ConnectionHealthCheck(???, configItem.Value));
                break;
            case EnumDiagType.Other:
                [...] }

如您所见,我无法创建ConnectionHealthCheck类的实例,因为我无法到达ILogger对象.

那我该怎么做?我想出了不同的解决方案,但我没有答案,也没有办法

  • 构建HealthCheck服务不是在App.xaml.cs中,而是在之后?(在视图模型中,我可以访问serviceCollection和记录器)
  • 找到让记录器在CreateHealthCheck方法中使用它的方法吗?
  • 这样做,但我不知道什么时候可以传递参数 serviceCollection.AddHealthChecks().AddCheck<ConnectionHealthCheck>(nameof(ConnectionHealthCheck));
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-26 10:27:26

您可以使用HealthCheckRegistration注册您的类(它应该实现IHealthCheck),它有接受委托Func<IServiceProvider,IHealthCheck>的构造函数,它允许您使用IServiceProvider解析所需的参数,以创建健康检查类的实例。就像这样:

代码语言:javascript
复制
public static class ConnectionHealthCheckBuilderExtensions
{
    const string DefaultName = "example_health_check";

    public static IHealthChecksBuilder AddConnectionHealthCheck(
        this IHealthChecksBuilder builder,
        string name,
        DiagnosticConfigItem configItem,
        HealthStatus? failureStatus = default,
        IEnumerable<string> tags = default)
    {
        return builder.Add(new HealthCheckRegistration(
            name ?? DefaultName,
            sp => new ConnectionHealthCheck(sp.GetRequiredService<ISomeService>(), configItem.Value),
            failureStatus,
            tags));
    }
}

有关详细信息,请参阅文档的部分。

票数 9
EN

Stack Overflow用户

发布于 2020-06-26 10:12:58

内置的.NET内核DI可以在构造器级别注入组件.因此,请使用以下方式,我在我的ASP.NET核心项目中使用了这种方法。

代码语言:javascript
复制
public class Startup
{
    public Startup(IWebHostEnvironment environment, IConfiguration configuration, ILoggerFactory loggerFactory)
    {
        Environment = environment;
        Configuration = configuration;
        LoggerFactory = loggerFactory;
    }

    public IConfiguration Configuration { get; }
    public ILoggerFactory LoggerFactory { get; }
    public IWebHostEnvironment Environment { get; }
    
    private void ConfigureServices(IServiceCollection serviceCollection)
    {
        List<DiagnosticConfigItem> diagnostics = Configuration.GetSection("AppSettings:Diagnostics").Get<List<DiagnosticConfigItem>>();
        diagnostics.ForEach(x => CreateHealthCheck(serviceCollection, x, LoggerFactory)); 
    }
    private void CreateHealthCheck(IServiceCollection serviceCollection, DiagnosticConfigItem configItem)
    {
        // Create a ILogger<T> based on your Type by
        loggerFactory.CreateLogger<MessagingServices>())
    }
}

这可能很粗糙,但希望这能有所帮助。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62592283

复制
相关文章

相似问题

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