在单例服务中使用瞬态服务
Posted
技术标签:
【中文标题】在单例服务中使用瞬态服务【英文标题】:Using Transient service within a Singleton Service 【发布时间】:2021-09-08 07:46:04 【问题描述】:我正在使用 ASP.Net Core 3.1 Web API。当我接到对控制器操作方法的调用时,我需要在后台执行额外的活动,而不会在当前操作的处理中增加太多延迟。我正在执行的其他活动是将一些数据准备到缓存中,以便在用户执行下一步之前可用。所以我想简单地触发该活动,而无需等待它完成。但同时,我不希望任务没有完成就被释放,仅仅因为动作方法完成了它的处理,将响应返回给调用者并且瞬态控制器被释放了。
所以我打算使用注入控制器的单例服务来执行任务。但任务本身可能涉及需要使用临时服务。因此,我不是直接将瞬态服务注入单例服务,而是考虑将瞬态服务注入控制器。然后在 action 方法中,我会将瞬态服务作为参数传递给 Singleton 服务上的异步方法,然后在该方法中调用所需的服务。
public IActionResult GetSomething(string input1)
var resp = await _transientService1.GetSomethingElse(input1);
// I am not awaiting this task
var backgroundTask = _singletonService1.DoSomethingAsync(_transientService2, resp.someattr);
return Ok(resp);
现在在单例服务中,我将获取所需的数据并将其写入缓存。
public async Task DoSomethingAsync(ITransientService2 myTransientService2, string someParam)
var temp1 = await myTransientService2.GetSomethingNew(someParam);
var temp2 = await _SingletonService2.WriteCache(temp1);
所以我首先想知道这种方法是否可行。如果可行,我需要注意哪些陷阱或陷阱。
目前,这都是概念性的。否则我会直接尝试:)因此问题。
【问题讨论】:
我会说这是使用background tasks with hosted services in ASP.NET Core的好地方。 您可能想质疑您是如何在控制器和后台进程之间传递信息的。那里有臭虫味。如果单例确实是一个后台进程,要求它从请求线程中执行操作可能会引入一些可以通过请求队列避免的同步问题。 【参考方案1】:只要您对将依赖项作为参数传递感到满意,它就可以工作。
如果您不想将瞬态依赖项作为参数传递,另一种选择是将IServiceProvider
注入单例服务,并在需要时实例化瞬态服务。
class MySingleton
private readonly IServiceProvider _serviceProvider;
public MySingleton(IServiceProvider serviceProvider)
_serviceProvider = serviceProvider;
public async Task ExecuteAsync()
// The scope informs the service provider when you're
// done with the transient service so it can be disposed
using (var scope = _serviceProvider.CreateScope())
var transientService = scope.ServiceProvider.GetRequiredService<MyTransientService>();
await transientService.DoSomethingAsync();
【讨论】:
以上是关于在单例服务中使用瞬态服务的主要内容,如果未能解决你的问题,请参考以下文章