反射+IOC容器

    说起反射,我们并不陌生,并且我在之前的博客中,http://blog.csdn.net/gaibian0823/article/details/44624423也已经提到过,一个是这里面提到的只是理解层面上的,二是反射一般很少自己出现,都是结合着其他知识点出现。所以这次不会再体现在理解层面上,我们从例子中看问题。

一、反射

    反射就是在我们不去引用另外一个程序集或者模块,而直接调用他的属性、方法。

  1.首先是这个程序,我要在Program中调用User中的属性以及方法。

                               反射+IOC容器_第1张图片

  2.类User中的代码:

<span style="font-family:KaiTi_GB2312;font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ITOO_DAL
{
    public class User
    {
        //字段
        public string Field = "Hello World";

        //属性
        public string Name { get; set; }

        //无参构造
        public User()
        {
            this.Name = "无参构造";     
        }

        //有参构造
        public User(string UserName)
        {
            this.Name = UserName;
        }

        //public函数
        public void publicFunction()
        {
            Console.WriteLine(string.Format("调用的是我public方法"));
        }

        //private函数
        private void privateFunction()
        {
            Console.WriteLine(string.Format("调用的是我private方法"));
        }

        //static函数
        public static void staticFunction()
        {
            Console.WriteLine(string.Format("调用的是我静态static方法"));
        }

        //public带参带返回值函数
        public string publicFunctionPara(string UserName)
        {
            return string.Format("调用带参带返回值函数,参数为:{0}",UserName);
        }
    }
}
</span>
 3.主函数

<span style="font-family:KaiTi_GB2312;font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ITOO_Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
            //使用 Assembly 定义和加载程序集,
            //加载在程序集清单中列出的模块,
            //以及从此程序集中查找类型并创建该类型的实例.
            //获取程序集
            Assembly assembly = Assembly.Load("ITOO_DAL");

            //从程序集中获取指定对象类型;
            Type type = assembly.GetType("ITOO_DAL.User");

            //方法一:创建类的实例 

           //使用Activator创建实例(无参数构造函数)
            var userNoParameter = Activator.CreateInstance(type);

            //使用Activator创建实例(带参数构造函数)
            var userParameter = Activator.CreateInstance(type, "wangjinbo");
  
            //方法二:创建类的实例

            //使用无参构造函数创建类(先反射创建构造函数,再使用构造函数创建类)
            ConstructorInfo constructorNoParameter = type.GetConstructor(new Type[] { });
            var userNoParameterByConstructorInfo = constructorNoParameter.Invoke(new object[] { });

            //使用有参构造函数创建类(先反射创建构造函数,再使用构造函数创建类) 
            ConstructorInfo constructorParameter = type.GetConstructor(new Type[] { typeof(string) });
            var userParameterByConstructorInfo = constructorParameter.Invoke(new object[] { "wangjinbo" });

            //调用public函数(无参数)
            type.InvokeMember("publicFunction",
                              BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, userNoParameter,
                              null);

            //调用public函数(带参数)
            string returnValuePublic =
                type.InvokeMember("publicFunctionPara",
                                  BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, userNoParameter,
                                  new object[] { "wangjinbo" }) as string;
            Console.WriteLine(returnValuePublic);

            //调用静态方法       
            string returnValueStatic =
                type.InvokeMember("staticFunction", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
                                  null, null, new object[] { }) as string;
            Console.WriteLine(returnValueStatic);

            //反射属性
            var Name =
                type.InvokeMember("Name", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null,
                                  userNoParameter, new object[] { }) as string;
            Console.WriteLine(Name);

            //设置属性(设置Name属性为"NewName")
            type.InvokeMember("Name", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null,
                                  userNoParameter, new object[] { "NewName" });


            //反射字段
            string Field =
                type.InvokeMember("Field", BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance, null,
                                  userNoParameter, new object[] { }) as string;
            Console.WriteLine(Field);

            //设置字段(设置Field字段为"NewField")
            type.InvokeMember("Field", BindingFlags.SetField | BindingFlags.Public | BindingFlags.Instance, null,
                                  userNoParameter, new object[] { "NewField" });

        }
    }
}
</span>
   上面就是通过反射从一个类中调用了另一个类中的属性以及方法。

二、反射+IOC容器

    1.什么是IOC?

    IOC即控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。依赖注入应用比较广泛。

    当然这是官方解释,我的解释是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器负责将这些联系在一起。简单的来讲,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。

    2.反射+依赖注入、依赖查找

    首先,我们来看依赖注入:

    配置文件中      反射+IOC容器_第2张图片

    通过get,set注入

 反射+IOC容器_第3张图片

    然后直接使用D层所有方法:

 反射+IOC容器_第4张图片

   2.依赖查找

   配置文件中:

 反射+IOC容器_第5张图片

    程序中,GetObject为反射:

 

    依赖注入和依赖查找都用到了反射,但是依赖注入是被动的,依赖查找是主动的,依赖查找是需要来把配置文件中的id写进来,而注入get,set后,可以使用里面的所有方法。

    总的流程就是:

    1.加载配置文件中的所有内容。

    2.将id,value放到一个哈希表中。

    3.反射来查找id或者name,来调用相关类。

    这些知识,我们用了很长时间,但是前面并不理解,所以我们需要更加主动地去整理总结这些知识,而不是被动地接受。

你可能感兴趣的:(反射+IOC容器)