예제 #1
0
        int ICalculator.Add(int x, int y, int z)
        {
            var method     = this.GetInterfaceMethod <Func <int, int, int, int>, ICalculator>(((ICalculator)this).Add);
            var invocation = new MethodInvocation(this, method, x, y, z);
            var returns    = pipeline.Invoke(
                invocation,
                (input, next) => {
                try
                {
                    var returnValue = calculator != null ?
                                      calculator.Add(x, y, z) :
                                      default(int);

                    return(input.CreateValueReturn(returnValue, x, y, z));
                }
                catch (Exception ex)
                {
                    return(input.CreateExceptionReturn(ex));
                }
            }
                );

            var exception = returns.Exception;

            if (exception != null)
            {
                throw exception;
            }

            return(((int?)returns.ReturnValue).GetValueOrDefault());
        }
예제 #2
0
        public void Intercept(IInvocation invocation)
        {
            if (invocation.Method.DeclaringType == typeof(IProxy))
            {
                invocation.ReturnValue = Behaviors;
                return;
            }

            var input   = new MethodInvocation(invocation.InvocationTarget, invocation.Method, invocation.Arguments);
            var returns = pipeline.Invoke(input, (i, next) => {
                try  {
                    invocation.Proceed();
                    var returnValue = invocation.ReturnValue;
                    return(input.CreateValueReturn(returnValue, invocation.Arguments));
                } catch (Exception ex) {
                    return(input.CreateExceptionReturn(ex));
                }
            });

            var exception = returns.Exception;

            if (exception != null)
            {
                throw exception;
            }

            invocation.ReturnValue = returns.ReturnValue;
            for (int i = 0; i < returns.Outputs.Count; i++)
            {
                var name  = returns.Outputs.GetName(i);
                var index = input.Arguments.IndexOf(name);
                invocation.SetArgumentValue(index, returns.Outputs[index]);
            }
        }
예제 #3
0
        public void WhenInvokingPipelineWithNoBehaviors_ThenTargetCannotInvokeNext()
        {
            var pipeline = new BehaviorPipeline();

            Action a = WhenInvokingPipelineWithNoBehaviors_ThenInvokesTarget;

            Assert.Throws <NotSupportedException>(() => pipeline.Invoke(
                                                      new MethodInvocation(this, a.GetMethodInfo(), (m, n) => n.Invoke(m, n))));
        }
예제 #4
0
        public void WhenInvokingPipeline_ThenBehaviorsCanReturnException()
        {
            var pipeline = new BehaviorPipeline(
                new ExecuteHandler((m, n) => m.CreateExceptionReturn(new ArgumentException())));

            Action a = WhenInvokingPipeline_ThenBehaviorsCanReturnException;

            Assert.Throws <ArgumentException>(() => pipeline.Invoke(MethodInvocation.Create(this, a.GetMethodInfo()), true));
        }
예제 #5
0
        public override int this[int x, int y]
        {
            get
            {
                var method     = ((MethodInfo)MethodBase.GetCurrentMethod()).GetBaseDefinition();
                var invocation = new MethodInvocation(this, method, x, y);
                var returns    = pipeline.Invoke(
                    invocation,
                    (input, next) => {
                    try {
                        var returnValue = target != null ?
                                          target[x, y] :
                                          base[x, y];

                        return(input.CreateValueReturn(returnValue, x, y));
                    } catch (Exception ex) {
                        return(input.CreateExceptionReturn(ex));
                    }
                }
                    );

                var exception = returns.Exception;
                if (exception != null)
                {
                    throw exception;
                }

                return(((int?)returns.ReturnValue).GetValueOrDefault());
            }
            set
            {
                var method     = ((MethodInfo)MethodBase.GetCurrentMethod()).GetBaseDefinition();
                var invocation = new MethodInvocation(this, method);
                var returns    = pipeline.Invoke(
                    invocation,
                    (input, next) => {
                    try {
                        if (target != null)
                        {
                            target[x, y] = value;
                        }
                        else
                        {
                            base[x, y] = value;
                        }

                        return(input.CreateValueReturn(null));
                    } catch (Exception ex) {
                        return(input.CreateExceptionReturn(ex));
                    }
                }
                    );

                var exception = returns.Exception;
                if (exception != null)
                {
                    throw exception;
                }
            }
        }
