首页 > 其他分享 >ioc

ioc

时间:2024-09-04 11:51:56浏览次数:15  
标签:serviceType return ioc serviceRegistry var Ioc public

 public class Ioc : IServiceProvider
 {
     private Ioc _root;
     private ConcurrentDictionary<Type, ServiceRegistry> _registries = new ConcurrentDictionary<Type, ServiceRegistry>();
     private ConcurrentDictionary<Type, object?> _services = new ConcurrentDictionary<Type, object?>();

     public Ioc()
     {
         this._root = this;
     }

     public Ioc(Ioc parent)
     {
         this._root = parent._root;
         this._services = parent._services;
     }

     public Ioc CreateScope()
     {
         return new Ioc(this);
     }

     public Ioc Register(ServiceRegistry serviceRegistry)
     {
         if (_registries.TryGetValue(serviceRegistry.ServiceType, out var exist))
         {
             serviceRegistry.Next = exist;
         }

         _registries[serviceRegistry.ServiceType] = serviceRegistry;

         return this;
     }

     public bool HasRegistry(Type serviceType)
     {
         return _services.ContainsKey(serviceType);
     }

     public object? GetService(Type serviceType)
     {
         // ioc 直接返回自己
         if (serviceType == typeof(Ioc) || serviceType == typeof(IServiceProvider))
         {
             return this;
         }

         ServiceRegistry? registry;

         // 服务类型为IEnumerable<T>
         if (serviceType.IsGenericType && serviceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
         {
             // 未注册,返回空数组
             var elementType = serviceType.GetGenericArguments()[0];
             if (!_registries.TryGetValue(elementType, out registry))
             {
                 return Array.CreateInstance(elementType, 0);
             }

             // 已注册,则从容器中获取所有实例
             var registries = registry.AsEnumerable();
             var services = registries.Select(it => GetServiceCore(it, new Type[0])).ToArray();
             Array array = Array.CreateInstance(elementType, services.Length);
             services.CopyTo(array, 0);
             return array;
         }

         // 泛型
         if (serviceType.IsGenericType && !_registries.ContainsKey(serviceType))
         {
             var definition = serviceType.GetGenericTypeDefinition();
             return _registries.TryGetValue(definition, out registry)
                 ? GetServiceCore(registry, serviceType.GetGenericArguments())
                 : null;
         }

         // 默认
         return _registries.TryGetValue(serviceType, out registry)
            ? GetServiceCore(registry, new Type[0])
            : null;
     }

     private object? GetServiceCore(ServiceRegistry serviceRegistry, Type[] genericArguments)
     {
         switch (serviceRegistry.LifeTime)
         {
             case LifeTime.Scope:
                 return GetOrCreate(serviceRegistry, genericArguments);
             case LifeTime.Singleton:
                 return _root.GetOrCreate(serviceRegistry, genericArguments);
             default:
                 return serviceRegistry.Factory(this, genericArguments);
         }
     }

     private object? GetOrCreate(ServiceRegistry serviceRegistry, Type[] genericArguments)
     {
         if (_services.TryGetValue(serviceRegistry.ServiceType, out var service))
         {
             return service;
         }

         var instance = serviceRegistry.Factory(this, genericArguments);
         _services.TryAdd(serviceRegistry.ServiceType, instance);
         return instance;
     }
 }

 public static class IocExtensions
 {
     public static Ioc Register(this Ioc ioc, Type serviceType, Type implType, LifeTime lifetime)
     {
         Func<Ioc, Type[], object?> factory = (_, arguments) => Create(_, implType, arguments);
         ioc.Register(new ServiceRegistry(serviceType, lifetime, factory));
         return ioc;
     }

     public static Ioc Register<TFrom, TTo>(this Ioc ioc, LifeTime lifetime) where TTo : TFrom
          => ioc.Register(typeof(TFrom), typeof(TTo), lifetime);

     public static Ioc Register<TServiceType>(this Ioc ioc, TServiceType instance)
     {
         Func<Ioc, Type[], object?> factory = (_, arguments) => instance;
         ioc.Register(new ServiceRegistry(typeof(TServiceType), LifeTime.Singleton, factory));
         return ioc;
     }

     public static Ioc Register<TServiceType>(this Ioc ioc, Func<Ioc, TServiceType> factory, LifeTime lifetime)
     {
         ioc.Register(new ServiceRegistry(typeof(TServiceType), lifetime, (_, arguments) => factory(_)));
         return ioc;
     }

     private static object? Create(Ioc ico, Type type, Type[] genericArguments)
     {
         // 闭合泛型
         if (genericArguments.Length > 0)
         {
             type = type.MakeGenericType(genericArguments);
         }

         // 查找构造函数
         var constructors = type.GetConstructors(BindingFlags.Instance);
         if (constructors.Length == 0)
         {
             throw new InvalidOperationException($"Cannot create the instance of {type} which does not have an public constructor.");
         }
         var constructor = constructors.FirstOrDefault(it => it.GetCustomAttributes(false).OfType<InjectionAttribute>().Any());
         constructor = constructor ?? constructors.First();

         // 构造函数参数为空,直接new
         var parameters = constructor.GetParameters();
         if (parameters.Length == 0)
         {
             return Activator.CreateInstance(type);
         }

         // 生成实参
         var arguments = new object?[parameters.Length];
         for (int index = 0; index < arguments.Length; index++)
         {
             var parameter = parameters[index];
             var parameterType = parameter.ParameterType;
             if (ico.HasRegistry(parameterType))
             {
                 arguments[index] = ico.GetService(parameterType);
             }
             else if (parameter.HasDefaultValue)
             {
                 arguments[index] = parameter.DefaultValue;
             }
             else
             {
                 throw new InvalidOperationException($"Cannot create the instance of {type} whose constructor has non-registered parameter type(s)");
             }
         }

         return Activator.CreateInstance(type, arguments);
     }
 }

 public class ServiceRegistry
 {
     public Type ServiceType { get; set; }
     public LifeTime LifeTime { get; set; }
     public Func<Ioc, Type[], object?> Factory { get; set; }
     public ServiceRegistry? Next { get; set; }

     public ServiceRegistry(Type serviceType, LifeTime lifetime, Func<Ioc, Type[], object?> factory)
     {
         ServiceType = serviceType;
         LifeTime = lifetime;
         Factory = factory;
     }

     internal IEnumerable<ServiceRegistry> AsEnumerable()
     {
         var list = new List<ServiceRegistry>();
         for (var self = this; self != null; self = self.Next)
         {
             list.Add(self);
         }
         return list;
     }
 }

 public enum LifeTime
 {
     Transient,
     Scope,
     Singleton
 }

 [AttributeUsage(AttributeTargets.Constructor)]
 public class InjectionAttribute : Attribute { }

来自: https://www.cnblogs.com/artech/p/net-core-di-05.html

标签:serviceType,return,ioc,serviceRegistry,var,Ioc,public
From: https://www.cnblogs.com/readafterme/p/18396178

相关文章

  • Spring框架之IOC介绍
    Spring之IOC简介首先,官网中有这样一句话:SpringFrameworkimplementationoftheInversionofControl(IoC)principle.这句话翻译过来就是:Spring实现控制反转(IOC)原理,由此可以得出,InversionofControl(IOC)是一个名为控制反转的原理,而Spring实现了他。而实现这个原理或者说设......
  • IoC&AOP详解
    1.IoC1.1什么是IoC    IoC即控制反转/反转控制。它是一种思想而不是一种技术实现,描述的是:Java开发领域对象的创建以及管理的问题    例如:现有类A依赖类B        传统开发方式:在类A中通过new关键字来创建一个类B的对象      ......
  • 了解依赖反转原则(DIP)、控制反转(IoC)、依赖注入(DI)及 IoC容器
    这篇文章将描述DIP、IoC、DI和IoC容器。大多数情况下,初学者开发人员会遇到DIP、IoC、DI和IoC容器的问题。他们混淆在一起,发现很难辨别他们之间的区别,不知道为什么他们需要使用他们。另一方面,很多人使用DI,IoC却不知道它能解决什么问题。关于这个话题有很多帖子......
  • 如何使用Spring IOC的注解进行开发
    目录1、如何使用注解标记和扫描2、如何使用注解配置作用域和周期方法3、如何使用注解进行引用类型自动装配4、如何使用注解对基本类型属性赋值Spring IoC(Inversion of Control,控制反转)容器通过注解提供了一种简洁且强大的方式来进行依赖注入和配置管理。注解开发使得......
  • 逆向工程、Spring框架IOC、AOP学习
    系列文章目录第一章基础知识、数据类型学习第二章万年历项目第三章代码逻辑训练习题第四章方法、数组学习第五章图书管理系统项目第六章面向对象编程:封装、继承、多态学习第七章封装继承多态习题第八章常用类、包装类、异常处理机制学习第九章集合学习第......
  • IOC/DI注解开发管理第三方bean
    IOC/DI注解开发管理第三方bean前面定义bean的时候都是在自己开发的类上面写个注解就完成了,但如果是第三方的类,这些类都是在jar包中,我们没有办法在类上面添加注解,这个时候该怎么办?遇到上述问题,我们就需要有一种更加灵活的方式来定义bean,这种方式不能在原始代码上面书写注......
  • C#进阶-快速了解IOC控制反转及相关框架的使用
    目录一、了解IOC1、概念2、生命周期二、IOC服务示例1、定义服务接口 2、实现服务三、扩展-CommunityToolkit.Mvvm工具包Messenger信使方式一(收发消息)方式二(收发消息)方式三(请求消息)一、了解IOCIOC,即控制反转(InversionofControl),它通过将对象的创建和管理责任从......
  • IOC/DI配置管理第三方bean
    文章目录一案例:数据源对象管理1环境准备2思路分析3实现Druid管理步骤1:导入`druid`的依赖步骤2:配置第三方bean步骤3:从IOC容器中获取对应的bean对象步骤4:运行程序4实现C3P0管理步骤1:导入`C3P0`的依赖步骤2:配置第三方bean步骤3:运行程序二加载properties文......