c# - 如何访问用AddSingleton<T>注入(inject)的后台服务的成员

标签 c# asp.net-core dependency-injection

在asp.netcore web api项目中,有一个名为TimedHostedService的后台服务是通过AddSingleton<>注入(inject)的,当 Controller 访问该服务的成员[ExecutionCount]时,该值总是等于0,当成员[ExecutionCount]设置为static时,值发生变化,不知道为什么?属性 [ExecutionCount] 必须是静态的吗?

TimedHostedService:

public class TimedHostedService : IHostedService, IDisposable
{
    private int executionCount = 0;
    private readonly ILogger<TimedHostedService> _logger;
    private Timer _timer;

    public int ExecutionCount
    {
        get { return executionCount; }
        set { executionCount = value; }
    }

    public TimedHostedService(ILogger<TimedHostedService> logger)
    {
        _logger = logger;
    }

    public Task StartAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Timed Hosted Service running.");

        _timer = new Timer(DoWork, null, TimeSpan.Zero,
            TimeSpan.FromSeconds(1));

        return Task.CompletedTask;
    }

    private void DoWork(object state)
    {
        var count = Interlocked.Increment(ref executionCount);

        _logger.LogInformation(
            "Timed Hosted Service is working. Count: {Count}", count);
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Timed Hosted Service is stopping.");

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

通过AddSingleton<>注入(inject):

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<TimedHostedService>();
        services.AddControllers();
    }

 public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var hostBuilder = Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            })
            .ConfigureServices(services =>
            {
                services.AddHostedService<TimedHostedService>();
            })
            .UseContentRoot(Directory.GetCurrentDirectory())

        return hostBuilder;
    }

从 WeatherForecastController 访问属性 [ExecutionCount]:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

    private readonly TimedHostedService _timedHostedService;

    public WeatherForecastController(ILogger<WeatherForecastController> logger,TimedHostedService timedHostedService)
    {
        _logger = logger;
        _timedHostedService = timedHostedService;
    }

    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        int timeValue = _timedHostedService.ExecutionCount;
        _logger.LogInformation("ExecutionCount:{0}", timeValue);

        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

最佳答案

您将服务的两个实例添加到服务集合中。线路

services.AddSingleton<TimedHostedService>();

添加您的 Controller 通过依赖注入(inject)和行获取的实例

services.AddHostedService<TimedHostedService>();

添加作为托管服务运行的实例。

尝试以下操作:

services.AddHostedService((sp) => sp.GetRequiredService<TimedHostedService>());
services.AddSingleton<TimedHostedService>();

保持这个顺序很重要。这会将托管服务添加到服务集合(作为单例),并为实际托管服务使用相同的实例。

关于c# - 如何访问用AddSingleton<T>注入(inject)的后台服务的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65914969/

相关文章:

c# - 使用 Cookie 的购物车

asp.net-mvc - 如何让 .Net Core Action 返回 Nothing 或 Redirect

php - 是否可以将路由参数传递给 Laravel 中的 Controller 构造函数?

java - 我可以将 session bean 与其他注入(inject)的类一起重用吗?

c# - Task.Factory.FromAsync 是否触发创建的任务?

c# - C# 中调用函数而不创建对象

c# - 一点一点地更改 asp.net 应用程序以使用异步

c# - 无法加载文件或程序集 'Microsoft.Azure.Documents.Client - Azure-Table-Api

asp.net-core - AspNetCore 自定义/显式 Swagger OperationId

java - 在支持组件中使用 @ManagedProperty