Asp.net核心如何注册也包含自定义接口的IHostedService [英] Asp.net core How to Register IHostedService which also Contains a Custom Interface
问题描述
如何属性注册一个同时包含 IHostedService
和自定义接口(例如 IMyInterface
)的类?
How do I property register an class which contains both the IHostedService
and a custom interface like IMyInterface
?
与
Class BackgroundTaskScheduler类:BackgroundService,ITaskScheduler {...}
如果配置如下:
services.AddHostedService<BackgroundTaskScheduler>();
然后尝试将其注入客户端,如下所示:
And then try to have it inject into a client, like so:
public class Foo
{
Foo(ITaskScheduler taskScheduler) {...}
}
生成错误,表明ASP.net无法解析 BackgroundTaskScheduler
,为什么?
An error is generated stating that ASP.net can't resolve BackgroundTaskScheduler
, why?
推荐答案
阅读了很多想法之后,包括:
After reading lots of ideas, including:
- AddHostedService()将服务注册为临时服务-我同意大多数抱怨,因为大多数托管服务不是独立存在和/或运行的.
- 如何注入对特定IHostedService的引用实施?-提出了一个独特的概念,即使用隐藏的
HostedServicewrapping
类将启动和停止调用转发到真正的托管服务.
- AddHostedService() registers service as Transient - which I agree with most of the complains, since most hosted services don't live and/or run in isolation.
- How to inject a reference to a specific IHostedService implementation? - which suggested a unique concept of using a hidden
HostedServicewrapping
class which forward the start and stop calls to the real hosted service.
但是,如何在不需要包装类的情况下使其工作呢?我将上面讨论的想法结合到以下两种扩展方法中.
But how to get it to work without requiring a wrapper class? I combined the ideas discussed above into the following two extension methods.
如果您喜欢使用接口DI,如 Bar.Bar(IFoo foo)
中所示,请使用以下代码:
If you like using interface DI, as in Bar.Bar(IFoo foo)
then use this one:
/// <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>());
}
用法:
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedApiService<ITaskScheduler, BackgroundTaskScheduler>();
}
具体的类依赖注入
如果您想使用具体的类注入,如 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>());
}
用法:
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedApiService<BackgroundTaskScheduler>();
}
享受!
这篇关于Asp.net核心如何注册也包含自定义接口的IHostedService的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!