第三方工具Unity的底层源码(IOC容器 DI注入 AOP面向切面)

public interface IXTContainer
    {
     
        void RegisterType<TFrom, TTo>(LifeTimeType lifeTimeType = LifeTimeType.Transient);
        T Resolve<T>();
    }

    /// 
    /// 容器--工厂
    /// 
    public class XTContainer : IXTContainer
    {
     
        private Dictionary<string, RegisterInfo> XTContainerDictionary = new Dictionary<string, RegisterInfo>();

        /// 
        /// 缓存起来,类型的对象实例
        /// 
        private Dictionary<Type, object> TypeObjectDictionary = new Dictionary<Type, object>();

        /// 
        /// 
        /// 
        /// 
        /// 
        /// 默认参数,不传递就是Transient
        public void RegisterType<TFrom, TTo>(LifeTimeType lifeTimeType = LifeTimeType.Transient)
        {
     
            XTContainerDictionary.Add(typeof(TFrom).FullName, new RegisterInfo()
            {
     
                TargetType = typeof(TTo),
                LifeTime = lifeTimeType
            });
        }

        public T Resolve<T>()
        {
     
            RegisterInfo info = XTContainerDictionary[typeof(T).FullName];
            Type type = XTContainerDictionary[typeof(T).FullName].TargetType;
            T result = default(T);
            switch (info.LifeTime)
            {
     
                case LifeTimeType.Transient:
                    result = (T)this.CreateObject(type);
                    break;
                case LifeTimeType.Singleton:
                    if (this.TypeObjectDictionary.ContainsKey(type))
                    {
     
                        result = (T)this.TypeObjectDictionary[type];
                    }
                    else
                    {
     
                        result = (T)this.CreateObject(type);
                        this.TypeObjectDictionary[type] = result;
                    }
                    break;
                case LifeTimeType.PerThread:
                    //怎么保证用线程校验呢? 线程槽,把数据存在这里
                    {
     
                        string key = type.FullName;
                        object oValue = CallContext.GetData(key);
                        if (oValue == null)
                        {
     
                            result = (T)this.CreateObject(type);
                            CallContext.SetData(key, result);
                        }
                        else
                        {
     
                            result = (T)oValue;
                        }
                    }
                    break;
                default:
                    throw new Exception("wrong LifeTime");
            }
            return result;
        }
        private object CreateObject(Type type)
        {
     
            ConstructorInfo[] ctorArray = type.GetConstructors();
            ConstructorInfo ctor = null;
            if (ctorArray.Count(c => c.IsDefined(typeof(XTInjectionConstructorAttribute), true)) > 0)
            {
     
                ctor = ctorArray.FirstOrDefault(c => c.IsDefined(typeof(XTInjectionConstructorAttribute), true));
            }
            else
            {
     
                ctor = ctorArray.OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
            }
            List<object> paraList = new List<object>();
            foreach (var parameter in ctor.GetParameters())
            {
     
                Type paraType = parameter.ParameterType;
                RegisterInfo info = XTContainerDictionary[paraType.FullName];
                Type targetType = info.TargetType;
                //object para = this.CreateObject(targetType);
                object para = null;
                #region 
                {
     
                    switch (info.LifeTime)
                    {
     
                        case LifeTimeType.Transient:
                            para = this.CreateObject(targetType);
                            break;
                        case LifeTimeType.Singleton:
                            //需要线程安全 双if+lock
                            {
     
                                if (this.TypeObjectDictionary.ContainsKey(targetType))
                                {
     
                                    para = this.TypeObjectDictionary[targetType];
                                }
                                else
                                {
     
                                    para = this.CreateObject(targetType);
                                    this.TypeObjectDictionary[targetType] = para;
                                }
                            }
                            break;
                        case LifeTimeType.PerThread:
                            //怎么保证用线程校验呢? 线程槽,把数据存在这里
                            {
     
                                string key = targetType.FullName;
                                object oValue = CallContext.GetData(key);
                                if (oValue == null)
                                {
     
                                    para = this.CreateObject(targetType);
                                    CallContext.SetData(key, para);
                                }
                                else
                                {
     
                                    para = oValue;
                                }
                            }
                            break;
                        default:
                            throw new Exception("wrong LifeTime");
                    }
                }
                #endregion
                //递归:隐形的跳出条件,就是GetParameters结果为空,targetType拥有无参数构造函数
                paraList.Add(para);
            }
            return Activator.CreateInstance(type, paraList.ToArray());
        }
        //属性注入+方法注入?


    }

你可能感兴趣的:(.Net通用工具)