我们平常写代码调用类方法等都会用的new一个对象,然后调对象的方法。
如:
//创建服务类
ServiceManager service=new ServiceManager();
//或者给接口
IServiceManager service=new ServiceManager();
其实在上面简单写法的时候就已经引入了一个耦合关系。类的使用方耦合了类的实现。如果后期类的实现类变了,所有的使用方都得改创建对象代码,造成系统不稳定性。
设计模式上说:
在创建对象时指定类名将使你受特定实现的约束而不是特定接口的约束。这会使未来的变化更复杂。要避免这种情况,应该间接地创建对象。
一套庞大的系统里有无数的创建对象代码。如:数据访问层创建具体的数据库连接操作对象;业务逻辑层创建数据访问层对象;UI层创建业务逻辑层对象等等,会引入数量庞大的对象创建耦合关系。如果哪天实现类需要变化会波及很广。为此引入工厂模式的概念,把创建对象的工作交给工厂。工厂模式分为简单工厂、工厂方法、抽象工厂。
简单工厂
实现类变化的时候只需要改工厂创建方法是实现就行了,把变化波动性压到这个方法了。缺点是这个方法的维护量大,需要随着变化不停的改。宁外全部系统的对象都创建都放一个方法内会照成这个方法很大。
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public class 工厂
{
/// <summary>
/// 简单工厂
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static 水果 生产(string a)
{
if (a.Equals("苹果"))
{
return new 苹果();
}
if (a.Equals("草莓"))
{
return new 草莓();
}
if (a.Equals("西瓜"))
{
return new 西瓜();
}
else
{
return null;
}
}
}
/// <summary>
/// 水果接口
/// </summary>
public interface 水果
{
void 种植();
void 成长();
void 收获();
}
/// <summary>
/// 苹果
/// </summary>
public class 苹果 : 水果
{
public void 种植()
{
MessageBox.Show("苹果在种植");
}
public void 成长()
{
MessageBox.Show("苹果在生长");
}
public void 收获()
{
MessageBox.Show("苹果在收获");
}
}
/// <summary>
/// 草莓
/// </summary>
public class 草莓 : 水果
{
public void 种植()
{
MessageBox.Show("草莓在种植");
}
public void 成长()
{
MessageBox.Show("草莓在生长");
}
public void 收获()
{
MessageBox.Show("草莓在收获");
}
}
/// <summary>
/// 西瓜
/// </summary>
public class 西瓜 : 水果
{
public void 种植()
{
MessageBox.Show("西瓜在种植");
}
public void 成长()
{
MessageBox.Show("西瓜在生长");
}
public void 收获()
{
MessageBox.Show("西瓜在收获");
}
}
}
工厂方法模式
由于简单工厂的创建对象代码都在一起,维护起来会有冲突。而工厂的作用都是创建对象,所以对工厂也进行接口抽象,把不同类别的工程分类。这个模式还是没有摆脱创建工厂对象时的new依赖。
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
/// <summary>
/// 工厂接口
/// </summary>
public interface 工厂
{
人 创建();
}
/// <summary>
/// 人接口
/// </summary>
public interface 人
{
void 你好();
}
/// <summary>
/// 学生
/// </summary>
public class 学生工厂 : 工厂
{
public 人 创建()
{
return new 学生();
}
}
/// <summary>
/// 老师工厂
/// </summary>
public class 老师工厂 : 工厂
{
public 人 创建()
{
return new 老师();
}
}
/// <summary>
/// 学生
/// </summary>
public class 学生 : 人
{
public void 你好()
{
MessageBox.Show("你好,我是学生");
}
}
/// <summary>
/// 老师
/// </summary>
public class 老师 : 人
{
public void 你好()
{
MessageBox.Show("你好,我是老师");
}
}
}
工厂使用
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 创建学生
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
工厂 g = new 学生工厂();
学生 a = (学生)g.创建();
a.你好();
}
/// <summary>
/// 创建老师
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
工厂 g = new 老师工厂();
老师 a = (老师)g.创建();
a.你好();
}
}
}
抽象工程
抽象工厂把类的属性对象都抽象出来,使用上值看到抽象类,并不知道具体实现类,来保证类逻辑的稳定性。
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public class ItMackt
{
public static Computer computer = null;
//static CPU cpu = null;
//static RAM ram = null;
public static Computer 组装(CPU cpu1, RAM ram1)
{
computer = new Computer(cpu1, ram1);
return computer;
}
}
/// <summary>
/// CPU抽象内
/// </summary>
public abstract class CPU
{
public abstract void 显示();
}
/// <summary>
/// RAM抽象类
/// </summary>
public abstract class RAM
{
public abstract void 显示();
}
/// <summary>
/// 苹果CPU
/// </summary>
public class MacCpu : CPU
{
public override void 显示()
{
MessageBox.Show("采用了苹果的CPU");
}
}
/// <summary>
/// 普通CPU
/// </summary>
public class PcCpu : CPU
{
public override void 显示()
{
MessageBox.Show("采用了PC的CPU");
}
}
/// <summary>
/// 苹果Ram
/// </summary>
public class MacRam : RAM
{
public override void 显示()
{
MessageBox.Show("采用了苹果的RAM");
}
}
/// <summary>
/// 普通RAM
/// </summary>
public class PcRam : RAM
{
public override void 显示()
{
MessageBox.Show("采用了PC的RAM");
}
}
/// <summary>
/// 电脑对象
/// </summary>
public class Computer
{
/// <summary>
/// cpu
/// </summary>
public static CPU cpu = null;
/// <summary>
/// ram
/// </summary>
public static RAM ram = null;
/// <summary>
/// 创建
/// </summary>
/// <param name="cpu1"></param>
/// <param name="ram1"></param>
public Computer(CPU cpu1, RAM ram1)
{
cpu = cpu1;
ram = ram1;
}
/// <summary>
/// 显示
/// </summary>
public void Show()
{
cpu.显示();
ram.显示();
}
}
}
基于抽象工厂思想的容器设计
采用反射的实现,根据xml配置反射对象到容器。由容器关联。获取放都调用容易的取对象方法得到对象,这样调用方完全不知道具体实现类。要获取对象传入接口,可见的只有接口。然后把不同接口的实现类配置上就行。换实现类就配置新的实现对象。
反射基础,根据类全名和dll名称创建类对象(用这个把创建耦合配置化)
/// <summary>
/// 通过配置得当对象
/// </summary>
/// <param name="confStr">配置</param>
/// <returns></returns>
private object GetObjectByConfString(string confStr)
{
try
{
LIS.Core.Util.LogUtils.WriteDebugLog("准备解析处理对象:" + confStr);
string[] strArr = confStr.Replace(" ","").Split(',');
if (strArr.Length < 2)
{
MessageBox.Show("配置的处理对象错误,请采用类全名,动态库名");
}
string path = Application.StartupPath+"\\"+ strArr[1];
if (!path.Contains(".dll"))
{
path = path + ".dll";
}
Assembly assembly = Assembly.LoadFile(path);
object obj = assembly.CreateInstance(strArr[0], false);
LIS.Core.Util.LogUtils.WriteDebugLog("解析处理对象:" + confStr+"成功");
return obj;
}
catch (Exception ex)
{
MessageBox.Show("解析处理对象出错:"+ex.Message );
return null;
}
}
模拟Spring.Net的事例代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Reflection;
using System.Configuration;
namespace GreenFramIoc
{
/// <summary>
/// [功能描述: 容器类]<br></br>
/// [创建者: 张联珠]<br></br>
/// [创建时间: 2013-9-17]<br></br>
/// <说明>
///
/// </说明>
/// <修改记录>
/// <修改时间></修改时间>
/// <修改内容>
///
/// </修改内容>
/// </修改记录>
/// </summary>
public class ObjectContainer
{
/// <summary>
/// 对象的容器,存放注入的对象
/// </summary>
private static IDictionary<string, object> objList = new Dictionary<string, object>();
/// <summary>
/// 类型容器,存放注入的类型
/// </summary>
private static IDictionary<string, Type> typeList = new Dictionary<string, Type>();
/// <summary>
/// 配置文件路径
/// </summary>
private static string configFilePath;
/// <summary>
/// 有参构造函数
/// </summary>
/// <param name="xmlFileName"></param>
public ObjectContainer(string xmlFileName)
{
configFilePath = xmlFileName;
InitTypes(xmlFileName,"IOC");//注入类型
InitObjects(xmlFileName, "IOC");//实例Ioc容器
DiObject(xmlFileName, "IOC");//属性注入
InitProxyTypes(xmlFileName, "AOP");//注入类型
DiObject(xmlFileName, "AOP");//属性注入
}
/// <summary>
/// 实例类型,注入所有的类型
/// </summary>
/// <param name="xmlFileName">配置文件名</param>
/// <param name="xmlFileName">节点分支名</param>
private static void InitTypes(string xmlFileName,string branch)
{
XElement root = XElement.Load(xmlFileName);
//获取所有的注入使用的程序集名字
var objects = (from obj in root.Element(branch).Elements("object") select obj.Attribute("dllName").Value).Distinct();
foreach (var obj in objects)
{
//读取程序集
Assembly assemly = Assembly.LoadFile(Environment.CurrentDirectory +"\\"+obj.ToString() + ".dll");
//把所有的类型加入类型字典
foreach (var type in assemly.GetTypes())
{
typeList.Add(type.FullName,type);
}
}
}
/// <summary>
/// 实例类型,注入所有的类型
/// </summary>
/// <param name="xmlFileName">配置文件名</param>
/// <param name="xmlFileName">节点分支名</param>
private static void InitProxyTypes(string xmlFileName, string branch)
{
XElement root = XElement.Load(xmlFileName);
//获取所有需要代理的类型的名字
var objects = (from obj in root.Element(branch).Elements("object") select obj);
//读取面向方面编程的程序集
Assembly assemly = Assembly.LoadFile(Environment.CurrentDirectory + "\\" + "GreenFramAop.dll");
//获得AOP代理构造器的类型
Type InterceptorProxyBuilderType = assemly.GetType("GreenFramAop.InterceptorProxyBuilder");
//创建AOP代理构造器的实例
object InterceptorProxyBuilder = System.Activator.CreateInstance(InterceptorProxyBuilderType);
var createProxy = InterceptorProxyBuilderType.GetMethod("CreateProxy");
//遍历所有的需要代理的类型
foreach (var obj in objects)
{
try
{
//参数
Object [] para=new Object[1];
//给类型参数赋值
para[0] = GetType(obj.Attribute("type").Value);
//调用生成代理的方法
var proxy=createProxy.Invoke(InterceptorProxyBuilder, para);
//把生成的代理对象放入对象容器
objList.Add(obj.Attribute("id").Value,proxy);
}
catch
{
}
}
}
/// <summary>
/// 实例Ioc容器,先注入全部的对象,再对对象注入属性,防止注入时找不到对象
/// </summary>
/// <param name="xmlFileName">配置文件路径名</param>
/// <param name="xmlFileName">节点分支名</param>
private static void InitObjects(string xmlFileName,string branch)
{
XElement root = XElement.Load(xmlFileName);
var objects = from obj in root.Element(branch).Elements("object") select obj;
//无参构造函数时
objList = objects.Where(obj => obj.Element("constructor-arg") == null).ToDictionary(
k => k.Attribute("id").Value//把id加入对象字典的键
, v =>//把反射的实体加入对象字典的值
{
string typeName = v.Attribute("type").Value
; Type type = GetType(typeName)
; return Activator.CreateInstance(type);
}
);
//有参构造函数时
foreach (XElement elem in objects.Where(obj => obj.Element("constructor-arg") != null))
{
//id的名字
string id = elem.Attribute("id").Value;
//id所指的类型全名
string typeName = elem.Attribute("type").Value;
//根据名称获得类型
Type type = GetType(typeName);
ConstructorInfo constructor = null;
//找到和配置文件参数个数相同的构造函数
foreach (var cons in type.GetConstructors())
{
if (cons.GetParameters().Count() == elem.Elements("constructor-arg").Count())
{
constructor = cons;
break;
}
}
//获得构造函数的参数
var args = from property in constructor.GetParameters()
join e1 in elem.Elements("constructor-arg")
on property.Name equals e1.Attribute("name").Value
select Convert.ChangeType(e1.Attribute("value").Value, property.ParameterType);
//根据参数和类型反射对象
object obj = Activator.CreateInstance(type, args.ToArray());
//把对象加入对像容器
objList.Add(id, obj);
}
}
/// <summary>
/// 属性注入
/// </summary>
/// <param name="fileName">配置文件名</param>
/// <param name="branch">节点分支名</param>
private static void DiObject(string fileName, string branch)
{
//读取XML配置文件
XElement root = XElement.Load(fileName);
//遍历框架下的所有节点
var objects = from obj in root.Element(branch).Elements("object") select obj;
//遍历对象集合
foreach (KeyValuePair<string, object> item in objList)
{
//查找XML节点id值等于对象集合字典的键的节点的名为property的子节点集合
foreach (var e1 in objects.Where(e => e.Attribute("id").Value == item.Key).Elements("property"))
{
//获取当前遍历对象的类型
Type type = item.Value.GetType();
//遍历该类型的所有的属性
foreach (PropertyInfo property in type.GetProperties())
{
//如果属性名等于节点name的值
if (property.Name == e1.Attribute("name").Value)
{
//如果该节点value(表名注入的是值)的值不为空
if (e1.Attribute("value") != null)
{
if (e1.Attribute("value").Value == "")
{
//如果该节点value的值为空串
Console.WriteLine("警告:" + e1.Attribute("name").Value + "的属性值为空");
}
//设置属性值
property.SetValue(item.Value, Convert.ChangeType(e1.Attribute("value").Value, property.PropertyType), null);
}
//如果注入的是引用
else if (e1.Attribute("ref") != null)
{
object refObject = null;
//如果引用的对象已经注入容器
if (objList.ContainsKey(e1.Attribute("ref").Value))
{
refObject = objList[e1.Attribute("ref").Value];
}
//如果在容器里没有找到引用的对象
else
{
Console.WriteLine(e1.Attribute("name").Value + "没有参照对象,请确定已注册");
}
//设置属性值
property.SetValue(item.Value, refObject, null);
}
}
}
}
}
}
/// <summary>
/// 根据名字获得单例对象
/// </summary>
/// <param name="objName">对象标示名</param>
/// <returns>返回的对象</returns>
public static object GetSingletonObject(string objName)
{
object obj = null;
if (objList.ContainsKey(objName))
{
obj = objList[objName];
}
return obj;
}
/// <summary>
/// 根据名字获得新对象
/// </summary>
/// <param name="objName">对象标示名</param>
/// <returns>返回的对象</returns>
public static object GetNewObject(string objName)
{
object obj = null;
if (objList.ContainsKey(objName))
{
obj = objList[objName];
}
return obj;
}
/// <summary>
/// 根据给定类型获得该类型的单例对象
/// </summary>
/// <typeparam name="T">给定的类型</typeparam>
/// <returns></returns>
public static object GetSingletonObject<T>()
{
return null;
}
/// <summary>
/// 根据给定类型获得该类型的单例对象
/// </summary>
/// <typeparam name="T">给定的类型</typeparam>
/// <returns></returns>
public static object GetNewObject<T>()
{
return null;
}
/// <summary>
/// 通过类型全名获得类型
/// </summary>
/// <param name="typeFullName">类型全名</param>
/// <returns>类型</returns>
public static Type GetType(string typeFullName)
{
if (typeList.Keys.Contains(typeFullName))
{
return typeList[typeFullName];
}
else
{
return null;
}
}
/// <summary>
/// 通过类型获取在配置文件中为该类型配置的拦截器
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public static object GetInterceptorByType(Type t)
{
XElement root = XElement.Load(configFilePath);
//获取所有需要代理的类型的名字
var objects = (from obj in root.Element("AOP").Elements("object") select obj);
foreach (var obj in objects)
{
if (obj.Attribute("type").Value.ToString() == t.FullName)
{
return objList[obj.Element("interceptor").Attribute("ref").Value];
}
}
return null;
}
}
}
AOP接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GreenFramAop
{
//后置通知接口
public interface IInterceptor
{
/// <summary>
/// 方法调用前
/// </summary>
/// <param name="operationName">方法名</param>
/// <param name="inputs">参数</param>
/// <returns>状态对象,用于调用后传入</returns>
object BeforeCall(string operationName, object[] inputs);
/// <summary>
/// 方法调用后
/// </summary>
/// <param name="operationName">方法名</param>
/// <param name="returnValue">结果</param>
/// <param name="correlationState">状态对象</param>
void AfterCall(string operationName, object returnValue, object correlationState);
}
}
动态代理
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using GreenFramIoc;
namespace GreenFramAop
{
/// <summary>
/// [功能描述: 默认代理创建器,技术探索]<br></br>
/// [创建者: 张联珠]<br></br>
/// [创建时间: 2013-9-5]<br></br>
/// <说明>
///
/// </说明>
/// <修改记录>
/// <修改时间></修改时间>
/// <修改内容>
///
/// </修改内容>
/// </修改记录>
/// </summary>
public class InterceptorProxyBuilder
{
/// <summary>
/// void类型
/// </summary>
private static readonly Type VoidType = Type.GetType("System.Void");
/// <summary>
/// 创建代理对象
/// </summary>
/// <typeparam name="T">要创建代理的类型</typeparam>
/// <returns>代理类型</returns>
public static object CreateProxy(Type type)
{
//获得T的类型
Type classType = type;
//代理类型的命名空间
string name = classType.Namespace + ".Aop";
//代理类型程序集的名字
string fileName = name + ".dll";
//定义程序集的唯一标识
var assemblyName = new AssemblyName(name);
//定义动态程序集
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
//定义动态模块
var moduleBuilder = assemblyBuilder.DefineDynamicModule(name, fileName);
//根据所给的类型和模块构建新类型(该类型的代理)
var aopType = BulidType(classType, moduleBuilder);
//保存程序集
assemblyBuilder.Save(fileName);
//返回构建的代理类型
return Activator.CreateInstance(aopType);
}
/// <summary>
/// 根据所给的类型和模块在该模块下构建该类型的代理类型
/// </summary>
/// <param name="classType">所要构建代理的类型</param>
/// <param name="moduleBuilder">所在模块</param>
/// <returns>构建的代理类型</returns>
private static Type BulidType(Type classType, ModuleBuilder moduleBuilder)
{
//代理类型的名字
string className = classType.Name + "Proxy";
//根据所给的类型定义类型
var typeBuilder = moduleBuilder.DefineType(className,
TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class,
classType);
//定义字段(拦截器) inspector
var inspectorFieldBuilder = typeBuilder.DefineField("inspector", typeof(IInterceptor),
FieldAttributes.Public | FieldAttributes.InitOnly);
//构造代理的构造函数
BuildCtor(classType, inspectorFieldBuilder, typeBuilder);
//构造代理的方法
BuildMethod(classType, inspectorFieldBuilder, typeBuilder);
//得到构造之后的代理类型
Type aopType = typeBuilder.CreateType();
//返回生成的代理类型
return aopType;
}
/// <summary>
/// 构造代理的方法
/// </summary>
/// <param name="classType">原类型</param>
/// <param name="inspectorFieldBuilder">拦截器</param>
/// <param name="typeBuilder">代理类型</param>
private static void BuildMethod(Type classType, FieldBuilder inspectorFieldBuilder, TypeBuilder typeBuilder)
{
//获取原类型的所有方法信息
var methodInfos = classType.GetMethods();
//遍历所有的方法信息
foreach (var methodInfo in methodInfos)
{
//如果不是虚方法和抽象放法,进入下一个
if (!methodInfo.IsVirtual && !methodInfo.IsAbstract) continue;
//如果是Object的ToString方法,进入下一个
if (methodInfo.Name == "ToString") continue;
//如果是Object的GetHashCode方法,进入下一个
if (methodInfo.Name == "GetHashCode") continue;
//如果是Object的Equals方法,进入下一个
if (methodInfo.Name == "Equals") continue;
//获取该方法的所有参数信息
var parameterInfos = methodInfo.GetParameters();
//用Lamada表达式获取每个参数的类型
var parameterTypes = parameterInfos.Select(p => p.ParameterType).ToArray();
//获取参数的个数
var parameterLength = parameterTypes.Length;
//获取方法是否有返回值
var hasResult = methodInfo.ReturnType != VoidType;
//创建和该方法一样的方法
var methodBuilder = typeBuilder.DefineMethod(methodInfo.Name,
MethodAttributes.Public | MethodAttributes.Final |
MethodAttributes.Virtual
, methodInfo.ReturnType
, parameterTypes);
//得到IL加载器
var il = methodBuilder.GetILGenerator();
//局部变量
il.DeclareLocal(typeof(object)); //correlationState
il.DeclareLocal(typeof(object)); //结果
il.DeclareLocal(typeof(object[])); //参数
//BeforeCall(string operationName, object[] inputs);前置通知
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, inspectorFieldBuilder);//获取字段inspector,把他的引用推送到栈里
il.Emit(OpCodes.Ldstr, methodInfo.Name);//方法名
if (parameterLength == 0)//判断方法参数长度,如果方法参数长度为0
{
il.Emit(OpCodes.Ldnull);//null -> 参数 inputs
}
else
{
//创建new object[parameterLength];
il.Emit(OpCodes.Ldc_I4, parameterLength);//把参数的长度入栈
il.Emit(OpCodes.Newarr, typeof(Object));//创建长度为参数长度的Object数组
il.Emit(OpCodes.Stloc_2);//把创建的Object数组压入局部变量2(前面创的参数的局部变量)
//循环加入每个参数
for (int i = 0, j = 1; i < parameterLength; i++, j++)
{
il.Emit(OpCodes.Ldloc_2);//把前面创建的参数的局部变量入栈
il.Emit(OpCodes.Ldc_I4, i);//把i入栈,后面用
il.Emit(OpCodes.Ldarg, j);//把j处的参数入栈
if (parameterTypes[i].IsValueType)//如果第i号参数是值类型
{
il.Emit(OpCodes.Box, parameterTypes[i]);//对值类型装箱
}
il.Emit(OpCodes.Stelem_Ref);//用(OpCodes.Ldarg, j)替换参数局部变量的第i个元素
}
il.Emit(OpCodes.Ldloc_2);//取出局部变量2 parameters-> 参数 inputs
}
il.Emit(OpCodes.Callvirt, typeof(IInterceptor).GetMethod("BeforeCall"));//调用BeforeCall
il.Emit(OpCodes.Stloc_0);//建返回压入局部变量0 correlationState
//Call methodInfo
il.Emit(OpCodes.Ldarg_0);
//获取参数表
for (int i = 1, length = parameterLength + 1; i < length; i++)
{
il.Emit(OpCodes.Ldarg_S, i);
}
il.Emit(OpCodes.Call, methodInfo);
//将返回值压入 局部变量1result void就压入null
if (!hasResult)
{
il.Emit(OpCodes.Ldnull);
}
else if (methodInfo.ReturnType.IsValueType)
{
il.Emit(OpCodes.Box, methodInfo.ReturnType);//对值类型装箱
}
il.Emit(OpCodes.Stloc_1);
//AfterCall(string operationName, object returnValue, object correlationState);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, inspectorFieldBuilder);//获取字段_inspector
il.Emit(OpCodes.Ldstr, methodInfo.Name);//参数 operationName
il.Emit(OpCodes.Ldloc_1);//局部变量1 result
il.Emit(OpCodes.Ldloc_0);// 局部变量0 correlationState
il.Emit(OpCodes.Callvirt, typeof(IInterceptor).GetMethod("AfterCall"));
//result
if (!hasResult)
{
il.Emit(OpCodes.Ret);
continue;
}
il.Emit(OpCodes.Ldloc_1);//非void取出局部变量1 result
if (methodInfo.ReturnType.IsValueType)
{
il.Emit(OpCodes.Unbox_Any, methodInfo.ReturnType);//对值类型拆箱
}
il.Emit(OpCodes.Ret);
}
}
/// <summary>
/// 构造代理的构造函数
/// </summary>
/// <param name="classType">原类型</param>
/// <param name="inspectorFieldBuilder">拦截器</param>
/// <param name="typeBuilder">代理类型</param>
private static void BuildCtor(Type classType, FieldBuilder inspectorFieldBuilder, TypeBuilder typeBuilder)
{
{
//定义代理的构造函数
var ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis,
Type.EmptyTypes);
//获得IL指令器
var il = ctorBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, classType.GetConstructor(Type.EmptyTypes));//调用base的默认ctor
il.Emit(OpCodes.Ldarg_0);
//将typeof(classType)压入计算堆
il.Emit(OpCodes.Ldtoken, classType);
il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }));
#region 创建并实例化拦截器
//调用DefaultInterceptorFactory.Create(type)
il.Emit(OpCodes.Call, typeof(ObjectContainer).GetMethod("GetInterceptorByType", new[] { typeof(Type) }));
//将结果保存到字段inspector
il.Emit(OpCodes.Stfld, inspectorFieldBuilder);
#endregion
il.Emit(OpCodes.Ret);
}
}
}
}