Scrutor
Scrutor copied to clipboard
Suggestion: Replace method
Scrutor API provides an easy way to actually replace service instead of decorating it. For example:
services.Decorate<ISeeder>((seeder, provider) => provider.CreateInstance<NoMigrationsAppSeeder>());
where CreateInstance
is extension around ActivatorUtilities
:
public static T CreateInstance<T>(this IServiceProvider serviceProvider, params object[] parameters) =>
ActivatorUtilities.CreateInstance<T>(serviceProvider, parameters);
and NoMigrationsAppSeeder
uses default constructor.
Unfortunately this approach sometimes lead to stack overflow since Scrutor tries to resolve implementation instance even so it's not needed in this case.
My suggestion is to provide Replace
extension methods which won't resolve previous implementation and provide callbacks with IServiceProvider
only.
I understand that this could be done manually but existing Scrutor infrastructure makes it much easier to implement.
Microsoft.Extensions.DependencyInjection.Abstractions has a Replace
method.
public static IServiceCollection Replace(this IServiceCollection collection, ServiceDescriptor descriptor)
Replace only has one implementation accepting a ServiceDescriptor with no overloads. Would it be a good idea for Scrutor to add overloads for Replace? I don't know how it would handle lifetimes, it could either copy the previous lifetime or you could have ReplaceTransient
,ReplaceScoped
, etc. It might not be worth adding anything, I don't know how popular replace is.
public static bool TryReplace(this IServiceCollection collection, ServiceDescriptor descriptor);
public static void ReplaceWith<TService>(this IServiceCollection collection, Func<ServiceProvider, ServiceDescriptor> descriptor); // Let the user define the replacing provider for the matching implementation.
public static void Replace<TService>(this IServiceCollection collection, TService implementationService); // Replace with a ServiceDescriptor of the same lifetime?