diff --git a/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceProviderKeyedServiceExtensions.cs b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceProviderKeyedServiceExtensions.cs
new file mode 100644
index 0000000000..f31923f68c
--- /dev/null
+++ b/framework/src/Volo.Abp.Core/Microsoft/Extensions/DependencyInjection/ServiceProviderKeyedServiceExtensions.cs
@@ -0,0 +1,19 @@
+using System;
+using Volo.Abp;
+
+namespace Microsoft.Extensions.DependencyInjection;
+
+public static class ServiceProviderKeyedServiceExtensions
+{
+ public static object? GetKeyedService(this IServiceProvider provider, Type serviceType, object? serviceKey)
+ {
+ Check.NotNull(provider, nameof(provider));
+
+ if (provider is IKeyedServiceProvider keyedServiceProvider)
+ {
+ return keyedServiceProvider.GetKeyedService(serviceType, serviceKey);
+ }
+
+ throw new InvalidOperationException("This service provider doesn't support keyed services.");
+ }
+}
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceDescriptor.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceDescriptor.cs
index 1b812fc4a2..b6dbcd8a02 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceDescriptor.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceDescriptor.cs
@@ -2,28 +2,53 @@ using System;
namespace Volo.Abp.DependencyInjection;
-public class CachedServiceDescriptor
+///
+/// https://github.com/dotnet/runtime/blob/release/8.0/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/ServiceIdentifier.cs#L9
+///
+public readonly struct ServiceIdentifier : IEquatable
{
- private object? Key { get; }
+ public object? ServiceKey { get; }
- private Type ServiceType { get; }
+ public Type ServiceType { get; }
- public CachedServiceDescriptor(object? key, Type serviceType)
+ public ServiceIdentifier(Type serviceType)
{
- Key = key;
ServiceType = serviceType;
}
+ public ServiceIdentifier(object? serviceKey, Type serviceType)
+ {
+ ServiceKey = serviceKey;
+ ServiceType = serviceType;
+ }
+
+ public bool Equals(ServiceIdentifier other)
+ {
+ if (ServiceKey == null && other.ServiceKey == null)
+ {
+ return ServiceType == other.ServiceType;
+ }
+ else if (ServiceKey != null && other.ServiceKey != null)
+ {
+ return ServiceType == other.ServiceType && ServiceKey.Equals(other.ServiceKey);
+ }
+ return false;
+ }
+
public override bool Equals(object? obj)
{
- return obj is CachedServiceDescriptor descriptor &&
- Key == descriptor.Key &&
- ServiceType == descriptor.ServiceType;
+ return obj is ServiceIdentifier && Equals((ServiceIdentifier)obj);
}
public override int GetHashCode()
{
- var keyHashCode = Key?.GetHashCode() ?? 0;
- return keyHashCode ^ ServiceType.GetHashCode();
+ if (ServiceKey == null)
+ {
+ return ServiceType.GetHashCode();
+ }
+ unchecked
+ {
+ return (ServiceType.GetHashCode() * 397) ^ ServiceKey.GetHashCode();
+ }
}
}
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs
index 774efedb9a..770355428e 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs
@@ -7,19 +7,19 @@ namespace Volo.Abp.DependencyInjection;
public abstract class CachedServiceProviderBase : ICachedServiceProviderBase
{
protected IServiceProvider ServiceProvider { get; }
- protected ConcurrentDictionary> CachedServices { get; }
+ protected ConcurrentDictionary> CachedServices { get; }
protected CachedServiceProviderBase(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
- CachedServices = new ConcurrentDictionary>();
- CachedServices.TryAdd(new CachedServiceDescriptor(null, typeof(IServiceProvider)), new Lazy