unity 2.0 interception 学习2
上一篇: public interface IHello { void SayHello(); } private void button3_Click(object sender, EventArgs e) { AppDomain domain = AppDomain.CurrentDomain; //动态程序集 AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(new AssemblyName("test"), AssemblyBuilderAccess.Run); //动态程序集模块 ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("helloWorldTypeBuilder"); //运行时创建类 TypeBuilder helloWorldTypeBuilder = moduleBuilder.DefineType("hello"); //声明实现IHello接口 helloWorldTypeBuilder.AddInterfaceImplementation(typeof(IHello)); //定义SayHello方法 MethodBuilder myMethodBuilder = helloWorldTypeBuilder.DefineMethod("SayHello2", MethodAttributes.Public | MethodAttributes.Virtual, null, null); // 方法体开始 ILGenerator myMethodIL = myMethodBuilder.GetILGenerator(); myMethodIL.Emit(OpCodes.Ldstr, "hello world"); Type[] showParameters = { typeof(String) }; MethodInfo messageBoxShow = typeof(MessageBox).GetMethod("Show", showParameters); myMethodIL.Emit(OpCodes.Call, messageBoxShow); myMethodIL.Emit(OpCodes.Pop); myMethodIL.Emit(OpCodes.Ret); // 方法体结束 //方法体注入接口SayHello方法 MethodInfo sayHelloMethod = typeof(IHello).GetMethod("SayHello"); helloWorldTypeBuilder.DefineMethodOverride(myMethodBuilder, sayHelloMethod); //调用 Type test = helloWorldTypeBuilder.CreateType();//创建动态类 var instance = Activator.CreateInstance(test); ((IHello)instance).SayHello(); test.GetMethod("SayHello2").Invoke(instance, null); }上面的理解了,分析源码就清楚多了。
(2)分析源码,了解IInterceptingProxy是如何被实现的:
在E:\Program Files\Microsoft Unity Application Block 2.0\UnitySource\Source\Unity.Interception\Src\Intercept.cs
public static object NewInstanceWithAdditionalInterfaces(
Type type,
ITypeInterceptor interceptor,
IEnumerable<IInterceptionBehavior> interceptionBehaviors,
IEnumerable<Type> additionalInterfaces,
params object[] constructorParameters)
{
Guard.ArgumentNotNull(type, "type");
Guard.ArgumentNotNull(interceptor, "interceptor");
Guard.ArgumentNotNull(interceptionBehaviors, "interceptionBehaviors");
Guard.ArgumentNotNull(additionalInterfaces, "additionalInterfaces");
if (!interceptor.CanIntercept(type))
{
throw new ArgumentException(
string.Format(
CultureInfo.CurrentCulture,
Resources.InterceptionNotSupported,
type.FullName),
"type");
}
var behaviors = interceptionBehaviors.ToList();
if(behaviors.Where(ib => ib == null).Count() > 0)
{
throw new ArgumentException(
string.Format(CultureInfo.CurrentCulture, Resources.NullBehavior),
"interceptionBehaviors");
}
Type implementationType = type;
var activeBehaviors = behaviors.Where(ib => ib.WillExecute);
Type[] allAdditionalInterfaces = GetAllAdditionalInterfaces(activeBehaviors, additionalInterfaces);
Type interceptionType = interceptor.CreateProxyType(implementationType, allAdditionalInterfaces);
var proxy = (IInterceptingProxy)Activator.CreateInstance(interceptionType, constructorParameters);
foreach (IInterceptionBehavior interceptionBehavior in activeBehaviors)
{
proxy.AddInterceptionBehavior(interceptionBehavior);
}
return proxy;
}
CreateProxyType在 E:\Program Files\Microsoft Unity Application Block 2.0\UnitySource\Source\Unity.Interception\Src\Interceptors\TypeInterceptors\VirtualMethodInterception\VirtualMethodInterceptor.cs
public Type CreateProxyType(Type t, params Type[] additionalInterfaces)
{
Guard.ArgumentNotNull(t, "t");
Guard.ArgumentNotNull(additionalInterfaces, "additionalInterfaces");
if (!CanIntercept(t))
{
throw new InvalidOperationException(
string.Format(CultureInfo.CurrentCulture, Resources.InterceptionNotSupported, t.Name));
}
Type interceptorType;
Type typeToDerive = t;
bool genericType = false;
if (t.IsGenericType)
{
typeToDerive = t.GetGenericTypeDefinition();
genericType = true;
}
GeneratedTypeKey key = new GeneratedTypeKey(typeToDerive, additionalInterfaces);
lock (derivedClasses)
{
if (!derivedClasses.TryGetValue(key, out interceptorType))
{
InterceptingClassGenerator generator =
new InterceptingClassGenerator(typeToDerive, additionalInterfaces);
interceptorType = generator.GenerateType();
derivedClasses[key] = interceptorType;
}
}
if (genericType)
{
interceptorType = interceptorType.MakeGenericType(t.GetGenericArguments());
}
return interceptorType;
}
类InterceptingClassGenerator 在 E:\Program Files\Microsoft Unity Application Block 2.0\UnitySource\Source\Unity.Interception\Src\Interceptors\TypeInterceptors\VirtualMethodInterception\InterceptingClassGeneration\InterceptingClassGenerator.cs
构造函数:
}
CreateTypeBuilder:
private void CreateTypeBuilder()
{
TypeAttributes newAttributes = typeToIntercept.Attributes;
newAttributes = FilterTypeAttributes(newAttributes);
Type baseClass = GetGenericType(typeToIntercept);
ModuleBuilder moduleBuilder = GetModuleBuilder();
typeBuilder = moduleBuilder.DefineType(
"DynamicModule.ns.Wrapped_" + typeToIntercept.Name + "_" + Guid.NewGuid().ToString("N"),
newAttributes,
baseClass);//由此看见继承于typeToIntercept
DefineGenericArguments(typeBuilder, baseClass);
// 实现接口靠下面这句
proxyInterceptionPipelineField = InterceptingProxyImplementor.ImplementIInterceptingProxy(typeBuilder);
}
ImplementIInterceptingProxy 在 E:\Program Files\Microsoft Unity Application Block 2.0\UnitySource\Source\Unity.Interception\Src\Interceptors\TypeInterceptors\VirtualMethodInterception\InterceptingClassGeneration\InterceptingProxyImplementor.cs
internal static FieldBuilder ImplementIInterceptingProxy(TypeBuilder typeBuilder)
{
typeBuilder.AddInterfaceImplementation(typeof(IInterceptingProxy));//声明实现IInterceptingProxy接口
FieldBuilder proxyInterceptorPipelineField =
typeBuilder.DefineField(
"pipeline",
typeof(InterceptionBehaviorPipeline),
FieldAttributes.Private | FieldAttributes.InitOnly);
// 方法体注入靠下面这句
ImplementAddInterceptionBehavior(typeBuilder, proxyInterceptorPipelineField);
return proxyInterceptorPipelineField;
}
private static void ImplementAddInterceptionBehavior(TypeBuilder typeBuilder, FieldInfo proxyInterceptorPipelineField)
{
// Declaring method builder
// Method attributes
const MethodAttributes methodAttributes = MethodAttributes.Private | MethodAttributes.Virtual
| MethodAttributes.Final | MethodAttributes.HideBySig
| MethodAttributes.NewSlot;
MethodBuilder methodBuilder =
typeBuilder.DefineMethod(
"Microsoft.Practices.Unity.InterceptionExtension.IInterceptingProxy.AddInterceptionBehavior",
methodAttributes);
// Setting return type
methodBuilder.SetReturnType(typeof(void));
// Adding parameters
methodBuilder.SetParameters(typeof(IInterceptionBehavior));
// Parameter method
methodBuilder.DefineParameter(1, ParameterAttributes.None, "interceptor");
ILGenerator il = methodBuilder.GetILGenerator();
// Writing body
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, proxyInterceptorPipelineField);
il.Emit(OpCodes.Ldarg_1);
il.EmitCall(OpCodes.Callvirt, InterceptionBehaviorPipelineMethods.Add, null);//IInterceptingProxy.AddInterceptionBehavior实际调的是红色
il.Emit(OpCodes.Ret);
typeBuilder.DefineMethodOverride(methodBuilder,IInterceptingProxyMethods.AddInterceptionBehavior);//红色的是AddInterceptionBehavior的methodinfo
}
InterceptionBehaviorPipelineMethods 在 Unity\Unity\Unity.Interception\Src\Interceptors\TypeInterceptors\VirtualMethodInterception\InterceptingClassGeneration\InterceptionBehaviorPipelineMethods.cs
internal static class InterceptionBehaviorPipelineMethods
{
internal static ConstructorInfo Constructor
{
get { return StaticReflection.GetConstructorInfo(() => new InterceptionBehaviorPipeline()); }
}
internal static MethodInfo Add
{
get { return StaticReflection.GetMethodInfo((InterceptionBehaviorPipelinepip) => pip.Add(null)); }
}
internal static MethodInfo Invoke
{
get { return StaticReflection.GetMethodInfo((InterceptionBehaviorPipeline pip) => pip.Invoke(null, null)); }
}
}
InterceptionBehaviorPipeline 在 E:\Program Files\Microsoft Unity Application Block 2.0\UnitySource\Source\Unity.Interception\Src\InterceptionBehaviors\InterceptionBehaviorPipeline.cs
public class InterceptionBehaviorPipeline
{
private readonly List<IInterceptionBehavior> interceptionBehaviors;
/// <summary>
/// Creates a new <see cref="HandlerPipeline"/> with an empty pipeline.
/// </summary>
public InterceptionBehaviorPipeline()
{
interceptionBehaviors = new List<IInterceptionBehavior>();
}
/// <summary>
/// Creates a new <see cref="HandlerPipeline"/> with the given collection
/// of <see cref="ICallHandler"/>s.
/// </summary>
/// <param name="interceptionBehaviors">Collection of interception behaviors to add to the pipeline.</param>
public InterceptionBehaviorPipeline(IEnumerable<IInterceptionBehavior> interceptionBehaviors)
{
Guard.ArgumentNotNull(interceptionBehaviors, "interceptionBehaviors");
this.interceptionBehaviors = new List<IInterceptionBehavior>(interceptionBehaviors);
}
/// <summary>
/// Get the number of interceptors in this pipeline.
/// </summary>
public int Count
{
get { return interceptionBehaviors.Count; }
}
/// <summary>
/// Execute the pipeline with the given input.
/// </summary>
/// <param name="input">Input to the method call.</param>
/// <param name="target">The ultimate target of the call.</param>
/// <returns>Return value from the pipeline.</returns>
public IMethodReturn Invoke(IMethodInvocation input, InvokeInterceptionBehaviorDelegate target)
{
if (interceptionBehaviors.Count == 0)
{
return target(input, null);
}
int interceptorIndex = 0;
IMethodReturn result = interceptionBehaviors[0].Invoke(input, delegate
{
++interceptorIndex;
if (interceptorIndex < interceptionBehaviors.Count)
{
return interceptionBehaviors[interceptorIndex].Invoke;
}
else
{
return target;
}
});
return result;
}
/// <summary>
/// Adds a <see cref="IInterceptionBehavior"/> to the pipeline.
/// </summary>
/// <param name="interceptionBehavior">The interception behavior to add.</param>
public void Add(IInterceptionBehavior interceptionBehavior)
{
Guard.ArgumentNotNull(interceptionBehavior, "interceptionBehavior");
this.interceptionBehaviors.Add(interceptionBehavior);
}
}
到这里,看见NewInstanceWithAdditionalInterfaces方法中:
foreach (IInterceptionBehavior interceptionBehavior in activeBehaviors)
{
proxy.AddInterceptionBehavior(interceptionBehavior);
}
AddInterceptionBehavior实际调用的是InterceptionBehaviorPipeline的Add方法
但是有一个环节:InterceptionBehaviorPipeline在proxy实例中是如何实例化的?
}
.......