首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

unity 2.0 interception 学习二

2012-12-22 
unity 2.0 interception 学习2上一篇:public interface IHello{void SayHello()}private void button3_Cl

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


构造函数:


public InterceptingClassGenerator(Type typeToIntercept, params Type[] additionalInterfaces)
        {
            this.typeToIntercept = typeToIntercept;
            this.additionalInterfaces = additionalInterfaces;
            CreateTypeBuilder();

        }


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实例中是如何实例化的? 


internal static class InterceptingProxyImplementor
    {
        internal static FieldBuilder ImplementIInterceptingProxy(TypeBuilder typeBuilder)
        {
            typeBuilder.AddInterfaceImplementation(typeof(IInterceptingProxy));
            FieldBuilder proxyInterceptorPipelineField =
                typeBuilder.DefineField(
                    "pipeline",
                    typeof(InterceptionBehaviorPipeline),
                    FieldAttributes.Private | FieldAttributes.InitOnly);

            ImplementAddInterceptionBehavior(typeBuilder, proxyInterceptorPipelineField);

            return proxyInterceptorPipelineField;

        }

.......



热点排行