通过反射实现IOC功能

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过反射实现IOC功能相关的知识,希望对你有一定的参考价值。

闲来没事,自己就想着根据反射可以自己写一个简易的IOC组件。IOC组件说白了就是根据反射实例化对应的接口。废话不多说,开始说说我的解决方案。

1、项目结构图:

  • IOCTest为web MVC项目。

  • Common 通过配置文件实例化对应的接口

  • IBLL定义的接口

  • BLL实现接口

2、引用

  1. IOCTest项目引用IBLL、Common项目,不能引用BLL项目,这样就使IOCTest项目只依赖接口。

  2. BLL项目引用IBLL并实现接口

  3. 修改BLL项目dll生成路径,使其DLL生成到IOCTest项目的Bin目录下,如下图设置

 

3、下面我们来看具体的实现

(1)在IBLL层的IHelloWord.cs类中我们定义一个接口,代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace IBLL
{
  public  interface IHelloWord
    {
      string SayHello(string Name);
    }
}
br

(2)BLL层实现接口‍

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IBLL;


namespace BLL
{
    public class HelloWord:IHelloWord
    {
        #region IHelloWord 成员


        public string SayHello(string Name)
        {
            return  "Hello_"+Name;
        }


        #endregion
    }
  
}

(3)在IOCTest 项目的根目录Web.config下做如下配置(把HelloWord和IHelloWord对应起来):

<appSettings>
    <add key="IBLL.IHelloWord" value="BLL,BLL.HelloWord"/>
  </appSettings>
 说明:  key值为接口的全称(命名空间+类名),value值为实现接口的类,两部分组成,逗号前面为生成的dll名称,逗号后面为类名全称(命名空间+类名)。

(4)Common 项目的IOCReflecter.cs类根据配置文件获取对应接口的实例化对象,代码实现如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Reflection;
using System.Configuration;


namespace Common
{
    public class IOCReflecter
    {
        private static Hashtable s_type=null;
        static IOCReflecter()
        {
            s_type = new Hashtable();
        }


        public static T CreateIntance<T>()
        {
            Type t=typeof(T);//key
            Type type = s_type[t] as Type;//value
            if (type == null)
            {
                string[] AssemblyInfos = ConfigurationManager.AppSettings[t.FullName].Split(',');
                type = Assembly.Load(AssemblyInfos[0]).GetType(AssemblyInfos[1]);
                s_type.Add(t, type);
            }
            return (T)CreateObject(type) ;
        }


        /// <summary>
        /// 根据typeName获取Type对象
        /// </summary>
        /// <param name="typeName"></param>
        /// <returns></returns>
        public static Type GetType(string typeName)
        {
            if (string.IsNullOrWhiteSpace(typeName))
            {
                return null;
            }
            return Type.GetType(typeName);
        }
        /// <summary>
        /// 获取对象
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        private static object CreateObject(Type t)
        {
            if (t == null)
            {
                return null;
            }
            //查找没有参数的构造函数
            //如果需要初始化带参数的构造函数 t.GetConstructors() 获取所有的构造函数 ,it.GetParameters()获取构造函数所有的参数,
            ConstructorInfo NonParameterConstructors= t.GetConstructors().Where(it=>it.GetParameters().Length==0).FirstOrDefault();
            if (NonParameterConstructors == null)
            {
                throw new Exception( t.FullName+"必须有一个无参数或默认的构造函数");
            }
            //调用数构造函数创建对象
            return t.InvokeMember(null, BindingFlags.CreateInstance, null, null, null);
        }
    }
}

(5)测试

在IOCTest项目Controllers中添加HomeController.cs文件,代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using IBLL;
using Common;


namespace IOCTest.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/


        public ActionResult Index()
        {
            //获取实例化对象
            IHelloWord hello = IOCReflecter.CreateIntance<IHelloWord>();
            ViewBag.Message = hello.SayHello("eric");
            return View();
        }


    }
}
@{
    ViewBag.Title = "Index";
}


<h2>@ViewBag.Message </h2>

最后上一张截图:

到此结束

以上是关于通过反射实现IOC功能的主要内容,如果未能解决你的问题,请参考以下文章

PHP依赖注入,控制反转,反射Ioc容器和服务提供者各个概念的理解和使用

PHP依赖注入,控制反转,反射Ioc容器和服务提供者各个概念的理解和使用

通过配置文件,反射,工厂模式实现IOC控制反转

C# WPF通过反射及Ioc容器综合实例

C# WPF通过反射及Ioc容器加载并显示其它项目界面(精品)

20170723-Ioc与AOP