示例#1
0
        public override IMessage Invoke(IMessage msg)
        {
            Guard.ArgumentNotNull(msg, "msg");

            IMethodCallMessage callMessage = (IMethodCallMessage)msg;

            if (callMessage.MethodBase.DeclaringType == typeof(IInterceptingProxy))
            {
                return(HandleInterceptingProxyMethod(callMessage));
            }

            HandlerPipeline pipeline = GetPipeline(TranslateInterfaceMethod(callMessage.MethodBase));

            TransparentProxyMethodInvocation invocation = new TransparentProxyMethodInvocation(callMessage, target);
            IMethodReturn result =
                pipeline.Invoke(
                    invocation,
                    delegate(IMethodInvocation input, GetNextHandlerDelegate getNext)
            {
                try
                {
                    object returnValue = callMessage.MethodBase.Invoke(target, invocation.Arguments);
                    return(input.CreateMethodReturn(returnValue, invocation.Arguments));
                }
                catch (TargetInvocationException ex)
                {
                    // The outer exception will always be a reflection exception; we want the inner, which is
                    // the underlying exception.
                    return(input.CreateExceptionMethodReturn(ex.InnerException));
                }
            });

            return(((TransparentProxyMethodReturn)result).ToMethodReturnMessage());
        }
示例#2
0
        private IMessage ExecuteGetPipeline(IMethodCallMessage callMessage)
        {
            MethodBase method = (MethodBase)callMessage.InArgs[0];

            method = TranslateInterfaceMethod(method);
            HandlerPipeline pipeline = GetPipeline(method);

            return(new ReturnMessage(pipeline, new object[0], 0, callMessage.LogicalCallContext, callMessage));
        }
        /// <summary>
        /// Retrieve the pipeline associated with the requested <paramref name="method"/>.
        /// </summary>
        /// <param name="method">The method for which the pipeline is being requested.</param>
        /// <returns>The handler pipeline for the given method. If no pipeline has
        /// been set, returns a new empty pipeline.</returns>
        public HandlerPipeline GetPipeline(MethodBase method)
        {
            HandlerPipelineKey key      = HandlerPipelineKey.ForMethod(method);
            HandlerPipeline    pipeline = emptyPipeline;

            if (pipelines.ContainsKey(key))
            {
                pipeline = pipelines[key];
            }
            return(pipeline);
        }
示例#4
0
        /// <summary>
        /// Called during the chain of responsibility for a build operation. The
        /// PostBuildUp method is called when the chain has finished the PreBuildUp
        /// phase and executes in reverse order from the PreBuildUp calls.
        /// </summary>
        /// <param name="context">Context of the build operation.</param>
        public override void PostBuildUp(IBuilderContext context)
        {
            // If it's already been intercepted, don't do it again.
            if (context.Existing is IInterceptingProxy)
            {
                return;
            }

            Type originalType;

            if (!BuildKey.TryGetType(context.OriginalBuildKey, out originalType))
            {
                return;
            }

            Type typeToIntercept;
            IInstanceInterceptionPolicy interceptionPolicy = FindInterceptorPolicy(context, out typeToIntercept);

            if (interceptionPolicy != null)
            {
                IInstanceInterceptor interceptor = interceptionPolicy.Interceptor;
                if (interceptor.CanIntercept(typeToIntercept))
                {
                    IUnityContainer    container   = BuilderContext.NewBuildUp <IUnityContainer>(context);
                    InjectionPolicy[]  policies    = BuilderContext.NewBuildUp <InjectionPolicy[]>(context);
                    PolicySet          allPolicies = new PolicySet(policies);
                    IInterceptingProxy proxy       = interceptor.CreateProxy(typeToIntercept, context.Existing);
                    bool hasHandlers = false;
                    foreach (MethodImplementationInfo method in interceptor.GetInterceptableMethods(typeToIntercept, context.Existing.GetType()))
                    {
                        HandlerPipeline pipeline = new HandlerPipeline(allPolicies.GetHandlersFor(method, container));
                        if (pipeline.Count > 0)
                        {
                            proxy.SetPipeline(interceptor.MethodInfoForPipeline(method), pipeline);
                            hasHandlers = true;
                        }
                    }
                    if (hasHandlers)
                    {
                        context.Existing = proxy;
                    }
                }
            }
        }
