Asp.net核心如何注册也包含自定义接口的IHostedService [英] Asp.net core How to Register IHostedService which also Contains a Custom Interface

查看:68
本文介绍了Asp.net核心如何注册也包含自定义接口的IHostedService的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何属性注册一个同时包含 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() 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