[英]Asp.net core How to Register IHostedService which also Contains a Custom Interface
How do I property register an class which contains both the IHostedService
and a custom interface like IMyInterface
?如何属性注册一个包含
IHostedService
和 IMyInterface 之类的自定义接口的IMyInterface
?
As in如在
class BackgroundTaskScheduler: BackgroundService, ITaskScheduler {...}
If it is configure like:如果配置如下:
services.AddHostedService<BackgroundTaskScheduler>();
And then try to have it inject into a client, like so:然后尝试将其注入客户端,如下所示:
public class Foo
{
Foo(ITaskScheduler taskScheduler) {...}
}
An error is generated stating that ASP.net can't resolve BackgroundTaskScheduler
, why?生成一个错误,指出 ASP.net 无法解析
BackgroundTaskScheduler
,为什么?
After reading lots of ideas, including:在阅读了很多想法后,包括:
HostedServicewrapping
class which forward the start and stop calls to the real hosted service. HostedServicewrapping
class 将启动和停止调用转发到真正的托管服务。 But how to get it to work without requiring a wrapper class?但是如何在不需要包装器 class 的情况下使其工作? I combined the ideas discussed above into the following two extension methods.
我将上面讨论的想法组合成以下两种扩展方法。
If you like using interface DI, as in Bar.Bar(IFoo foo)
then use this one:如果您喜欢使用接口 DI,如
Bar.Bar(IFoo foo)
中,那么使用这个:
/// <summary>
/// Used to register <see cref="IHostedService"/> class which defines an referenced <typeparamref name="TInterface"/> interface.
/// </summary>
/// <typeparam name="TInterface">The interface other components will use</typeparam>
/// <typeparam name="TService">The actual <see cref="IHostedService"/> service.</typeparam>
/// <param name="services"></param>
public static void AddHostedApiService<TInterface, TService>(this IServiceCollection services)
where TInterface : class
where TService : class, IHostedService, TInterface
{
services.AddSingleton<TInterface, TService>();
services.AddSingleton<IHostedService>(p => (TService) p.GetService<TInterface>());
}
Usage:用法:
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedApiService<ITaskScheduler, BackgroundTaskScheduler>();
}
If you like to use concrete class injection, as in Bar.Bar(Foo foo)
then use:如果你喜欢使用具体的 class 注入,就像在
Bar.Bar(Foo foo)
中一样,那么使用:
/// <summary>
/// Used to register <see cref="IHostedService"/> class which defines an interface but will reference the <typeparamref name="TService"/> directly.
/// </summary>
/// <typeparam name="TService">The actual <see cref="IHostedService"/> service.</typeparam>
public static void AddHostedApiService<TService>(this IServiceCollection services)
where TService : class, IHostedService
{
services.AddSingleton<TService>();
services.AddSingleton<IHostedService>(p => p.GetService<TService>());
}
Usage:用法:
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedApiService<BackgroundTaskScheduler>();
}
Enjoy!享受!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.