示例#5
0
        private HandlerPipeline CreatePipeline(MethodInfo method, IEnumerable<ICallHandler> handlers)
        {
            HandlerPipelineKey key = HandlerPipelineKey.ForMethod(method);
            if (pipelines.ContainsKey(key))
            {
                return pipelines[key];
            }

            if (method.GetBaseDefinition() == method)
            {
                pipelines[key] = new HandlerPipeline(handlers);
                return pipelines[key];
            }

            var basePipeline = CreatePipeline(method.GetBaseDefinition(), handlers);
            pipelines[key] = basePipeline;
            return basePipeline;
            
        }
        private HandlerPipeline CreatePipeline(MethodInfo method, IEnumerable <ICallHandler> handlers)
        {
            HandlerPipelineKey key = HandlerPipelineKey.ForMethod(method);

            if (pipelines.ContainsKey(key))
            {
                return(pipelines[key]);
            }

            if (method.GetBaseDefinition() == method)
            {
                pipelines[key] = new HandlerPipeline(handlers);
                return(pipelines[key]);
            }

            var basePipeline = CreatePipeline(method.GetBaseDefinition(), handlers);

            pipelines[key] = basePipeline;
            return(basePipeline);
        }
        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Guard.ArgumentNotNull(input, "input");
            Guard.ArgumentNotNull(getNext, "getNext");

            HandlerPipeline pipeline = GetPipeline(input.MethodBase);

            return(pipeline.Invoke(
                       input,
                       delegate(IMethodInvocation policyInjectionInput, GetNextHandlerDelegate policyInjectionInputGetNext)
            {
                try
                {
                    return getNext()(policyInjectionInput, getNext);
                }
                catch (TargetInvocationException ex)
                {
                    // The outer exception will always be a reflection exception; we want the inner, which is
                    // the underlying exception.
                    return policyInjectionInput.CreateExceptionMethodReturn(ex.InnerException);
                }
            }));
        }
        /// <summary>
        /// Called during the chain of responsibility for a build operation. The
        /// PostBuildUp method is called when the chain has finished the PreBuildUp
        /// phase and executes in reverse order from the PreBuildUp calls.
        /// </summary>
        /// <remarks>In this class, PostBuildUp checks to see if the object was proxyable,
        /// and if it was, wires up the handlers.</remarks>
        /// <param name="context">Context of the build operation.</param>
        public override void PostBuildUp(IBuilderContext context)
        {
            Guard.ArgumentNotNull(context, "context");

            IInterceptingProxy proxy = context.Existing as IInterceptingProxy;

            if (proxy == null)
            {
                return;
            }

            ITypeInterceptionPolicy interceptionPolicy = GetInterceptionPolicy(context);

            Type            typeToIntercept      = BuildKey.GetType(context.BuildKey);
            PolicySet       interceptionPolicies = new PolicySet(BuilderContext.NewBuildUp <InjectionPolicy[]>(context));
            IUnityContainer currentContainer     = BuilderContext.NewBuildUp <IUnityContainer>(context);

            foreach (MethodImplementationInfo item in interceptionPolicy.Interceptor.GetInterceptableMethods(typeToIntercept, typeToIntercept))
            {
                HandlerPipeline pipeline = new HandlerPipeline(
                    interceptionPolicies.GetHandlersFor(item, currentContainer));
                proxy.SetPipeline(interceptionPolicy.Interceptor.MethodInfoForPipeline(item), pipeline);
            }
        }
示例#9
0
 /// <summary>
 /// Set a new pipeline for a method.
 /// </summary>
 /// <param name="methodToken">Metadata token for the method to apply the pipeline to.</param>
 /// <param name="pipeline">The new pipeline.</param>
 public void SetPipeline(int methodToken, HandlerPipeline pipeline)
 {
     pipelines[methodToken] = pipeline;
 }
示例#10
0
 /// <summary>
 /// Set a new pipeline for a method.
 /// </summary>
 /// <param name="method">The method on which the pipeline should be set.</param>
 /// <param name="pipeline">The new pipeline.</param>
 public void SetPipeline(MethodBase method, HandlerPipeline pipeline)
 {
     HandlerPipelineKey key = HandlerPipelineKey.ForMethod(method);
     pipelines[key] = pipeline;
 }
        /// <summary>
        /// Set a new pipeline for a method.
        /// </summary>
        /// <param name="method">The method on which the pipeline should be set.</param>
        /// <param name="pipeline">The new pipeline.</param>
        public void SetPipeline(MethodBase method, HandlerPipeline pipeline)
        {
            HandlerPipelineKey key = HandlerPipelineKey.ForMethod(method);

            pipelines[key] = pipeline;
        }
示例#12
0
 public void SetPipeline(MethodBase method, HandlerPipeline pipeline)
 {
     Guard.ArgumentNotNull(method, "method");
     pipelines.SetPipeline(method.MetadataToken, pipeline);
 }