手写IOC容器和两种注入(构造方法注入和属性注入)

昨天说了依赖注入要用反射去创建实例。

注入的前提是注册了。注册分两种:1、代码注册(手动注册到容器中)2、配置文件注册(代码自动搜寻配置文件反射注入进去)

这里上代码吧:控制反转主要是依赖抽象。这里就定一接口

先讲思路:

1、首先注册。定义一个容器(这里用Dictionary<接口名称,实现类型>)。

2、注入

  2.1构造函数注入:先去容器中找到该接口的实现类型。然后遍历该实现类型的构造函数中的参数。首先找有特性标记的。如果没有特性就找构造参数最多的那个构造函数。然后对这个构造函数里的参数进行实例化。如果该类型构造函数也是有多的参数。也就在遍历他。因为不知道深度。所以这里用递归去遍历。直到可以直接实例化的那个构造参数。

  2.2属性注入::先去容器中找到该接口的实现类型。然后遍历该实现类型的属性,然后再去容器中找。然后实例化赋值。因为不知道该属性的实例后的属性多少和深度。这里也用递归去找。

 

 

 

 

 

 

 

 

 

 

抽象定义和实现。你们自定吧。往里面套就像。把思路弄懂了。你们可以自己扩展一个方法注入

 

注册:

             IMyselfContainer container = new MyselfContainer();
            container.RegisterType<IFirstService, FirstService>();
            container.RegisterType<IFourthService, FourthService>();
            container.RegisterType<ISecondService, SecondService>();
            container.RegisterType<IThirdService, ThirdService>();        

 

 

 

 容器的实现:

 public class MyselfContainer : IMyselfContainer

    {
        /// <summary>
        /// 容器
        /// </summary>
        private Dictionary<string, Type> Container = new Dictionary<string, Type>();
        /// <summary>
        /// 注册
        /// </summary>
        /// <typeparam name="TFrom"></typeparam>
        /// <typeparam name="TTo"></typeparam>
        public void RegisterType<TFrom, TTo>()
        {
            Container.Add(typeof(TFrom).FullName, typeof(TTo));
        }
        /// <summary>
        /// 构造函数注入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IT Resolve<IT>()
        {
            Type type= Container[typeof(IT).FullName];

            return (IT)CreateObject(type);
        }
        /// <summary>
        ///构造函数注入,因为不知道构造函数的参数深入
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        private object CreateObject(Type type)
        {
            ConstructorInfo[] constructorInfo = type.GetConstructors();
            ConstructorInfo model = null;
            var modelcons = constructorInfo.Where(t => t.IsDefined(typeof(IsSignAttribute), true)).FirstOrDefault();
            if (model != null)
            {
                model = modelcons;
            }
            else
            {
                ///获取构造函数最多的那个构造那函数的参数
                model = constructorInfo.OrderByDescending(t => t.GetParameters().Length).FirstOrDefault();
            }
            List<object> list = new List<object>();
            foreach (var item in model.GetParameters())
            {
                //Type paraType = item.ParameterType;
                var types = Container[item.ParameterType.FullName];
                var newtype= this.CreateObject(types);
                list.Add(newtype);
            }
            return Activator.CreateInstance(type, list.ToArray());
        }
        /// <summary>
        /// 属性注入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T AttributeInjectionResolve<T>()
        {
            //var typeName= typeof(T).FullName;
            var TypeClass= Container[typeof(T).FullName];
            return (T)CreateObjectByIn(TypeClass);
        }
        private object CreateObjectByIn(Type type)
        {
            var t = Activator.CreateInstance(type);
            //List<object> list = new List<object>();
            foreach (var item in type.GetProperties())
            { 
                //Type paraType = item.PropertyType;
                var types = Container[item.PropertyType.FullName];
                var value = CreateObjectByIn(types);
                item.SetValue(t, value);
                //list.Add(types);
            }
            return t;
        }
    }

 

posted @ 2020-11-03 00:05  小换哥  阅读(408)  评论(0编辑  收藏  举报