自從.Net Core引入IOC相關的體系之後,關於它的討論就從來沒有停止過,因為它是.Net Core體系的底層框架,你只要使用了.Net Core的時候就必然會用到它。當然關於使用它的過程中產生的問題也從來沒停止過。我對待問題的態度向來都是,如果你踩到了坑,說明你還沒有足夠了解它,所以我們對它認知的突破,很多時候是遇到了問題並解決了問題。今天的話題呢,也是一個群友在研究.Net Core作用域的過程中產生的疑問,博主呢對這個問題也很有興趣,就藉此機會探究了一下,把自己研究結果分享給大家。
在日常的開發中使用CreateScope()
或CreateAsyncScope()
的場景可能沒有那麼多,但是在ASP.NET Core底層的話這是核心設計,在上篇文章<解決ASP.NET Core在Task中使用IServiceProvider的問題>中提到過,ASP.NET Core會為每次請求建立一個Scope
,也就是咱們這次提到的作用域。使用的方法有很簡單,本質就是IServiceProvider
的一個擴充套件方法。咱們今天主要說的就是ServiceLifetime.Scoped
這個比較特殊的生命週期,在Scope內是如何工作的,原始點的寫法其實就是
IServiceCollection services = new ServiceCollection();
services.AddScoped<Person>(provider => new() { Id = 1, Name = "yi念之間", Sex = "Man" });
IServiceProvider serviceProvider = services.BuildServiceProvider();
using (IServiceScope serviceScope = serviceProvider.CreateScope())
{
var personOne = serviceScope.ServiceProvider.GetService<Person>();
Console.WriteLine(person.Name);
}
如果在ASP.NET Core框架裡那玩法就多了,只要有IServiceProvide
的地方都可以使用CreateScope()
或CreateAsyncScope()
方法,簡單演示一下,但是如果感覺自己把握不住的話還是提前自己試驗一下
[HttpGet]
public async Task<object> JudgeScope([FromServices]IServiceProvider scopeProvider)
{
using IServiceScope scope = HttpContext.RequestServices.CreateScope();
Person person = scope.ServiceProvider.GetService<Person>();
await using (AsyncServiceScope scope2 = scopeProvider.CreateAsyncScope())
{
Person person2 = scope2.ServiceProvider.GetService<Person>();
}
return person;
}
通過上面的範例,我們可以看到其實關於IServiceScope
的操作部分就是三個核心。
CreateScope()
或CreateAsyncScope()
方法建立服務作用域。GetService
相關的方法建立需要的物件範例。Dispose()
或者DisposeAsync()
方法(using的方式同理)釋放作用域。為了怕大家心裡有疑慮,因為使用CreateScope()
方法建立出來的是IServiceScope
範例,使用CreateAsyncScope
方法建立的是AsyncServiceScope
範例。咱們這裡先來說一下AsyncServiceScope
和IServiceScope
的關係,看了之後大家就不用惦記它了,先來看一下CreateAsyncScope()
方法的定義[點選檢視原始碼