#c# #.net-core #dependency-injection
#c# #.net-ядро #внедрение зависимостей
Вопрос:
В обычной службе .net core шаблон создал бы для меня такую функцию :
public void Configure(IApplicationBuilder app)
{
...
}
Здесь я могу внедрить свои сервисы и использовать их при запуске, например, сценарий предварительного развертывания базы данных.
В шаблоне рабочей службы эта функция не создается для меня, только функция CreateHostbuilder .
Как мне создать функцию Configure() или запустить / сконструировать класс при запуске в рабочей службе?
Комментарии:
1. Вы имеете в виду, что хотите использовать внедрение зависимостей из консольного процесса? docs.microsoft.com/en-us/dotnet/core/extensions/generic-host
2. Подсказка,
.ConfigureServices(...)
не обязательно должно быть лямбда. Вы можете определить статический метод.3. В
workerService
шаблоне нет метода Configure, я не знаю, зачем вам нужно его создавать?4. @osmanRahimi, потому что я хочу создать класс один раз при обновлении состояния службы.
5. таким образом, вы можете зарегистрировать свои интерфейсы / класс, как и раньше, используя сервисы в
ConfigureServices
Ответ №1:
Итак, вы хотите настроить службы, а затем использовать их из консольного приложения.
Из вашего вопроса и комментариев кажется, что вы понимаете, как настраивать службы;
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
...
.ConfigureServices(ConfigureServices);
public static void ConfigureServices(HostBuilderContext context, IServiceCollection serviceCollection) {
...
}
Теперь у вас есть несколько способов использовать эти службы. Вы можете запустить хост, затем получить сервисы и использовать их в своем основном методе. Выход, когда ваша работа выполнена и все службы удалены.
public static async Task<int> Main(string[] args)
{
using (var host = CreateHostBuilder(args).Build())
{
await host.StartAsync();
var lifetime = host.Services.GetRequiredService<IHostApplicationLifetime>();
var logger = host.Services.GetRequiredService<ILogger<Program>>();
...
lifetime.StopApplication();
await host.WaitForShutdownAsync();
}
return 0;
}
Или вы могли бы выполнять текущие задачи, реализуя IHostedService
/ BackgroundService
. При IHost
запуске все зарегистрированные IHostedService
будут запущены в том порядке, в котором они были зарегистрированы, а затем остановлены / отменены при завершении работы хоста.
public static async Task<int> Main(string[] args)
{
using (var host = CreateHostBuilder(args).Build())
{
await host.RunAsync();
}
return 0;
}
public static void ConfigureServices(HostBuilderContext context, IServiceCollection serviceCollection) {
serviceCollection.AddHostedService<Service>();
}
public class Service : BackgroundService {
public Service (...) {...}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await Task.Yield();
while (!stoppingToken.IsCancellationRequested)
{
...
}
}
}
Или некоторая комбинация из вышеперечисленных.
Обратите внимание, что когда вы используете веб-хост, это IHostedService
функция ( GenericWebHostedService
), которая фактически запускает веб-сервер. Вызов всех зарегистрированных IStartupFilters
, включая тот, который вызывает ваш Startup.Configure
метод, для компиляции конвейера запросов.
Ответ №2:
Если вы хотите зарегистрировать интерфейс или службу, чтобы внедрить их в другие службы, вы все равно можете зарегистрировать свои службы ConfigureServices
.
в следующем примере есть две службы, которые регистрируются как Singleton
и Transient
.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
services.AddSingleton<IEmployeeService, EmployeeService>();
services.AddTransient<UserService>();
});