• 实现一个简易IOC容器


    本文,实现了一个简易的IOC容器,主要供学习使用。

    首先抽象需要实现的功能,容器主要由两部分组成
    1.注册
    2.获取实例

            /// <summary>
            /// 注册 基类/接口->实际类型
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <typeparam name="TReal"></typeparam>
            void Register<T, TReal>();
    
            /// <summary>
            /// 注册 实例
            /// </summary>   
            /// <typeparam name="obj"></typeparam>
            void RegisterInstances(object obj);
    
            /// <summary>
            /// 注册 实例
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="obj"></param>
            void RegisterInstances<T>(object obj);
    
            /// <summary>
            /// 注册 泛型
            /// “开放”类型 只能存在于typeof操作中
            /// </summary>
            /// <param name="t1"></param>
            /// <param name="t2"></param>
            void RegisterGeneric(Type t1, Type t2);
    
            /// <summary>
            /// 获取类型实例
            /// </summary>
            /// <param name="type"></param>
            /// <returns></returns>
            T GetInstances<T>();
    

    为了简单起见,本文使用静态的Dictionary作为存放容器,XML配置部分未实现,

    具体实现如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    
    namespace Core.IOC
    {
        public class IOCManage
        {
            /// <summary>
            /// 多构造函数 创建对象规则
            /// 默认为 MultipleCtor.Longest
            /// </summary>
            public static MultipleCtor MultipleType = MultipleCtor.Longest;
    
            /// <summary>
            /// 类型字典 存放 声明类型->实际类型
            /// </summary>
            private static Dictionary<Type, Type> _types = new Dictionary<Type, Type>();
    
            /// <summary>
            /// 实例字典
            /// </summary>
            private static Dictionary<Type, object> _instances = new Dictionary<Type, object>();
    
    
    
    
            static IOCManage()
            {
                //TODO:XML配置加载
            }
    
    
    
    
            /// <summary>
            /// 创建类型
            /// </summary>
            /// <param name="type"></param>
            /// <returns></returns>
            public static T GetInstances<T>()
            {
                return (T)Get(typeof(T));
            }
    
            /// <summary>
            /// 该方法供 属性注入 中递归调用
            /// </summary>
            /// <param name="type"></param>
            /// <returns></returns>
            private static object Get(Type type)
            {
                object obj = InjectCtor(type);
                InjectProperty(obj);
                return obj;
            }
    
            #region 构造器注入
    
    
            /// <summary>
            /// 构造器注入
            /// </summary>
            /// <param name="type"></param>
            /// <returns></returns>
            private static object InjectCtor(Type type)
            {
                //查找 对象字典中是否有现成对象可以使用
                object obj;
                if (_instances.TryGetValue(type, out obj))
                    return obj;
    
    
                //查找 类型字典 获取要创建的实际类型   
                Type t = GetRealType(type);
                if (t == null || !t.IsClass || t.IsAbstract) return null;
    
    
                //对构造函数的几种处理方法
                ConstructorInfo[] ctors = t.GetConstructors();
                if (ctors.Length == 0)
                {
                    //throw new MissingMethodException("找不到匹配的公共构造函数");
                }
                else if (ctors.Length == 1)
                {
                    obj = CreateObj(t, ctors[0]);
                }
                else if (ctors.Length > 1)
                {
                    if (MultipleType == MultipleCtor.Error) { throw new CtorMultipleException("构造函数多余一个!"); }
                    if (MultipleType == MultipleCtor.Attribute)
                    {
                        foreach (var ctor in ctors)
                        {
                            if (ctor.IsDefined(typeof(AutoCtorAttribute), false))
                            {
                                obj = CreateObj(t, ctor);
                                if (obj != null) break;
                            }
                        }
                    }
                    if (MultipleType == MultipleCtor.Longest || obj == null)//如果标记为特性模式 却创建失败,重新执行
                    {
                        var _ctors = ctors.OrderByDescending(a => a.GetParameters().Length);
                        foreach (var ctor in _ctors)
                        {
                            obj = CreateObj(t, ctor);
                            if (obj != null) break;
                        }
                    }
                }
                _instances[type] = obj;
                return obj;
            }
    
    
            /// <summary>
            /// 查找实际类型
            /// </summary>
            /// <param name="type"></param>
            /// <returns></returns>
            private static Type GetRealType(Type type)
            {
                Type t;
                if (!_types.TryGetValue(type, out t))//查找 类型字典,找出实际要创建的类型
                {
                    t = GetGenericType(type);
                }
                return t;
            }
    
            /// <summary>
            /// 获取泛型类型
            /// </summary>
            /// <param name="type"></param>
            /// <returns></returns>
            private static Type GetGenericType(Type type)
            {
                //假设 字典中存的是 typeof(IList<>)->typeof(List<>)
                //现在需要从IList<string>创建List<string>对象
                Type t = null;
                if (type.IsGenericType)
                {
                    if (_types.TryGetValue(type.GetGenericTypeDefinition(), out t) && t.IsGenericType)//获取“开放” 类型 字典中查找                
                    {
                        t = t.MakeGenericType(type.GetGenericArguments());//获取 实际需要创建的“封闭”类型
                    }
                }
                return t;
            }
    
            /// <summary>
            /// 通过构造函数类型创建实例
            /// </summary>
            /// <param name="type"></param>
            /// <param name="t"></param>
            /// <param name="ctor"></param>
            /// <returns></returns>
            private static object CreateObj(Type type, ConstructorInfo ctor)
            {
                ParameterInfo[] @params = ctor.GetParameters();
                int length = @params.Length;
                object[] args = new object[length];
    
                for (int i = 0; i < length; i++)
                {
                    args[i] = InjectCtor(@params[i].ParameterType);//获取参数类型 递归调用创建方法
                }
                try
                {
                    return Activator.CreateInstance(type, args);
                }
                catch
                {
                    return null;
                }
            }
    
            #endregion
    
            #region 属性注入
    
            /// <summary>
            /// 属性注入
            /// 通过[AutoWrite]特性标记
            /// </summary>
            /// <param name="obj"></param>
            private static void InjectProperty(object obj)
            {
                if (obj != null)
                {
                    PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);//只查找公开属性
    
                    foreach (var property in properties)
                    {
                        AutoWriteAttribute autoWrite = (AutoWriteAttribute)Attribute.GetCustomAttribute(property, typeof(AutoWriteAttribute));
                        if (autoWrite != null)
                        {
                            object value = Get(autoWrite.RealType);
                            InjectProperty(obj);//递归注入
                            property.SetValue(obj, value, null);
                        }
                    }
                }
            }
    
            #endregion
    
            #region 注册
    
            /// <summary>
            /// 注册 基类/接口->实际类型
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <typeparam name="TReal"></typeparam>
            public static void Register<T, TReal>() where TReal : T
            {
                _types[typeof(T)] = typeof(TReal);
            }
    
            /// <summary>
            /// 注册 类型
            /// </summary>   
            /// <typeparam name="T"></typeparam>
            public static void RegisterType<T>()
            {
               _types[typeof(T)] = typeof(T);
            }
    
            /// <summary>
            /// 注册 实例
            /// </summary>   
            /// <typeparam name="T"></typeparam>
            public static void RegisterInstances(object obj)
            {
                if (obj == null) throw new ArgumentNullException("obj 不能为null!");
                _instances[obj.GetType()] = obj;
            }
    
            /// <summary>
            /// 注册 实例
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="obj"></param>
            public static void RegisterInstances<T>(object obj)
            {
                Type type = typeof(T);
                Type t = obj.GetType();
    
                if (!type.IsAssignableFrom(t))  //判断obj类型是否 等于/继承/实现 T
                {
                    throw new RegisterException(string.Format("obj的实际类型{0}与泛型类型{1}不匹配!", t.Name, type.Name));
                }
                _instances[type] = obj;
            }
    
            /// <summary>
            /// 注册 泛型
            /// “开放”类型 只能存在于typeof操作中
            /// </summary>
            /// <param name="t1"></param>
            /// <param name="t2"></param>
            public static void RegisterGeneric(Type t1, Type t2)
            {
                //判断t1是否 等于/继承/实现t2 
                //if (!t1.IsAssignableFrom(t2))
                //{
                Type _t1 = t1;
                Type _t2 = t2;
    
                //if (t1.IsGenericTypeDefinition || t2.IsGenericTypeDefinition)//泛型特殊处理
                //{
                //TODO:判断泛型是否存在 继承 实现 关系
    
                //通过创建泛型的“封闭”类型判断继承关系
                //todo:暂时实现不了
                //Type _t1 = t1.MakeGenericType(typeof(object));//泛型约束
                //Type _t2 = t2.MakeGenericType(typeof(object));//泛型约束
                //if (!_t1.IsAssignableFrom(_t2))
                //{
                //    throw new RegisterException(string.Format("参数类型{0}与{1}不匹配!", t1.Name, t2.Name));
                //}
                //}
                //else
                //{
                //throw new RegisterException(string.Format("参数类型{0}与{1}不匹配!", t1.Name, t2.Name));
                //}
                //}
                _types[t1] = t2;
            }
    
            #endregion
        }
    }
    

      其中使用到的相关类

        public class AutoWriteAttribute : Attribute
        {
            public Type RealType { get; private set; }
            public AutoWriteAttribute(Type type) { this.RealType = type; }
        }
    
        public class AutoCtorAttribute : Attribute
        {
            
        }
    
        public class CtorMultipleException : Exception
        {
            public CtorMultipleException(string message) : base(message) { }
        }
    
        /// <summary>
        /// 针对多个构造函数的创建方法
        /// </summary>
        public enum MultipleCtor
        {
            /// <summary>
            /// 按照 参数数量 依次调用构造函数 直到创建成功
            /// </summary>
            Longest,
            /// <summary>
            /// 抛出CtorMultipleException异常
            /// </summary>
            Error,
            /// <summary>
            /// 优先使用特性标记的构造函数 然后按照 Longest;
            /// </summary>
            Attribute
        }
    
        public class RegisterException : Exception
        {
            public RegisterException(string message) : base(message) { }
        }
    

      test

        class Program
        {
            static void Main(string[] args)
            {
                IOCManage.RegisterInstances(new A { Name = "A" });
                IOCManage.RegisterInstances<B>(new B { Name = "B" });
                IOCManage.RegisterType<C>();
                C c = IOCManage.GetInstances<C>();
    
                Console.Read();
            }
        }
    
        class A { public string Name { get; set; } }
        class B { public string Name { get; set; } }
        class C
        {
            private A a;
            private B b;
            public C(A a, B b)
            {
                this.a = a;
                this.b = b;
            }
        }
    

      

  • 相关阅读:
    oracle之check约束小结
    非归档模式下使用Rman进行备份和恢复
    R中,定义一个长度为0的向量
    R中,去掉dataframe中的NA行
    Oracle数据库的后备和恢复————关于检查点的一些知识
    关于oracle修复控制文件与数据文件不一致的问题----
    《SLAM机器人基础教程》第三章 单片机与STM32:GPIO实验及Keil软件使用WatchWindows进行Debug调试
    《SLAM导航机器人基础》第三章:单片机与STM32:单片机概述和Keil开发环境配置
    《SLAM导航机器人基础》第二章:C/C++编程(后)
    《SLAM导航机器人基础》第二章:C/C++编程(中)
  • 原文地址:https://www.cnblogs.com/ylws/p/3301425.html
Copyright © 2020-2023  润新知