实现一个简易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;
        }
    }

  

posted @ 2013-09-09 12:00  YLWS  阅读(315)  评论(0编辑  收藏  举报