简体   繁体   中英

Referencing non-static method in a static way

I have this C# class:

public static class HealthCheckHighMark
{

    public static IEndpointConventionBuilder MapHighMarkChecks(
        this IEndpointRouteBuilder endpoints)
    {

        return endpoints.MapHealthChecks("/api/health/highmark", new HealthCheckOptions
        {
            ResponseWriter = async (context, report) =>
            {
                var result = JsonConvert.SerializeObject(
                    new HighMarkResult
                    {
                        HighMark = HHandler.GetHighMark().High.ToString(),
                    }, Formatting.None,
                    new JsonSerializerSettings
                    {
                        NullValueHandling = NullValueHandling.Ignore
                    });
                context.Response.ContentType = MediaTypeNames.Application.Json;
                await context.Response.WriteAsync(result);
            },

            Predicate = (check) => check.Tags.Contains("highmark")
        });
    }
}

HHandler.GetHighMark() is a non-static method in the HHandler class:

public WatermarkOffsets GetHighMark()
{
    return consumer.QueryWatermarkOffsets(TopicPartition.TopicPartition, TimeSpan.FromSeconds(2));
}

When I run my check I get a HTTP 500 error with the following error in the log:

2021-03-03 11:54:51.308Z ERROR APP=2227 COMP=3789 [13] Connection id "0HM6U7CJEMU0S", Request id "0HM6U7CJEMU0S:00000001": An unhandled exception was thrown by the application. - Logger=Microsoft.AspNetCore.Server.Kestrel,Level=ERROR,ThreadId=13,,Exception="System.MissingMethodException: Method not found: 'Confluent.Kafka.WatermarkOffsets Ed.Md.FHandler.Health.HHandler.GetHighMark()'. at Ed.Health.HealthCheckHMark.<>c.<<-cctor>b__2_0>d.MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine) at Ed.Health.HealthCheckHMark.<>c.<.cctor>b__2_0(HttpContext context, HealthReport report) at Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckMiddleware.InvokeAsync(HttpContext httpContext) at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)"

I think the issue is that I'm trying to reference a non-static method in a static way. How do I resolve this though?

Additional Info

Here's my HHandler class:

public class HHandler : IHHandler
{
    private readonly IConfig _config;
    public IConsumer<Ignore, MdpMessage> consumer { get;  set; }
    public TopicPartitionOffset TopicPartition { get; set; }

    public HHandler([NotNull] IConfig healthOptions)
    {
        _config = healthOptions;
    }

    public WatermarkOffsets GetHighMark()
    {
        return consumer.QueryWatermarkOffsets(TopicPartition.TopicPartition, TimeSpan.FromSeconds(2));
    }

    WatermarkOffsets IHHandler.GetHighMark()
    {
        return GetHighMark();
    }
}

What are you trying to check in this healthcheck endpoint?

It is ussialy used to check that some existing system is healthy, like internal DB connection is ok, or some resources are below limits etc. So you need to run a check on that existing system - if it's not a sttatic class, than there should be an instance somewhere, singleton maybe, or some way to create that instance (some factory for example), if it's transient. Usialy a good idea is to ask a DI container to resolve the instance for you. Providing that you are using DI of course (well, in a modern AspNetCore I think you should use it:)

Try something like

context.RequestServices.GetService(typeof(HHandler)).GetHighMark().High.ToString()

and see if this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM