In an Asp.Net MVC Core (early versions, versions 1.0 or 1.1), dependency injection bindings are configured as follow in the Startup.cs class :
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddScoped<IMyService, MyService>(); // ... } }
In my applications, I usually have a base Startup class, where generic bindings are defined as a sequence of these lines :
public abstract class BaseStartup { public virtual void ConfigureServices(IServiceCollection services) { services.AddScoped<IMyService1, MyService1>(); services.AddScoped<IMyService2, MyService2>(); } }
Then in my application, I inherit the startup class, and inject other services as well :
public class Startup : BaseStartup { public override void ConfigureServices(IServiceCollection services) { base.ConfigureServices(services); services.AddScoped<IMyService3, MyService3>(); services.AddScoped<IMyService4, MyService4>(); } }
I now wonder : how can I kind of 'override' a previous binding ? I would like, for instance, to either remove, or modify a binding defined in the base class, like :
services.Remove<IMyService1>(); // Doesn't exist services.AddScoped<IMyService1, MyBetterService1>();
Or simply update the binding :
services.AddScoped<IMyService1, MyBetterService1>(replacePreviousBinding: true); // Doesn't exist either !
Is there a way to do that ? Or maybe simply declaring a new binding with the same interface as a previously defined binding will override that binding ?
When you make it explicit, you've got basically two options: 1. Configure the DI to return transient objects and dispose these objects yourself. 2. Configure a factory and instruct the factory to create new instances.
Use Transient lifetime for the lightweight service with little or no state. Scoped services service is the better option when you want to maintain state within a request. Singletons are created only once and not destroyed until the end of the Application. Any memory leaks in these services will build up over time.
Disposable transient services are captured by the container for disposal. This can turn into a memory leak if resolved from the top-level container. Enable scope validation to make sure the app doesn't have singletons that capture scoped services.
AddScoped(IServiceCollection, Type, Type) Adds a scoped service of the type specified in serviceType with an implementation of the type specified in implementationType to the specified IServiceCollection.
You can use normal collection API to remove your services:
services.AddScoped<IService>(); var serviceDescriptor = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(IService)); services.Remove(serviceDescriptor);
Also you can create extension methods to achieve the same:
public static class ServiceCollectionExtensions { public static IServiceCollection Remove<T>(this IServiceCollection services) { if (services.IsReadOnly) { throw new ReadOnlyException($"{nameof(services)} is read only"); } var serviceDescriptor = services.FirstOrDefault(descriptor => descriptor.ServiceType == typeof(T)); if (serviceDescriptor != null) services.Remove(serviceDescriptor); return services; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With