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()); }
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); }
/// <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; } } } }
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); } }
/// <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; }
/// <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; }
public void SetPipeline(MethodBase method, HandlerPipeline pipeline) { Guard.ArgumentNotNull(method, "method"); pipelines.SetPipeline(method.MetadataToken, pipeline); }