将参数传递给 AddHostedService
Pass Parameters to AddHostedService
我正在编写一个 .Net Core windows 服务,这里是一段代码:
internal static class Program
{
public static async Task Main(string[] args)
{
var isService = !(Debugger.IsAttached || args.Contains("--console"));
var builder = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<IntegrationService>();
});
if (isService)
{
await builder.RunAsServiceAsync();
}
else
{
await builder.RunConsoleAsync();
}
}
}
我想向我的服务传递一些参数,即 IntegrationService
- 如何向我的服务发送参数?
在 .net core 3
之前,您可以使用配置 class,您可以通过 DI 将其注入服务。
您的配置 class 可能如下所示:
class IntegrationConfig
{
public int Timeout { get; set; }
public string Name { get; set; }
}
然后你需要将此配置添加到 DI-system:
services.AddSingleton(new IntegrationConfig
{
Timeout = 1234,
Name = "Integration name"
});
在 class IntegrationService
中,您需要添加一个构造函数,该构造函数接受配置对象:
public IntegrationService(IntegrationConfig config)
{
// setup with config or simply store config
}
这基本上就是您所需要的。在我看来这不是最漂亮的解决方案 .net core 3
您可以简单地使用工厂功能来添加 HostedService 但我认为这样的事情是最好的选择
如果您 .net core 2.2
或以下。
编辑:
柯克·拉金在评论中提到:
You can emulate the overload. It's just a wrapper around AddTransient(), which of course does support the factory func approach.
为此,您可能需要查看可访问的当前过载 here:
/// <summary>
/// Add an <see cref="IHostedService"/> registration for the given type.
/// </summary>
/// <typeparam name="THostedService">An <see cref="IHostedService"/> to register.</typeparam>
/// <param name="services">The <see cref="IServiceCollection"/> to register with.</param>
/// <param name="implementationFactory">A factory to create new instances of the service implementation.</param>
/// <returns>The original <see cref="IServiceCollection"/>.</returns>
public static IServiceCollection AddHostedService<THostedService>(this IServiceCollection services, Func<IServiceProvider, THostedService> implementationFactory)
where THostedService : class, IHostedService
{
services.TryAddEnumerable(ServiceDescriptor.Singleton<IHostedService>(implementationFactory));
return services;
}
请注意,last commit that changed this file 是在 6 月 3 日,并被标记为 .net core 3 的预览版 6 和预览版 7。因为我从未听说过 TryAddEnumerable
并且我不是微软员工,所以我不知道不知道你是否可以直接翻译那个。
仅仅通过查看 current implementation of AddTransient
并深入研究了几个文件,遗憾的是我无法很好地绘制线条,无法为您提供您目前能够使用的确切功能获得 .net core 3
.
我给出的解决方法仍然有效,并且根据情况似乎可以接受。
Joelius 的回答是正确的,尽管还有另一种方法
services.AddSingleton<IHostedService>(provider => new IntegrationService("Test"));
关于 .Net Core 3 的 Joelius 答案的小更新
给定一个具有此构造函数混合参数 (TimeSpan
) 和服务 (ILogger<StatusService>
、IHttpClientFactory
) 的 HostedService
public StatusService(
TimeSpan cachePeriod,
ILogger<StatusService> logger,
IHttpClientFactory clientFactory)
您可以在 Startup.cs 中将其添加到您的 HostedService 中,如下所示:
services.AddHostedService
(serviceProvider =>
new StatusService(
TimeSpan.FromDays(1),
serviceProvider.GetService<ILogger<StatusService>>(),
serviceProvider.GetService<IHttpClientFactory>()));
虽然上面的答案是正确的,但它们确实有一个缺点,即您不能再在服务构造函数中使用 DI。
我做的是:
class Settings {
public string Url { get; set; }
}
class SomeService : IHostedService {
public SomeService (string instanceId, IOptionsMonitor<Settings> optionsMonitor) {
var settings = optionsMonitor.Get(instanceId);
}
}
services.Configure<Settings>("Instance1", (s) => s.Url = "http://google.com");
services.Configure<Settings>("Instance2", (s) => s.Url = "http://facebook.com");
services.AddSingleton<IHostedService>(x =>
ActivatorUtilities.CreateInstance<SomeService>(x, "Instance1")
);
services.AddSingleton<IHostedService>(x =>
ActivatorUtilities.CreateInstance<SomeService>(x, "Instance2")
);
这将为每个实例创建命名设置并将命名设置名称传递给 HostedService。
如果您想要多个具有相同 Class 和不同参数的服务,请确保使用 AddSingleton 而不是 AddHostedService,因为 AddHostedService 只会添加一个同一类型的实例,这将导致仅启动一个实例!
我正在编写一个 .Net Core windows 服务,这里是一段代码:
internal static class Program
{
public static async Task Main(string[] args)
{
var isService = !(Debugger.IsAttached || args.Contains("--console"));
var builder = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<IntegrationService>();
});
if (isService)
{
await builder.RunAsServiceAsync();
}
else
{
await builder.RunConsoleAsync();
}
}
}
我想向我的服务传递一些参数,即 IntegrationService
- 如何向我的服务发送参数?
在 .net core 3
之前,您可以使用配置 class,您可以通过 DI 将其注入服务。
您的配置 class 可能如下所示:
class IntegrationConfig
{
public int Timeout { get; set; }
public string Name { get; set; }
}
然后你需要将此配置添加到 DI-system:
services.AddSingleton(new IntegrationConfig
{
Timeout = 1234,
Name = "Integration name"
});
在 class IntegrationService
中,您需要添加一个构造函数,该构造函数接受配置对象:
public IntegrationService(IntegrationConfig config)
{
// setup with config or simply store config
}
这基本上就是您所需要的。在我看来这不是最漂亮的解决方案 .net core 3
您可以简单地使用工厂功能来添加 HostedService 但我认为这样的事情是最好的选择
如果您 .net core 2.2
或以下。
编辑:
柯克·拉金在评论中提到:
You can emulate the overload. It's just a wrapper around AddTransient(), which of course does support the factory func approach.
为此,您可能需要查看可访问的当前过载 here:
/// <summary>
/// Add an <see cref="IHostedService"/> registration for the given type.
/// </summary>
/// <typeparam name="THostedService">An <see cref="IHostedService"/> to register.</typeparam>
/// <param name="services">The <see cref="IServiceCollection"/> to register with.</param>
/// <param name="implementationFactory">A factory to create new instances of the service implementation.</param>
/// <returns>The original <see cref="IServiceCollection"/>.</returns>
public static IServiceCollection AddHostedService<THostedService>(this IServiceCollection services, Func<IServiceProvider, THostedService> implementationFactory)
where THostedService : class, IHostedService
{
services.TryAddEnumerable(ServiceDescriptor.Singleton<IHostedService>(implementationFactory));
return services;
}
请注意,last commit that changed this file 是在 6 月 3 日,并被标记为 .net core 3 的预览版 6 和预览版 7。因为我从未听说过 TryAddEnumerable
并且我不是微软员工,所以我不知道不知道你是否可以直接翻译那个。
仅仅通过查看 current implementation of AddTransient
并深入研究了几个文件,遗憾的是我无法很好地绘制线条,无法为您提供您目前能够使用的确切功能获得 .net core 3
.
我给出的解决方法仍然有效,并且根据情况似乎可以接受。
Joelius 的回答是正确的,尽管还有另一种方法
services.AddSingleton<IHostedService>(provider => new IntegrationService("Test"));
关于 .Net Core 3 的 Joelius 答案的小更新
给定一个具有此构造函数混合参数 (TimeSpan
) 和服务 (ILogger<StatusService>
、IHttpClientFactory
) 的 HostedService
public StatusService(
TimeSpan cachePeriod,
ILogger<StatusService> logger,
IHttpClientFactory clientFactory)
您可以在 Startup.cs 中将其添加到您的 HostedService 中,如下所示:
services.AddHostedService
(serviceProvider =>
new StatusService(
TimeSpan.FromDays(1),
serviceProvider.GetService<ILogger<StatusService>>(),
serviceProvider.GetService<IHttpClientFactory>()));
虽然上面的答案是正确的,但它们确实有一个缺点,即您不能再在服务构造函数中使用 DI。
我做的是:
class Settings {
public string Url { get; set; }
}
class SomeService : IHostedService {
public SomeService (string instanceId, IOptionsMonitor<Settings> optionsMonitor) {
var settings = optionsMonitor.Get(instanceId);
}
}
services.Configure<Settings>("Instance1", (s) => s.Url = "http://google.com");
services.Configure<Settings>("Instance2", (s) => s.Url = "http://facebook.com");
services.AddSingleton<IHostedService>(x =>
ActivatorUtilities.CreateInstance<SomeService>(x, "Instance1")
);
services.AddSingleton<IHostedService>(x =>
ActivatorUtilities.CreateInstance<SomeService>(x, "Instance2")
);
这将为每个实例创建命名设置并将命名设置名称传递给 HostedService。 如果您想要多个具有相同 Class 和不同参数的服务,请确保使用 AddSingleton 而不是 AddHostedService,因为 AddHostedService 只会添加一个同一类型的实例,这将导致仅启动一个实例!