Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove a service in ASP.Net Core Dependency Injection [duplicate]

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 ?

like image 290
kall2sollies Avatar asked Mar 22 '17 08:03

kall2sollies


People also ask

How do you dispose of resources using dependency injection?

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.

Should services be singleton or transient?

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.

Do transient services get disposed?

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.

What is IServiceCollection in .NET core?

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.


1 Answers

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;     } } 
like image 194
Andrii Litvinov Avatar answered Sep 19 '22 09:09

Andrii Litvinov