从asp.net core 2.1中的控制器访问BackgroundService
Posted
技术标签:
【中文标题】从asp.net core 2.1中的控制器访问BackgroundService【英文标题】:access BackgroundService from controller in asp.net core 2.1 【发布时间】:2018-09-07 04:38:06 【问题描述】:我只需要从控制器访问我的 BackgroundService。 由于 BackgroundServices 被注入了
services.AddSingleton<IHostedService, MyBackgroundService>()
如何从 Controller 类中使用它?
【问题讨论】:
将构造函数添加到控制器public ControllerName(IHostedService service) ..
在这里提问之前您是否尝试过阅读文档? docs.microsoft.com/en-us/aspnet/core/fundamentals/…
是的,我做到了。我需要在我的控制器中注入 BackgroundService,而不是 IHostedService 接口。我可以拥有多个 BackgroundService,并且都作为 services.AddSingletonStart()
的实例
【参考方案1】:
最后我在控制器中注入了IEnumerable<IHostedService>
,并按类型过滤:background.FirstOrDefault(w => w.GetType() == typeof(MyBackgroundService)
【讨论】:
【参考方案2】:我就是这样解决的:
public interface IHostedServiceAccessor<T> where T : IHostedService
T Service get;
public class HostedServiceAccessor<T> : IHostedServiceAccessor<T>
where T : IHostedService
public HostedServiceAccessor(IEnumerable<IHostedService> hostedServices)
foreach (var service in hostedServices)
if (service is T match)
Service = match;
break;
public T Service get;
然后在Startup
:
services.AddTransient<IHostedServiceAccessor<MyBackgroundService>, HostedServiceAccessor<MyBackgroundService>>();
在我的班级需要访问后台服务...
public class MyClass
private readonly MyBackgroundService _service;
public MyClass(IHostedServiceAccessor<MyBackgroundService> accessor)
_service = accessor.Service ?? throw new ArgumentNullException(nameof(accessor));
【讨论】:
一句警告——在遇到一些异常行为后,请注意虽然 IHostedService 实现的行为类似于单例,但它的状态将无法访问。例如,如果您将private readonly Guid _id = Guid.NewGuid();
添加到服务类中,并在服务启动与通过 IHostedServiceAccessor 获取时观察它,您会注意到它是两个不同的值。
@UtopiaLtd 不要将后台服务添加为Transient
,而是添加为Singleton
。 microsoft 文档指出托管服务必须自己创建范围,就像您将其添加为 Scoped
一样,您可能会使用已处置的对象。
从 .NET 5.0 开始,API 派生自 ControllerBase。如果这个答案解决了从 ControllerBase 派生的“MyController”如何调用 BackgroundService 会更好。【参考方案3】:
在ConfigureServices函数中添加BackgroundService:
public void ConfigureServices(IServiceCollection services)
services.AddHostedService<ListenerService>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
在控制器中注入:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
private readonly IHostedService listenerService;
public ValuesController(IHostedService listenerService)
this.listenerService = listenerService;
我使用 BackgroundService 为 AWSSQS 侦听器启动了多个侦听器。如果消费者想要旋转新的监听器,那么可以通过 POST 到控制器方法(端点)来完成。
【讨论】:
以上是关于从asp.net core 2.1中的控制器访问BackgroundService的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core 2.1 中的数据保护仅适用于一台机器
如何使用 fetch 将 FormData 从 javascript 发送到 ASP.NET Core 2.1 Web API
ReactJS/ASP.Net Core 2.1 版本 CORS 错误
Angular / ASP.NET Core 2.1 CORS 问题