.net core IOC容器实现(一) — ServiceDescriptor

  • .net core IOC容器实现(一) — ServiceDescriptor已关闭评论
  • 200 次浏览
  • A+
所属分类:.NET技术
摘要

IOC 容器内保存的程序运行过程中使用的服务实例。那么如果有些服务实例需要在运行时动态生成,比如,数据库连接,不可能在程序运行过程中所有线程共用一条数据库连接。所以 IOC 容器内保存的不是具体的服务实例,而是服务的相关信息,使用这个信息可以在程序运行时动态的生成服务实例,这些信息就保存在 ServiceDescriptor 类型的对象中。

IOC 容器内保存的程序运行过程中使用的服务实例。那么如果有些服务实例需要在运行时动态生成,比如,数据库连接,不可能在程序运行过程中所有线程共用一条数据库连接。所以 IOC 容器内保存的不是具体的服务实例,而是服务的相关信息,使用这个信息可以在程序运行时动态的生成服务实例,这些信息就保存在 ServiceDescriptor 类型的对象中。

属性

//生命周期  //Singleton 容器内有且只有一份 //Scope 范围内只有一份,范围 可以使用 ServicePorvider.CreateScope 创建(可以将容器理解成树状结构每个Scope就是一个子容器),最常见的范围就是 Http 请求,每个请求算一个范围 //Trasient 每次从IOC容器获取都是新的实例 public ServiceLifetime Lifetime { get; }    //接口类型  接口类型和实现类型可以相同 public Type ServiceType { get; }      //实现类型 [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]public Type? ImplementationType { get; }          //实现实例   public object? ImplementationInstance { get; }    //实现类型工厂  public Func<IServiceProvider, object>? ImplementationFactory { get; } 

构造函数

  1. private 构造函数
    先介绍一个 private 的构造函数,个人认为这个构造函数设计为private有两个原因
  • 实例化出来的所有 ServiceDescriptor 对象都具有 serviceType 和 lifetime,所以这两个属性的赋值可以被单独剥离
  • 由于所有 ServiceDescriptor 必须要描述服务实例的构造方式,所以不能允许外部直接调用这个构造函数生成ServiceDescriptor实例,所以是 private 的
  1. public 构造函数
    根据服务的生命周期和生成方式有三种不同的 public 的构造函数。
  • Singleton
public ServiceDescriptor( Type serviceType,object instance)     : this(serviceType, ServiceLifetime.Singleton) {     //.....     ImplementationInstance = instance; } 
  • Scope 和 Trasient
    • 通过注入的实例类型通过反射获取
public ServiceDescriptor(Type serviceType,Type implementationType,ServiceLifetime lifetime)             : this(serviceType, lifetime) {      // ....      ImplementationType = implementationType; } 
    • 通过传入的 构造工厂(委托)获取
public ServiceDescriptor( Type serviceType,  //服务类型          Func<IServiceProvider, object> factory,       //创建服务的工厂      ServiceLifetime lifetime    //服务的生命周期 ): this(serviceType, lifetime)    {                      ImplementationFactory = factory;         } 

方法

ServiceDescriptor 里的方法都是静态方法,用于生成 ServiceDescriptor 实例。
核心 是要获取 注入的接口类型 和 实例类型或者生成实例的工厂,所以调用 Describe 方法之后,最终还是两个方法,一个保存了 接口类型和实例类型,一个保存了 接口类型和生成实例的工厂(),下面贴出来的是生成 Trasient 的 ServcieDescriptor 的方法,生成 Scope 和 Singleton 的与之类似

//使用TService, TImplementation 生成 ServiceDescriptor(Transient)   // TService 接口类型 // TImplementation 实现类型 继承 TService public static ServiceDescriptor Transient <TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>()             where TService : class             where TImplementation : class, TService         {                 return Describe<TService, TImplementation>(ServiceLifetime.Transient);         }  // service 接口类型 // implementationType 实现类型 // lifetime 生命周期 public static ServiceDescriptor Describe(                 Type serviceType,                 [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType,            ServiceLifetime lifetime )         {                 return new ServiceDescriptor(serviceType, implementationType, lifetime);         }