본문 바로가기
C#

[C#] Web API NET 7 Background Service 추가 초기 설정.

by Jcoder 2023. 2. 16.

1. Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        // Add services to the container.

        builder.Services.AddControllers();
        // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen();

        // 0. json 환경 변수 파일 읽기.
        builder.Configuration.AddJsonFile("appsettings.json", true, true)
             .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", true, true);

        // 1. build 후 바인딩.
        var options = new TestOptions();
        builder.Configuration.GetSection(nameof(TestOptions)).Bind(options);

        // Http Client 추가.
        builder.Services.AddHttpClient("Nimble", httpClient => {
            httpClient.BaseAddress = new Uri("https://api.wmspanel.com/v1/");
            httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
        });

        builder.Services.AddHttpClient("Slack", httpClient => {
            httpClient.BaseAddress = new Uri(options.Option1); // 옵션 1 사용.
            httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
        });

        builder.Services.AddHostedService<TestWorkerService>();

        // 싱글톤 서비스 주입.
        builder.Services.AddSingleton<CancellationTokenSource>();

        // Microsoft.EntityFrameworkCore 설치 필요.
        //builder.Services.AddDbContext<MyDbContext>(options =>
        //{
        //    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"), (options1) =>
        //    {
        //        options1.EnableRetryOnFailure(3);
        //    });
        //},
        //ServiceLifetime.Scoped);

        // 2. di로 주입.
        builder.Services.Configure<TestOptions>(builder.Configuration.GetSection(nameof(TestOptions)));


        builder.Services.AddCors(options =>
        {
            options.AddPolicy("AllowAny", builder => 
            {
                builder.AllowAnyMethod()
                .AllowAnyHeader();
            });
        });

        var app = builder.Build();

        // 로깅 추가
        app.UseHttpLogging();

        // Configure the HTTP request pipeline.
        if (app.Environment.IsDevelopment())
        {
            app.UseSwagger();
            app.UseSwaggerUI();
        }
        else
        {
            // 에러 핸들링 추가.
            app.UseExceptionHandler("/Error");
        }

        app.UseCors();

        app.UseHttpsRedirection();

        app.UseAuthorization();

        app.MapControllers();

        app.Run();
    }
}

    public class TestOptions
    {
        public string? Option1 { get; set; }
        public string? Option2 { get; set; }
        public string? Option3 { get; set; }

        public TestOptions()
        {

        }
    }
public class TestWorkerService : BackgroundService
{
    private readonly ILogger<TestWorkerService>? _logger;
    private readonly CancellationTokenSource? _cancellationTokenSource;
    private readonly TestOptions? _options;
    private readonly IHttpClientFactory? _httpClientFactory;
    private readonly MyDbContext _dbContext;

    public override Task? ExecuteTask => base.ExecuteTask;

    #region 생성자
    //public TestWorkerService(ILogger<TestWorkerService> logger, CancellationTokenSource cancellationTokenSource, IOptions<TestOptions> options, IHttpClientFactory httpClientFactory, MyDbContext DbContext)  
    //{
    //    _logger = logger;
    //    _cancellationTokenSource = cancellationTokenSource;
    //    _options = options.Value;
    //    _httpClientFactory = httpClientFactory;
    //    _dbContext = DbContext;

    //    _logger.LogInformation($"TestWorkerService.Option1={_options.Option1}");
    //    _logger.LogInformation($"TestWorkerService.Option2= {_options.Option2}");
    //}
    public TestWorkerService(ILogger<TestWorkerService> logger, CancellationTokenSource cancellationTokenSource, IOptions<TestOptions> options, IHttpClientFactory httpClientFactory)
    {
        _logger = logger;
        _cancellationTokenSource = cancellationTokenSource;
        _options = options.Value;
        _httpClientFactory = httpClientFactory;

        _logger.LogInformation($"TestWorkerService.Option1={_options.Option1}");
        _logger.LogInformation($"TestWorkerService.Option2= {_options.Option2}");
    }
    #endregion

    public override Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("TestWorkerService start");
        return base.StartAsync(cancellationToken);
    }

    public override Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("TestWorkerService stop");
        return base.StopAsync(cancellationToken);
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("TestWorkerService ExecuteAsync");
        while (stoppingToken.IsCancellationRequested)
        {
            if (DateTime.Now.ToString("HHmm").Equals("0000") && !string.IsNullOrEmpty(_options.Option1))
            {
                using var client = _httpClientFactory.CreateClient("Slack");
                client.BaseAddress = new(_options.Option1);
            }

            _logger.LogInformation($"{DateTime.Now}");

            await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
        }
    }
}