Let us consider a service registration in Startup.ConfigureServices
:
public void ConfigureServices(IServiceCollection services)
{
services.A
It is easy to override ASP.NET Core DI functionality if you know two simple things:
List
: public class ServiceCollection : IServiceCollection
{
private List _descriptors = new List();
}
private static IServiceCollection Add(
IServiceCollection collection,
Type serviceType,
Type implementationType,
ServiceLifetime lifetime)
{
var descriptor = new ServiceDescriptor(serviceType, implementationType, lifetime);
collection.Add(descriptor);
return collection;
}
Therefore, it is possible to add/remove descriptors to/from this list to replace the registration:
IFoo service = services.BuildServiceProvider().GetService();
Assert.True(service is FooA);
var descriptor = services.FirstOrDefault(d => d.ServiceType == typeof(IFoo));
Assert.NotNull(descriptor);
services.Remove(descriptor);
service = services.BuildServiceProvider().GetService();
Assert.Null(service);
We finish with Replace
extention method:
services.Replace(ServiceLifetime.Transient);
Its implementation:
public static IServiceCollection Replace(
this IServiceCollection services,
ServiceLifetime lifetime)
where TService : class
where TImplementation : class, TService
{
var descriptorToRemove = services.FirstOrDefault(d => d.ServiceType == typeof(TService));
services.Remove(descriptorToRemove);
var descriptorToAdd = new ServiceDescriptor(typeof(TService), typeof(TImplementation), lifetime);
services.Add(descriptorToAdd);
return services;
}