From 70b69590a1ab48810bd23a67a4fc19bf4eece142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 30 Nov 2022 09:56:30 +0300 Subject: [PATCH 1/6] Fix AbpLazyServiceProvider.LazyGetRequiredService It should not return null, but throw exception if a service was not found. --- .../Abp/DependencyInjection/AbpLazyServiceProvider.cs | 2 +- .../Abp/DependencyInjection/CachedServiceProviderBase.cs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs index 3aff8a78ad..7a18689dbe 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs @@ -17,7 +17,7 @@ public class AbpLazyServiceProvider : CachedServiceProviderBase, IAbpLazyService public virtual object LazyGetRequiredService(Type serviceType) { - return GetService(serviceType); + return GetRequiredService(serviceType); } public virtual T LazyGetService() 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 c261d3a3bb..2116ec8fb7 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using Microsoft.Extensions.DependencyInjection; namespace Volo.Abp.DependencyInjection; @@ -22,4 +23,12 @@ public abstract class CachedServiceProviderBase _ => new Lazy(() => ServiceProvider.GetService(serviceType)) ).Value; } + + public virtual object GetRequiredService(Type serviceType) + { + return CachedServices.GetOrAdd( + serviceType, + _ => new Lazy(() => ServiceProvider.GetRequiredService(serviceType)) + ).Value; + } } From 740312cc6720a07c01446f7a4d07bbaedf6c9e2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 30 Nov 2022 10:45:00 +0300 Subject: [PATCH 2/6] Inherit IAbpLazyServiceProvider from IServiceProvider Provide methods without Lazy prefix. --- .../AbpLazyServiceProvider.cs | 46 ++++++++++++++---- .../CachedServiceProviderBase.cs | 10 +--- .../IAbpLazyServiceProvider.cs | 48 ++++++++++++++++++- 3 files changed, 84 insertions(+), 20 deletions(-) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs index 7a18689dbe..8af18416ff 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs @@ -1,15 +1,42 @@ using System; +using Microsoft.Extensions.DependencyInjection; namespace Volo.Abp.DependencyInjection; [ExposeServices(typeof(IAbpLazyServiceProvider))] -public class AbpLazyServiceProvider : CachedServiceProviderBase, IAbpLazyServiceProvider, ITransientDependency +public class AbpLazyServiceProvider : + CachedServiceProviderBase, + IAbpLazyServiceProvider, + ITransientDependency { public AbpLazyServiceProvider(IServiceProvider serviceProvider) : base(serviceProvider) { } + public T GetService(T defaultValue) + { + return (T)GetService(typeof(T), defaultValue); + } + + public object GetService(Type serviceType, object defaultValue) + { + return GetService(serviceType) ?? defaultValue; + } + + public T GetService(Func factory) + { + return (T)GetService(typeof(T), factory); + } + + public object GetService(Type serviceType, Func factory) + { + return CachedServices.GetOrAdd( + serviceType, + _ => new Lazy(() => factory(ServiceProvider)) + ).Value; + } + public virtual T LazyGetRequiredService() { return (T)LazyGetRequiredService(typeof(T)); @@ -17,7 +44,7 @@ public class AbpLazyServiceProvider : CachedServiceProviderBase, IAbpLazyService public virtual object LazyGetRequiredService(Type serviceType) { - return GetRequiredService(serviceType); + return this.GetRequiredService(serviceType); } public virtual T LazyGetService() @@ -30,26 +57,27 @@ public class AbpLazyServiceProvider : CachedServiceProviderBase, IAbpLazyService return GetService(serviceType); } + #region Old Methods + public virtual T LazyGetService(T defaultValue) { - return (T)LazyGetService(typeof(T), defaultValue); + return GetService(defaultValue); } public virtual object LazyGetService(Type serviceType, object defaultValue) { - return LazyGetService(serviceType) ?? defaultValue; + return GetService(serviceType, defaultValue); } public virtual T LazyGetService(Func factory) { - return (T)LazyGetService(typeof(T), factory); + return GetService(factory); } public virtual object LazyGetService(Type serviceType, Func factory) { - return CachedServices.GetOrAdd( - serviceType, - _ => new Lazy(() => factory(ServiceProvider)) - ).Value; + return GetService(serviceType, factory); } + + #endregion } 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 2116ec8fb7..49da116fea 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.DependencyInjection; namespace Volo.Abp.DependencyInjection; -public abstract class CachedServiceProviderBase +public abstract class CachedServiceProviderBase : IServiceProvider { protected IServiceProvider ServiceProvider { get; } protected ConcurrentDictionary> CachedServices { get; } @@ -23,12 +23,4 @@ public abstract class CachedServiceProviderBase _ => new Lazy(() => ServiceProvider.GetService(serviceType)) ).Value; } - - public virtual object GetRequiredService(Type serviceType) - { - return CachedServices.GetOrAdd( - serviceType, - _ => new Lazy(() => ServiceProvider.GetRequiredService(serviceType)) - ).Value; - } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs index 610bb40dfa..bfe08026ca 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs @@ -2,21 +2,65 @@ namespace Volo.Abp.DependencyInjection; -public interface IAbpLazyServiceProvider +public interface IAbpLazyServiceProvider : IServiceProvider { + T GetService(T defaultValue); + + object GetService(Type serviceType, object defaultValue); + + T GetService(Func factory); + + object GetService(Type serviceType, Func factory); + + #region Old Methods + + /// + /// This method is equivalent of the GetRequiredService method. + /// It does exists for backward compatibility. + /// T LazyGetRequiredService(); + /// + /// This method is equivalent of the GetRequiredService method. + /// It does exists for backward compatibility. + /// object LazyGetRequiredService(Type serviceType); + /// + /// This method is equivalent of the GetService method. + /// It does exists for backward compatibility. + /// T LazyGetService(); + /// + /// This method is equivalent of the GetService method. + /// It does exists for backward compatibility. + /// object LazyGetService(Type serviceType); + /// + /// This method is equivalent of the method. + /// It does exists for backward compatibility. + /// T LazyGetService(T defaultValue); - + + /// + /// This method is equivalent of the method. + /// It does exists for backward compatibility. + /// object LazyGetService(Type serviceType, object defaultValue); + /// + /// This method is equivalent of the method. + /// It does exists for backward compatibility. + /// object LazyGetService(Type serviceType, Func factory); + /// + /// This method is equivalent of the method. + /// It does exists for backward compatibility. + /// T LazyGetService(Func factory); + + #endregion } From 0a061ad4e3b2d5813a44213fb3dfd499ac78e2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 30 Nov 2022 10:53:08 +0300 Subject: [PATCH 3/6] Equalize IAbpLazyServiceProvider and ITransientCachedServiceProvider To reduce cached service provider service count. --- .../AbpLazyServiceProvider.cs | 29 ++++--------------- .../CachedServiceProviderBase.cs | 26 +++++++++++++++-- .../IAbpLazyServiceProvider.cs | 26 ++++++----------- .../ICachedServiceProvider.cs | 6 ++-- .../ICachedServiceProviderBase.cs | 14 +++++++++ .../ITransientCachedServiceProvider.cs | 4 +-- 6 files changed, 55 insertions(+), 50 deletions(-) create mode 100644 framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProviderBase.cs diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs index 8af18416ff..60d4afd40c 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs @@ -3,6 +3,10 @@ using Microsoft.Extensions.DependencyInjection; namespace Volo.Abp.DependencyInjection; +/// +/// This class is equivalent of the . +/// Use instead of this class, for new projects. +/// [ExposeServices(typeof(IAbpLazyServiceProvider))] public class AbpLazyServiceProvider : CachedServiceProviderBase, @@ -13,29 +17,8 @@ public class AbpLazyServiceProvider : : base(serviceProvider) { } - - public T GetService(T defaultValue) - { - return (T)GetService(typeof(T), defaultValue); - } - - public object GetService(Type serviceType, object defaultValue) - { - return GetService(serviceType) ?? defaultValue; - } - - public T GetService(Func factory) - { - return (T)GetService(typeof(T), factory); - } - public object GetService(Type serviceType, Func factory) - { - return CachedServices.GetOrAdd( - serviceType, - _ => new Lazy(() => factory(ServiceProvider)) - ).Value; - } + #region Old Methods public virtual T LazyGetRequiredService() { @@ -57,8 +40,6 @@ public class AbpLazyServiceProvider : return GetService(serviceType); } - #region Old Methods - public virtual T LazyGetService(T defaultValue) { return GetService(defaultValue); 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 49da116fea..21f2b1c516 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProviderBase.cs @@ -1,10 +1,9 @@ using System; using System.Collections.Concurrent; -using Microsoft.Extensions.DependencyInjection; namespace Volo.Abp.DependencyInjection; -public abstract class CachedServiceProviderBase : IServiceProvider +public abstract class CachedServiceProviderBase : ICachedServiceProviderBase { protected IServiceProvider ServiceProvider { get; } protected ConcurrentDictionary> CachedServices { get; } @@ -23,4 +22,27 @@ public abstract class CachedServiceProviderBase : IServiceProvider _ => new Lazy(() => ServiceProvider.GetService(serviceType)) ).Value; } + + public T GetService(T defaultValue) + { + return (T)GetService(typeof(T), defaultValue); + } + + public object GetService(Type serviceType, object defaultValue) + { + return GetService(serviceType) ?? defaultValue; + } + + public T GetService(Func factory) + { + return (T)GetService(typeof(T), factory); + } + + public object GetService(Type serviceType, Func factory) + { + return CachedServices.GetOrAdd( + serviceType, + _ => new Lazy(() => factory(ServiceProvider)) + ).Value; + } } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs index bfe08026ca..cd5f1da67f 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/IAbpLazyServiceProvider.cs @@ -2,18 +2,12 @@ namespace Volo.Abp.DependencyInjection; -public interface IAbpLazyServiceProvider : IServiceProvider +/// +/// This service is equivalent of the . +/// Use instead of this interface, for new projects. +/// +public interface IAbpLazyServiceProvider : ICachedServiceProviderBase { - T GetService(T defaultValue); - - object GetService(Type serviceType, object defaultValue); - - T GetService(Func factory); - - object GetService(Type serviceType, Func factory); - - #region Old Methods - /// /// This method is equivalent of the GetRequiredService method. /// It does exists for backward compatibility. @@ -39,28 +33,26 @@ public interface IAbpLazyServiceProvider : IServiceProvider object LazyGetService(Type serviceType); /// - /// This method is equivalent of the method. + /// This method is equivalent of the method. /// It does exists for backward compatibility. /// T LazyGetService(T defaultValue); /// - /// This method is equivalent of the method. + /// This method is equivalent of the method. /// It does exists for backward compatibility. /// object LazyGetService(Type serviceType, object defaultValue); /// - /// This method is equivalent of the method. + /// This method is equivalent of the method. /// It does exists for backward compatibility. /// object LazyGetService(Type serviceType, Func factory); /// - /// This method is equivalent of the method. + /// This method is equivalent of the method. /// It does exists for backward compatibility. /// T LazyGetService(Func factory); - - #endregion } diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProvider.cs index 073daa135a..4a923901f9 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProvider.cs @@ -1,6 +1,4 @@ -using System; - -namespace Volo.Abp.DependencyInjection; +namespace Volo.Abp.DependencyInjection; /// /// Provides services by caching the resolved services. @@ -8,7 +6,7 @@ namespace Volo.Abp.DependencyInjection; /// This service's lifetime is scoped and it should be used /// for a limited scope. /// -public interface ICachedServiceProvider : IServiceProvider +public interface ICachedServiceProvider : ICachedServiceProviderBase { } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProviderBase.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProviderBase.cs new file mode 100644 index 0000000000..2e15a45a46 --- /dev/null +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ICachedServiceProviderBase.cs @@ -0,0 +1,14 @@ +using System; + +namespace Volo.Abp.DependencyInjection; + +public interface ICachedServiceProviderBase : IServiceProvider +{ + T GetService(T defaultValue); + + object GetService(Type serviceType, object defaultValue); + + T GetService(Func factory); + + object GetService(Type serviceType, Func factory); +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ITransientCachedServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ITransientCachedServiceProvider.cs index 55c43e7c94..7b57b54e07 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ITransientCachedServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/ITransientCachedServiceProvider.cs @@ -1,5 +1,3 @@ -using System; - namespace Volo.Abp.DependencyInjection; /// @@ -8,7 +6,7 @@ namespace Volo.Abp.DependencyInjection; /// This service's lifetime is transient. /// for the one with scoped lifetime. /// -public interface ITransientCachedServiceProvider : IServiceProvider +public interface ITransientCachedServiceProvider : ICachedServiceProviderBase { } \ No newline at end of file From 184e50e6e6f109477b8c7e51699da014aaab5f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 30 Nov 2022 11:13:23 +0300 Subject: [PATCH 4/6] Added "Cached Service Providers" section to the document --- docs/en/Dependency-Injection.md | 33 +++++++++++++++++++ .../CachedServiceProvider.cs | 1 - 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/docs/en/Dependency-Injection.md b/docs/en/Dependency-Injection.md index 147ef1689a..c59b371018 100644 --- a/docs/en/Dependency-Injection.md +++ b/docs/en/Dependency-Injection.md @@ -403,6 +403,39 @@ using (var scope = _serviceProvider.CreateScope()) Both services are released when the created scope is disposed (at the end of the `using` block). +### Cached Service Providers + +ABP provides two special services to optimize resolving services from `IServiceProvider`. `ICachedServiceProvider` and `ITransientCachedServiceProvider` both inherits from the `IServiceProvider` interface and internally caches the resolved services, so you get the same service instance even if you resolve a service multiple times. + +The main difference is the `ICachedServiceProvider` is itself registered as scoped, while the `ITransientCachedServiceProvider` is registered as transient to the dependency injection system. + +The following example injects the `ICachedServiceProvider` service and resolves a service in the `DoSomethingAsync` method: + +````csharp +public class MyService : ITransientDependency +{ + private readonly ICachedServiceProvider _serviceProvider; + + public MyService(ICachedServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public async Task DoSomethingAsync() + { + var taxCalculator = _serviceProvider.GetRequiredService(); + // TODO: Use the taxCalculator + } +} + +```` + +With such a usage, you don't need to deal with creating service scopes and disposing the resolved services (as explained in the *Releasing/Disposing Services* section above). Because all the services resolved from the `ICachedServiceProvider` will be released once the service scope of the `MyService` instance is disposed. Also, you don't need to care about memory leaks (because of creating too many `ITaxCalculator` instances if we call `DoSomethingAsync` too many times), because only one `ITaxCalculator` instance is created, and it is reused. + +Use `ICachedServiceProvider` (instead of `ITransientCachedServiceProvider`) unless you need to create the service cache per usage. `ITransientCachedServiceProvider` guarantees that the created service instances are not shared with any other service, even they are in the same service scope. The services resolved from `ICachedServiceProvider` are shared with other services in the same service scope (in the same HTTP Request, for example), so it can be thought as more optimized. + +> ABP Framework also provides the `IAbpLazyServiceProvider` service. It does exists for backward compatibility and works exactly same with the `ITransientCachedServiceProvider` service. So, use the `ITransientCachedServiceProvider` since the `IAbpLazyServiceProvider` might be removed in future ABP versions. + ## Advanced Features ### IServiceCollection.OnRegistred Event diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProvider.cs index 870e1f8faf..ef0fed3541 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/CachedServiceProvider.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; namespace Volo.Abp.DependencyInjection; From 84750d9d74bb85020a47f8a084c211705d359e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 30 Nov 2022 11:15:48 +0300 Subject: [PATCH 5/6] Update AbpLazyServiceProvider.cs --- .../Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs index 60d4afd40c..a180592a01 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/DependencyInjection/AbpLazyServiceProvider.cs @@ -18,8 +18,6 @@ public class AbpLazyServiceProvider : { } - #region Old Methods - public virtual T LazyGetRequiredService() { return (T)LazyGetRequiredService(typeof(T)); @@ -59,6 +57,4 @@ public class AbpLazyServiceProvider : { return GetService(serviceType, factory); } - - #endregion } From 790c0bb763b7d621b6aebb794a978e83928f9a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 30 Nov 2022 11:22:10 +0300 Subject: [PATCH 6/6] Update Dependency-Injection.md --- docs/en/Dependency-Injection.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/en/Dependency-Injection.md b/docs/en/Dependency-Injection.md index c59b371018..47e60700bc 100644 --- a/docs/en/Dependency-Injection.md +++ b/docs/en/Dependency-Injection.md @@ -432,6 +432,8 @@ public class MyService : ITransientDependency With such a usage, you don't need to deal with creating service scopes and disposing the resolved services (as explained in the *Releasing/Disposing Services* section above). Because all the services resolved from the `ICachedServiceProvider` will be released once the service scope of the `MyService` instance is disposed. Also, you don't need to care about memory leaks (because of creating too many `ITaxCalculator` instances if we call `DoSomethingAsync` too many times), because only one `ITaxCalculator` instance is created, and it is reused. +Since `ICachedServiceProvider` and `ITransientCachedServiceProvider` extends the standard `IServiceProvider` interface, you can use all the extension method of the `IServiceProvider` interface on them. In addition, they provides some other methods to provide a default value or a factory method for the services that are not found (that means not registered to the dependency injection system). Notice that the default value (or the value returned from your factory method) is also cached and reused. + Use `ICachedServiceProvider` (instead of `ITransientCachedServiceProvider`) unless you need to create the service cache per usage. `ITransientCachedServiceProvider` guarantees that the created service instances are not shared with any other service, even they are in the same service scope. The services resolved from `ICachedServiceProvider` are shared with other services in the same service scope (in the same HTTP Request, for example), so it can be thought as more optimized. > ABP Framework also provides the `IAbpLazyServiceProvider` service. It does exists for backward compatibility and works exactly same with the `ITransientCachedServiceProvider` service. So, use the `ITransientCachedServiceProvider` since the `IAbpLazyServiceProvider` might be removed in future ABP versions.