可以只讀的 ServiceCollection
Intro
在 .NET 7 Preview 4 中,ServiceCollection
可以聲明為只讀了,這使得我們可以有效避免在構建了 ServiceProvider
之后再新增服務,導致服務注冊失敗。
Sample
在新的版本中,ServiceCollection
新增了一個 MakeReadonly()
的 API,調用之后,ServiceCollection
就不能再修改了,不能再注冊新的服務或者移除集合中的服務,再修改就會拋異常。
直接來看一個示例吧,示例代碼如下:
var?services?=?new?ServiceCollection();
services.AddSingleton<IUserIdProvider,?EnvironmentUserIdProvider>();
await?using?(var?provider?=?services.BuildServiceProvider())
{Console.WriteLine(provider.GetRequiredService<IUserIdProvider>().GetHashCode());
}Console.WriteLine(services.IsReadOnly);services.MakeReadOnly();Console.WriteLine(services.IsReadOnly);try
{services.AddSingleton<IHttpRequester,?HttpClientHttpRequester>();
}
catch?(Exception?ex)
{Console.WriteLine(ex);
}
輸出結果如下:
43942917
False
True
System.InvalidOperationException:?The?service?collection?cannot?be?modified?because?it?is?read-only.at?Microsoft.Extensions.DependencyInjection.ServiceCollection.ThrowReadOnlyException()at?Microsoft.Extensions.DependencyInjection.ServiceCollection.CheckReadOnly()at?Microsoft.Extensions.DependencyInjection.ServiceCollection.System.Collections.Generic.ICollection<Microsoft.Extensions.DependencyInjection.ServiceDescriptor>.Add(ServiceDescriptor?item)at?Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.Add(IServiceCollection?collection,?Type?serviceType,?Type?implementationType,?ServiceLifetime?lifetime)at?Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton(IServiceCollection?services,?Type?serviceType,?Type?implementationType)at?Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton[TService,TImplementation](IServiceCollection?services)at?Net7Sample.ServiceCollectionSample.MainTest()?in?C:\projects\sources\SamplesInPractice\net7Sample\Net7Sample\ServiceCollectionSample.cs:line?28
More
在新的 HostApplicationBuilder
中也借助了這個 API ,在構建 Host
的時候也會調用這個 API 來使得 ServiceCollection
中注冊的服務不能再變更,可以參考:https://github.com/dotnet/runtime/pull/68051/files#diff-e55c31d683c37cca99b7a3a274beef4a3101d53b02c9ea989e4f6310094f68ec
在我們的應用中遇到想要使 ServiceCollection
不能再修改的時候就可以考慮使用這個 API 來避免誤操作從而導致意外的 BUG
References
https://github.com/dotnet/runtime/pull/68051
https://github.com/dotnet/runtime/pull/68051/files#diff-e55c31d683c37cca99b7a3a274beef4a3101d53b02c9ea989e4f6310094f68ec
https://github.com/dotnet/runtime/issues/66126
https://github.com/WeihanLi/SamplesInPractice/blob/master/net7Sample/Net7Sample/ServiceCollectionSample.cs
.NET 7 中的 HostApplicationBuilder