Net Core 移除已注册Service

项目需要重构某个包中的某一个功能

把源码拿下来之后发现需要重写其中一个服务
但是因为该服务访问级别为internal, 需要把原来internal服务从service collection注册器中移除
注入重写之后的服务

ASP.NET Core中的DI容器最终体现为一个IServiceProvider接口, 我们将所有实现了该接口的类型及其实例统称为ServiceProvider, 它仅仅提供了唯一个GetService方法,该方法根据提供的服务类型为你提供对应的服务实例

ASP.NET Core内部真正使用的是一个实现了IServiceProvider接口的内部类型(该类型的名称为“ServiceProvider”), 我们不能直接创建该对象,只能间接地通过调用IServiceCollection接口的扩展方法BuildServiceProvider得到它。IServiceCollection接口定义在“Microsoft.Extensions.DependencyInjection”命名空间下

IServiceCollection接口实际上代表一个元素为ServiceDescriptor对象的集合,它直接继承了另一个接口IList,而ServiceCollection类实现了该接口。

体现为DI容器的ServiceProvider之所以能够根据我们给定的服务类型(一般是一个接口类型)提供一个能够开箱即用的服务实例,是因为我们预先注册了相应的服务描述信息,这些指导ServiceProvider正确实施服务提供操作的服务描述体现为如下一个ServiceDescriptor类型。

public class ServiceDescriptor
{
    public ServiceDescriptor(Type serviceType, object instance);
    public ServiceDescriptor(Type serviceType, Func<IServiceProvider, object> factory, ServiceLifetimelifetime);
    public ServiceDescriptor(Type serviceType, TypeimplementationType, ServiceLifetime lifetime);

    public Type ServiceType {  get; }
    public ServiceLifetime Lifetime {  get; }

    public Type ImplementationType {  get; }
    public object ImplementationInstance {  get; }
    public Func<IServiceProvider, object> ImplementationFactory{  get; }      
}

ASP.NET Core中的ServiceProvider是根据一个代表ServiceDescriptor集合的IServiceCollection对象创建的,当我们调用其GetService方法的时候,它会根据我们提供的服务类型找到对应的ServiceDecriptor对象。如果该ServiceDecriptor对象的ImplementationInstance属性返回一个具体的对象,该对象将直接用作被提供的服务实例

所以要移除某个服务找到其在ServiceCollection中注册的对应ServiceDesriptor就可以

public static IServiceCollection RemoveRegisteredServiceExtension(this IServiceCollection services)
{
     var descriptorDbContext = services.FirstOrDefault(descriptor => descriptor.Name == nameof(RemoveService));
            
     services.Remove(descriptorDbContext);
     return services;
}

猜你喜欢

转载自blog.csdn.net/Helloantoherday/article/details/126420508