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

C# .NET核心HealthCheck-添加带有依赖项注入和参数的HealthCheck,c#,dependency-injection,.net-core-3.1,health-check,C#,Dependency Injection,.net Core 3.1,Health Check,我有不同的类继承了基类。基类实现接口IHealthCheck。每个类都有一个构造函数,该构造函数需要一个记录器和相应于类的参数。 例如: public ConnectionHealthCheck(ILogger logger, string address) : base(logger) { Address = address; } 我有一个appSettings.json,它允许我在健康检查服务中配置几个诊断 我在App.xaml.cs中获得

我有不同的类继承了基类。基类实现接口IHealthCheck。每个类都有一个构造函数,该构造函数需要一个记录器和相应于类的参数。 例如:

public ConnectionHealthCheck(ILogger logger, string address)
        : base(logger)
    {
         Address = address;
    }
我有一个appSettings.json,它允许我在健康检查服务中配置几个诊断

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

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

这是我代码的一些部分

启动时方法:

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方法:

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)); 
        [...] }
如您所见,我无法创建ConnectionHealthCheck类的实例,因为我无法访问ILogger对象

那我怎么做呢?我考虑不同的解决方案,但我没有答案或方法

不是在App.xaml.cs中而是在App.xaml.cs之后构建HealthCheck服务?例如,在视图模型中,我可以访问serviceCollection和logger

找到让记录器在CreateHealthCheck方法中使用它的方法吗

这样做,但我不知道什么时候可以传递参数

serviceCollection.AddHealthChecks.AddChecknameofConnectionHealthCheck


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

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>())
    }
}
    

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

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

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>())
    }
}
    
这可能很粗糙,但希望能有所帮助。

您可以使用它来注册您的类。它应该实现IHealthCheck,它有接受委托函数的构造函数,它允许您使用IServiceProvider解析所需参数以创建healthcheck类的实例。大概是这样的:

public static class ConnectionHealthCheckBuilderExtensions
{
    const string DefaultName = "example_health_check";

    public static IHealthChecksBuilder AddConnectionHealthCheck(
        this IHealthChecksBuilder builder,
        string name = default,
        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));
    }
}
有关更多详细信息,请参阅部分文档。

您可以使用它来注册您的类。它应该实现IHealthCheck,它具有接受委托函数的构造函数,允许您使用IServiceProvider解析所需参数以创建healthcheck类的实例。大概是这样的:

public static class ConnectionHealthCheckBuilderExtensions
{
    const string DefaultName = "example_health_check";

    public static IHealthChecksBuilder AddConnectionHealthCheck(
        this IHealthChecksBuilder builder,
        string name = default,
        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));
    }
}

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

这似乎是一个很好的解决方案,但我在尝试启动HealthCheck时遇到了一个问题。无法解析生成器中的记录器,我有一个例外:没有注册类型为“Microsoft.Extensions.Logging.ILogger”的服务。你知道为什么吗?@elassmania你正在尝试注入/解析不受支持的非泛型ILogger,你应该注入/解析ILogger,在这种情况下,ILogger实际上也是因为您正在手动处理此解析,所以您仍然可以在healthcheck的ctor中使用ILogger,但应该解析通用的:sp.GetRequiredServiceWoups!你说得对,我忘了打记录器。它正在工作,谢谢你的帮助!这似乎是一个很好的解决方案,但我在尝试启动HealthCheck时遇到了一个问题。无法解析生成器中的记录器,我有一个例外:没有注册类型为“Microsoft.Extensions.Logging.ILogger”的服务。你知道为什么吗?@elassmania你正在尝试注入/解析不受支持的非泛型ILogger,你应该注入/解析ILogger,在这种情况下,ILogger实际上也是因为您正在手动处理此解析,所以您仍然可以在healthcheck的ctor中使用ILogger,但应该解析通用的:sp.GetRequiredServiceWoups!你说得对,我忘了打记录器。它正在工作,谢谢你的帮助!