闲来没事,自己就想着根据反射可以自己写一个简易的IOC组件。IOC组件说白了就是根据反射实例化对应的接口。废话不多说,开始说说我的解决方案。
1、项目结构图:
IOCTest为web MVC项目。
Common 通过配置文件实例化对应的接口
IBLL定义的接口
BLL实现接口
2、引用
IOCTest项目引用IBLL、Common项目,不能引用BLL项目,这样就使IOCTest项目只依赖接口。
BLL项目引用IBLL并实现接口
修改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);//keyType type = s_type[t] as Type;//valueif (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>
最后上一张截图:
到此结束