Я пытаюсь найти правильную архитектуру для решения этой проблемы: мне нужно создать API, который обслуживает контроллер REST. Этот контроллер REST просто обращается к значениям, хранящимся в словаре, и передает их пользователю. Что в структуре данных словаря? Есть данные, которые являются результатом очистки внешнего API.
Решение 1: Я не создаю рабочую службу, а только мой API. Мой API при запуске запускает другой поток асинхронно, который продолжает очищать внешний API и сохраняет данные в этом словаре.
Решение 2 - Я выбрал тот, который мне подходит лучше (поправьте меня, если я ошибаюсь) : Я создаю рабочую службу, которая вызывается при запуске моего API и выполняет роль очистки внешнего API и сохранения данных в словаре. Такие данные будут обслуживаться контроллером в моем API.
Итак, во-первых, я не знаю, правильный ли мой выбор по отношению к первому. Если это ... У меня проблемы с настройкой работника.
Program.cs моего API:
public class Program
{
public static void Main(string[] args)
{
var webHost = CreateHostBuilder(args).Build();
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
.Build();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Startup.cs моего API:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHostedService<Worker>(); //here I register my worker service
}
Program.cs моего работника:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton<IScraperService, ScraperService>();
// Inject IHttpClientFactory
services.AddHttpClient();
services.AddHostedService<Worker>();
});
}
Мой работник:
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IScraperService _scraperService;
public Worker(ILogger<Worker> logger, IScraperService scraperService)
{
_logger = logger;
_scraperService = scraperService;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_scraperService.ScrapeObjects();
}
}
}
, поэтому, когда мой API запустит вызов рабочего (или, по крайней мере, попытка), но жалобы. Там написано, что мой работник ничего не знает о регистрации IScraperService . Конечно, нет .. потому что я зарегистрировался в ConfigureServices моего проекта Worker Service, который никогда не вызывается, потому что я не запускаю его самостоятельно.
Возможное решение: правильно ли сделать регистрацию IScraperService (services.AddSingleton ();) при запуске моего API? Пожалуйста, дайте мне знать, если все не так. Спасибо!