예제 #6
0
        public void WhenInvokingPipelineWithNoBehaviors_ThenInvokesTarget()
        {
            var targetCalled = false;

            var pipeline = new BehaviorPipeline();

            Action a = WhenInvokingPipelineWithNoBehaviors_ThenInvokesTarget;

            pipeline.Invoke(new MethodInvocation(this, a.GetMethodInfo()),
                            new ExecuteDelegate((m, n) => { targetCalled = true; return(m.CreateValueReturn(null)); }));

            Assert.True(targetCalled);
        }
예제 #7
0
        public void WhenInvokingPipeline_ThenBehaviorsCanReturnValueWithArg()
        {
            var expected = new object();

            var pipeline = new BehaviorPipeline(
                new ExecuteHandler((m, n) => m.CreateValueReturn(expected, m.Arguments)));

            Func <object, object?> a = NonVoidMethodWithArg;

            var result = pipeline.Invoke(MethodInvocation.Create(this, a.GetMethodInfo(), expected));

            Assert.Equal(expected, result.ReturnValue);
        }
예제 #8
0
        public void WhenInvokingPipeline_ThenBehaviorsCanReturnValueWithArg()
        {
            var expected = new object();

            var pipeline = new BehaviorPipeline(
                new ExecuteDelegate((m, n) => m.CreateValueReturn(expected, new object())));

            Func <object, object> a = NonVoidMethodWithArg;

            var result = pipeline.Invoke(new MethodInvocation(this, a.GetMethodInfo(), expected),
                                         new ExecuteDelegate((m, n) => throw new NotImplementedException()));

            Assert.Equal(expected, result.ReturnValue);
        }
예제 #9
0
        public void WhenInvokingPipeline_ThenBehaviorsCanReturnValueWithOut()
        {
            var expected = new object();
            var output   = new object();

            var pipeline = new BehaviorPipeline(
                new ExecuteHandler((m, n) => m.CreateValueReturn(expected, new object(), output)));

            NonVoidMethodWithArgOutDelegate a = NonVoidMethodWithArgOut;

            var result = pipeline.Invoke(MethodInvocation.Create(this, a.GetMethodInfo(), expected, output));

            Assert.Equal(expected, result.ReturnValue);
            Assert.Equal(output, result.Outputs.GetValue(0));
        }
예제 #10
0
        public void WhenInvokingPipeline_ThenBehaviorsCanReturnValueWithOut()
        {
            var expected = new object();
            var output   = new object();

            var pipeline = new BehaviorPipeline(
                new InvokeBehavior((m, n) => m.CreateValueReturn(expected, new object(), output)));

            NonVoidMethodWithArgOutDelegate a = NonVoidMethodWithArgOut;

            var result = pipeline.Invoke(new MethodInvocation(this, a.GetMethodInfo(), expected, output),
                                         new InvokeBehavior((m, n) => throw new NotImplementedException()));

            Assert.Equal(expected, result.ReturnValue);
            Assert.Equal(output, result.Outputs[0]);
        }
예제 #11
0
        public void WhenInvokingPipeline_ThenBehaviorsCanPassDataWithContext()
        {
            var expected = Guid.NewGuid();
            var actual   = Guid.Empty;

            var pipeline = new BehaviorPipeline(
                new ExecuteHandler((m, n) => { m.Context["guid"] = expected; return(n.Invoke(m, n)); }),
                new ExecuteHandler((m, n) => { actual = (Guid)m.Context["guid"]; return(n.Invoke(m, n)); }));

            Action a = WhenInvokingPipeline_ThenBehaviorsCanPassDataWithContext;

            var result = pipeline.Invoke(MethodInvocation.Create(this, a.GetMethodInfo(), (m, n) => m.CreateReturn()));

            Assert.Equal(expected, actual);
            Assert.True(result.Context.ContainsKey("guid"));
            Assert.Equal(expected, result.Context["guid"]);
        }
예제 #12
0
        public void WhenInvokingPipeline_ThenBehaviorCanShortcircuitInvocation()
        {
            var firstCalled  = false;
            var secondCalled = false;
            var targetCalled = false;

            var pipeline = new BehaviorPipeline(
                new ExecuteDelegate((m, n) => { firstCalled = true; return(m.CreateValueReturn(null)); }),
                new ExecuteDelegate((m, n) => { secondCalled = true; return(n().Invoke(m, n)); }));

            Action a = WhenInvokingPipeline_ThenBehaviorCanShortcircuitInvocation;

            pipeline.Invoke(new MethodInvocation(this, a.GetMethodInfo()),
                            new ExecuteDelegate((m, n) => { targetCalled = true; return(m.CreateValueReturn(null)); }));

            Assert.True(firstCalled);
            Assert.False(secondCalled);
            Assert.False(targetCalled);
        }
