微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

asp.net-core – 如何注入对特定IHostedService实现的引用?

我的网络应用程序有一个后台服务,可以收听服务总线.基于 docs,运行后台服务的内置方式似乎是实现IHostedService.

所以我有一些看起来像这样的代码

public class ServiceBusListener : IMessageSource<string>,IHostedService
{
    public virtual event ServiceBusMessageHandler<string> OnMessage = delegate { };

    public Task StartAsync(CancellationToken cancellationToken)
    {
        // run the background task...
    }

    // ... other stuff ...
}

然后在Startup.cs中注册该服务:

services.AddSingleton<IHostedService,ServiceBusListener>();

一旦我更新到ASP.NET 2.1,我可以使用新的便捷方法

services.AddHostedService<ServiceBusListener>();

但我相信这两者在功能上是等价的.

复杂性:我的Web应用程序有多个IHostedService实现(特别是服务总线监听器的不同实例).

问题:如何让其他组件获得对特定托管服务实现(我的服务总线监听器)的引用?换句话说,如何将特定实例注入组件?

用例:我的后台服务侦听服务总线消息,然后重新发布消息作为.NET事件(如果您想知道,消费代码处理线程问题).如果事件在后台服务上,则订阅者需要获得对后台服务的引用才能进行订阅.

我尝试过:如果我做了显而易见的事情并将ServiceBusListener声明为注入不同组件的依赖项,我的启动代码会抛出“无法解析类型的服务”异常.

甚至可以请求IHostedService的特定实现吗?如果没有,最好的解决方法是什么?介绍我的服务和消费者可以参考的第三个组件?避免使用IHostedService并手动运行后台服务?

解决方法

原来有一种简单的方法可以做到这一点(感谢指针,Steven).

如果您需要能够注入/获取某些服务的引用,请继续正常注册服务(不必担心任何IHostedService的东西):

services.AddSingleton<ServiceBusListener>();

现在我们可以注册一个单独的托管服务,其唯一的职责是启动/停止我们刚刚注册的服务:

services.AddHostedService<BackgroundServiceStarter<ServiceBusListener>>();

其中BackgroundServiceStarter是一个类似于的辅助类:

public class BackgroundServiceStarter<T> : IHostedService where T:IHostedService
{
    readonly T backgroundService;

    public BackgroundServiceStarter(T backgroundService)
    {
        this.backgroundService = backgroundService;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        return backgroundService.StartAsync(cancellationToken);
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return backgroundService.StopAsync(cancellationToken);
    }
}

更新2018/8/6:由于ygoe的建议,更新了代码以避免服务定位器模式

原文地址:https://www.jb51.cc/aspnet/246975.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