예제 #13
0
        public void WhenInvokingPipeline_ThenSkipsNonApplicableBehaviors()
        {
            var firstCalled  = false;
            var secondCalled = false;
            var targetCalled = false;

            var pipeline = new BehaviorPipeline(
                StuntBehavior.Create((m, n) => { firstCalled = true; return(n().Invoke(m, n)); }),
                StuntBehavior.Create((m, n) => { secondCalled = true; return(n().Invoke(m, n)); }, m => false));

            Action a = WhenInvokingPipeline_ThenInvokesAllBehaviorsAndTarget;

            pipeline.Invoke(new MethodInvocation(this, a.GetMethodInfo()),
                            new ExecuteDelegate((m, n) => { targetCalled = true; return(m.CreateValueReturn(null)); }));

            Assert.True(firstCalled);
            Assert.False(secondCalled);
            Assert.True(targetCalled);
        }
예제 #14
0
        public void WhenInvokingPipeline_ThenInvokesAllBehaviorsAndTarget()
        {
            var firstCalled  = false;
            var secondCalled = false;
            var targetCalled = false;

            var pipeline = new BehaviorPipeline(
                new InvokeBehavior((m, n) => { firstCalled = true; return(n().Invoke(m, n)); }),
                new InvokeBehavior((m, n) => { secondCalled = true; return(n().Invoke(m, n)); }));

            Action a = WhenInvokingPipeline_ThenInvokesAllBehaviorsAndTarget;

            pipeline.Invoke(new MethodInvocation(this, a.GetMethodInfo()),
                            new InvokeBehavior((m, n) => { targetCalled = true; return(m.CreateValueReturn(null)); }));

            Assert.True(firstCalled);
            Assert.True(secondCalled);
            Assert.True(targetCalled);
        }
예제 #15
0
        public void WhenInvokingPipeline_ThenSkipsNonApplicableBehaviors()
        {
            var firstCalled  = false;
            var secondCalled = false;
            var targetCalled = false;

            var pipeline = new BehaviorPipeline(
                new AnonymousBehavior((m, n) => { firstCalled = true; return(n.Invoke(m, n)); }),
                new AnonymousBehavior((m, n) => { secondCalled = true; return(n.Invoke(m, n)); }, m => false));

            Action a = WhenInvokingPipeline_ThenInvokesAllBehaviorsAndTarget;

            pipeline.Invoke(MethodInvocation.Create(this, a.GetMethodInfo(),
                                                    (m, n) => { targetCalled = true; return(m.CreateReturn()); }));

            Assert.True(firstCalled);
            Assert.False(secondCalled);
            Assert.True(targetCalled);
        }
예제 #16
0
        public object Intercept(InvocationInfo invocation)
        {
            //ReturnValue = invocation.TargetMethod.Invoke (invocation.Target, invocation.Arguments);
            if (invocation.TargetMethod.DeclaringType == typeof(IProxy))
            {
                return(Behaviors);
            }

            var input   = new MethodInvocation(invocation.Target, invocation.TargetMethod, invocation.Arguments);
            var returns = pipeline.Invoke(input, (i, next) => {
                try {
                    var returnValue = invocation.TargetMethod.Invoke(invocation.Target, invocation.Arguments);
                    return(input.CreateValueReturn(returnValue, invocation.Arguments));
                }
                catch (TargetInvocationException tie) {
                    return(input.CreateExceptionReturn(tie.InnerException));
                }
                catch (Exception ex) {
                    return(input.CreateExceptionReturn(ex));
                }
            });

            var exception = returns.Exception;

            if (exception != null)
            {
                throw exception;
            }

            for (int i = 0; i < returns.Outputs.Count; i++)
            {
                var name  = returns.Outputs.GetName(i);
                var index = input.Arguments.IndexOf(name);
                invocation.SetArgument(index, returns.Outputs[index]);
            }

            return(returns.ReturnValue);
        }