コード例 #1
0
        public void ParametersPassProperlyToTarget()
        {
            IInstanceInterceptor interceptor = new InterfaceInterceptor();
            MyDal target = new MyDal();

            CallCountHandler depositHandler  = new CallCountHandler();
            CallCountHandler withdrawHandler = new CallCountHandler();
            PipelineManager  manager         = new PipelineManager();

            manager.SetPipeline(typeof(IDal).GetMethod("Deposit"),
                                new HandlerPipeline(new ICallHandler[] { depositHandler }));
            manager.SetPipeline(typeof(IDal).GetMethod("Withdraw"),
                                new HandlerPipeline(new ICallHandler[] { withdrawHandler }));
            IInterceptingProxy proxy = interceptor.CreateProxy(typeof(IDal), target);

            proxy.AddInterceptionBehavior(new PolicyInjectionBehavior(manager));

            IDal intercepted = (IDal)proxy;

            intercepted.Deposit(100.0);
            intercepted.Deposit(25.95);
            intercepted.Deposit(19.95);

            intercepted.Withdraw(15.00);
            intercepted.Withdraw(6.25);

            Assert.AreEqual(3, depositHandler.CallCount);
            Assert.AreEqual(2, withdrawHandler.CallCount);

            Assert.AreEqual(100.0 + 25.95 + 19.95 - 15.00 - 6.25, target.Balance);
        }
コード例 #2
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>
        /// <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>
        /// <param name="pre"></param>
        public override void PostBuildUp(IBuilderContext context)
        {
            IInterceptingProxy proxy = context.Existing as IInterceptingProxy;

            if (proxy == null)
            {
                return;
            }

            var effectiveInterceptionBehaviorsPolicy =
                (EffectiveInterceptionBehaviorsPolicy)context.Policies
                .Get(context.OriginalBuildKey.Type,
                     context.OriginalBuildKey.Name,
                     typeof(EffectiveInterceptionBehaviorsPolicy), out _);

            if (effectiveInterceptionBehaviorsPolicy == null)
            {
                return;
            }

            foreach (var interceptionBehavior in effectiveInterceptionBehaviorsPolicy.Behaviors)
            {
                proxy.AddInterceptionBehavior(interceptionBehavior);
            }
        }
コード例 #3
0
        public void ThrowingFromInterceptedMethodStillRunsAllHandlers()
        {
            MethodInfo           thrower  = typeof(ClassWithDefaultCtor).GetMethod("NotImplemented");
            ClassWithDefaultCtor instance = WireupHelper.GetInterceptingInstance <ClassWithDefaultCtor>();
            IInterceptingProxy   pm       = (IInterceptingProxy)instance;

            CallCountHandler     handler     = new CallCountHandler();
            PostCallCountHandler postHandler = new PostCallCountHandler();
            HandlerPipeline      pipeline    = new HandlerPipeline(new ICallHandler[] { postHandler, handler });
            PipelineManager      manager     = new PipelineManager();

            manager.SetPipeline(thrower, pipeline);
            pm.AddInterceptionBehavior(new PolicyInjectionBehavior(manager));

            try
            {
                instance.NotImplemented();
                Assert.Fail("Should have thrown before getting here");
            }
            catch (NotImplementedException)
            {
                // We're expecting this one
            }

            Assert.AreEqual(1, handler.CallCount);
            Assert.AreEqual(1, postHandler.CallsCompleted);
        }
コード例 #4
0
        public void CanAddInterceptionBehaviorsToPipeline()
        {
            ClassWithDefaultCtor instance = WireupHelper.GetInterceptingInstance <ClassWithDefaultCtor>();
            IInterceptingProxy   pm       = (IInterceptingProxy)instance;

            CallCountInterceptionBehavior interceptor = new CallCountInterceptionBehavior();

            pm.AddInterceptionBehavior(interceptor);
        }
コード例 #5
0
        private void ApplyPolicies(IInterceptor interceptor, IInterceptingProxy proxy, object target, PolicySet policies)
        {
            PipelineManager manager = new PipelineManager();

            foreach (MethodImplementationInfo method in interceptor.GetInterceptableMethods(target.GetType(), target.GetType()))
            {
                HandlerPipeline pipeline = new HandlerPipeline(policies.GetHandlersFor(method, container));
                manager.SetPipeline(method.ImplementationMethodInfo, pipeline);
            }

            proxy.AddInterceptionBehavior(new PolicyInjectionBehavior(manager));
        }
コード例 #6
0
ファイル: Intercept.cs プロジェクト: ydb3600701/myunity
        public static object ThroughProxyWithAdditionalInterfaces(
            Type interceptedType,
            object target,
            IInstanceInterceptor interceptor,
            IEnumerable <IInterceptionBehavior> interceptionBehaviors,
            IEnumerable <Type> additionalInterfaces)
        {
            Guard.ArgumentNotNull(interceptedType, "interceptedType");
            Guard.ArgumentNotNull(target, "target");
            Guard.ArgumentNotNull(interceptor, "interceptor");
            Guard.ArgumentNotNull(interceptionBehaviors, "interceptionBehaviors");
            Guard.ArgumentNotNull(additionalInterfaces, "additionalInterfaces");

            if (!interceptor.CanIntercept(interceptedType))
            {
                throw new ArgumentException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Resources.InterceptionNotSupported,
                              interceptedType.FullName),
                          "interceptedType");
            }

            var behaviors = interceptionBehaviors.ToList();

            if (behaviors.Where(ib => ib == null).Count() > 0)
            {
                throw new ArgumentException(
                          string.Format(CultureInfo.CurrentCulture, Resources.NullBehavior),
                          "interceptionBehaviors");
            }

            var activeBehaviors = behaviors.Where(ib => ib.WillExecute).ToList();

            var allAdditionalInterfaces
                = GetAllAdditionalInterfaces(activeBehaviors, additionalInterfaces).ToList();

            // If no behaviors and no extra interfaces, nothing to do.
            if (activeBehaviors.Count == 0 && allAdditionalInterfaces.Count == 0)
            {
                return(target);
            }

            IInterceptingProxy proxy =
                interceptor.CreateProxy(interceptedType, target, allAdditionalInterfaces.ToArray());

            foreach (IInterceptionBehavior interceptionBehavior in activeBehaviors)
            {
                proxy.AddInterceptionBehavior(interceptionBehavior);
            }

            return(proxy);
        }
コード例 #7
0
        public void ProxyInterceptsEvents()
        {
            IInstanceInterceptor          interceptor          = new InterfaceInterceptor();
            ClassWithEvents               target               = new ClassWithEvents();
            IInterceptingProxy            proxy                = interceptor.CreateProxy(typeof(IDoEvents), target);
            CallCountInterceptionBehavior interceptionBehavior = new CallCountInterceptionBehavior();

            proxy.AddInterceptionBehavior(interceptionBehavior);

            ((IDoEvents)proxy).SomeEvent += (s, a) => { };

            Assert.AreEqual(1, interceptionBehavior.CallCount);
        }
コード例 #8
0
        internal static T GetInterceptedInstance <T>(string methodName, ICallHandler handler)
        {
            MethodInfo method = typeof(T).GetMethod(methodName);

            T instance = GetInterceptingInstance <T>();

            PipelineManager manager = new PipelineManager();

            manager.SetPipeline(method, new HandlerPipeline(Sequence.Collect(handler)));

            IInterceptingProxy pm = (IInterceptingProxy)instance;

            pm.AddInterceptionBehavior(new PolicyInjectionBehavior(manager));

            return(instance);
        }
コード例 #9
0
        public void CanInterceptMethodsThroughProxy()
        {
            CallCountInterceptionBehavior interceptor = new CallCountInterceptionBehavior();

            MBROWithOneMethod original    = new MBROWithOneMethod();
            MBROWithOneMethod intercepted = new InterceptingRealProxy(original, typeof(MBROWithOneMethod))
                                            .GetTransparentProxy() as MBROWithOneMethod;

            IInterceptingProxy proxy = (IInterceptingProxy)intercepted;

            proxy.AddInterceptionBehavior(interceptor);

            int result = intercepted.DoSomething(5);

            Assert.AreEqual(5 * 3, result);
            Assert.AreEqual(1, interceptor.CallCount);
        }
コード例 #10
0
        public void CanInterceptGenericMethodOnInterface()
        {
            var interceptor = new CallCountInterceptionBehavior();

            var original    = new ObjectWithGenericMethod();
            var intercepted = new InterceptingRealProxy(original, typeof(IInterfaceWithGenericMethod))
                              .GetTransparentProxy() as IInterfaceWithGenericMethod;

            IInterceptingProxy proxy = (IInterceptingProxy)intercepted;

            proxy.AddInterceptionBehavior(interceptor);

            var result = intercepted.GetTypeName(6);

            Assert.AreEqual("Int32", result);
            Assert.AreEqual(1, interceptor.CallCount);
        }
コード例 #11
0
        public void InterceptorCanInterceptProxyInstances()
        {
            CallCountInterceptionBehavior callCounter = new CallCountInterceptionBehavior();

            ProxiedInterfaceImpl impl     = new ProxiedInterfaceImpl();
            IProxiedInterface    instance = (IProxiedInterface) new MyProxy(typeof(IProxiedInterface), impl).GetTransparentProxy();

            IInstanceInterceptor interceptor = new InterfaceInterceptor();

            IInterceptingProxy proxy = (IInterceptingProxy)interceptor.CreateProxy(typeof(IProxiedInterface), (IProxiedInterface)instance);

            proxy.AddInterceptionBehavior(callCounter);

            IProxiedInterface inter = (IProxiedInterface)proxy;

            Assert.AreEqual("hello world", inter.DoSomething());
            Assert.AreEqual(1, callCounter.CallCount);
        }
コード例 #12
0
        public void GeneratedProxyCallsInterceptionBehaviors()
        {
            IInstanceInterceptor   interceptor = new InterfaceInterceptor();
            ImplementsInterfaceOne target      = new ImplementsInterfaceOne();

            IInterceptingProxy            proxy = interceptor.CreateProxy(typeof(IInterfaceOne), target);
            CallCountInterceptionBehavior interceptionBehavior = new CallCountInterceptionBehavior();

            proxy.AddInterceptionBehavior(interceptionBehavior);

            IInterfaceOne intercepted = (IInterfaceOne)proxy;

            intercepted.TargetMethod();
            intercepted.TargetMethod();
            intercepted.TargetMethod();

            Assert.AreEqual(3, interceptionBehavior.CallCount);
        }
コード例 #13
0
        private ISignatureTestTarget GetTarget()
        {
            var                interceptor = new InterfaceInterceptor();
            PolicySet          policySet   = GetPolicies();
            var                target      = new SignatureTestTarget();
            IInterceptingProxy proxy       = interceptor.CreateProxy(typeof(ISignatureTestTarget), target);

            PipelineManager manager = new PipelineManager();

            foreach (MethodImplementationInfo method in interceptor.GetInterceptableMethods(typeof(ISignatureTestTarget), typeof(SignatureTestTarget)))
            {
                HandlerPipeline pipeline = new HandlerPipeline(
                    policySet.GetHandlersFor(method, container));
                manager.SetPipeline(method.ImplementationMethodInfo, pipeline);
            }
            proxy.AddInterceptionBehavior(new PolicyInjectionBehavior(manager));

            return((ISignatureTestTarget)proxy);
        }
コード例 #14
0
        public void CallingMethodInvokesHandlers()
        {
            MethodInfo           methodOne = typeof(ClassWithDefaultCtor).GetMethod("MethodOne");
            ClassWithDefaultCtor instance  = WireupHelper.GetInterceptingInstance <ClassWithDefaultCtor>();
            IInterceptingProxy   pm        = (IInterceptingProxy)instance;

            CallCountHandler     handler     = new CallCountHandler();
            PostCallCountHandler postHandler = new PostCallCountHandler();
            HandlerPipeline      pipeline    = new HandlerPipeline(new ICallHandler[] { postHandler, handler });
            PipelineManager      manager     = new PipelineManager();

            manager.SetPipeline(methodOne, pipeline);
            pm.AddInterceptionBehavior(new PolicyInjectionBehavior(manager));

            instance.MethodOne();

            Assert.AreEqual(1, handler.CallCount);
            Assert.AreEqual(1, postHandler.CallsCompleted);
        }
コード例 #15
0
        public void CanGenerateProxyForClosedGeneric()
        {
            IInstanceInterceptor interceptor           = new InterfaceInterceptor();
            GenericImplementationOne <DateTime> target = new GenericImplementationOne <DateTime>();

            IInterceptingProxy            proxy = interceptor.CreateProxy(typeof(IGenericOne <DateTime>), target);
            CallCountInterceptionBehavior interceptionBehavior = new CallCountInterceptionBehavior();

            proxy.AddInterceptionBehavior(interceptionBehavior);

            IGenericOne <DateTime> intercepted = (IGenericOne <DateTime>)proxy;
            DateTime now = DateTime.Now;

            DateTime result = intercepted.DoSomething(now);

            Assert.AreEqual(now, result);
            Assert.IsTrue(target.DidSomething);
            Assert.AreEqual(1, interceptionBehavior.CallCount);
        }
コード例 #16
0
        public void ProxySendsOriginalWhenRaisingEvent()
        {
            // arrange
            IInstanceInterceptor          interceptor          = new InterfaceInterceptor();
            ClassWithEvents               target               = new ClassWithEvents();
            IInterceptingProxy            proxy                = interceptor.CreateProxy(typeof(IDoEvents), target);
            CallCountInterceptionBehavior interceptionBehavior = new CallCountInterceptionBehavior();

            proxy.AddInterceptionBehavior(interceptionBehavior);
            object sender = null;

            ((IDoEvents)proxy).SomeEvent += (s, a) => { sender = s; };

            // act
            ((IDoEvents)proxy).TriggerIt();

            // assert
            Assert.AreSame(target, sender);
            Assert.AreEqual(2, interceptionBehavior.CallCount);  // adding + calling TriggerIt
        }
コード例 #17
0
        public void RefsAndOutsAreProperlyHandled()
        {
            IInstanceInterceptor          interceptor = new InterfaceInterceptor();
            ImplementsHaveSomeRefsAndOuts target      = new ImplementsHaveSomeRefsAndOuts();

            IInterceptingProxy            proxy = interceptor.CreateProxy(typeof(IHaveSomeRefsAndOuts), target);
            CallCountInterceptionBehavior interceptionBehavior = new CallCountInterceptionBehavior();

            proxy.AddInterceptionBehavior(interceptionBehavior);

            IHaveSomeRefsAndOuts intercepted = (IHaveSomeRefsAndOuts)proxy;

            int    a;
            string s = "something";

            intercepted.DoSomething(out a, ref s);

            Assert.AreEqual(37, a);
            Assert.AreEqual("+++something***", s);
            Assert.AreEqual(1, interceptionBehavior.CallCount);
        }
コード例 #18
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>
        /// <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(ref BuilderContext context)
        {
            IInterceptingProxy proxy = context.Existing as IInterceptingProxy;

            if (proxy == null)
            {
                return;
            }

            var effectiveInterceptionBehaviorsPolicy = (EffectiveInterceptionBehaviorsPolicy)context.Registration.Get(
                typeof(EffectiveInterceptionBehaviorsPolicy));

            if (effectiveInterceptionBehaviorsPolicy == null)
            {
                return;
            }

            foreach (var interceptionBehavior in effectiveInterceptionBehaviorsPolicy.Behaviors)
            {
                proxy.AddInterceptionBehavior(interceptionBehavior);
            }
        }
コード例 #19
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>
        /// <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)
        {
            IInterceptingProxy proxy = (context ?? throw new ArgumentNullException(nameof(context))).Existing as IInterceptingProxy;

            if (proxy == null)
            {
                return;
            }

            EffectiveInterceptionBehaviorsPolicy effectiveInterceptionBehaviorsPolicy =
                context.Policies.Get <EffectiveInterceptionBehaviorsPolicy>(context.BuildKey, true);

            if (effectiveInterceptionBehaviorsPolicy == null)
            {
                return;
            }

            foreach (var interceptionBehavior in effectiveInterceptionBehaviorsPolicy.Behaviors)
            {
                proxy.AddInterceptionBehavior(interceptionBehavior);
            }
        }
コード例 #20
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>
        /// <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;
            }

            EffectiveInterceptionBehaviorsPolicy effectiveInterceptionBehaviorsPolicy =
                context.Policies.Get <EffectiveInterceptionBehaviorsPolicy>(context.BuildKey, true);

            if (effectiveInterceptionBehaviorsPolicy == null)
            {
                return;
            }

            foreach (var interceptionBehavior in effectiveInterceptionBehaviorsPolicy.Behaviors)
            {
                proxy.AddInterceptionBehavior(interceptionBehavior);
            }
        }
コード例 #21
0
        private void ApplyPolicies(IInterceptor interceptor, IInterceptingProxy proxy, object target, PolicySet policies)
        {
            PipelineManager manager = new PipelineManager();

            foreach (MethodImplementationInfo method in interceptor.GetInterceptableMethods(target.GetType(), target.GetType()))
            {
                HandlerPipeline pipeline = new HandlerPipeline(policies.GetHandlersFor(method, container));
                manager.SetPipeline(method.ImplementationMethodInfo, pipeline);
            }

            proxy.AddInterceptionBehavior(new PolicyInjectionBehavior(manager));
        }
        public static void PerformTest(IInterceptingProxy proxy)
        {
            var behavior = new FakeInterceptionBehavior();

            int argumentsCount = 0;

            object[] argumentsValuesByIndex = null;
            string[] argumentsNames         = null;
            object[] argumentsValuesByName  = null;
            int      inputsCount            = 0;

            object[] inputsValuesByIndex = null;
            string[] inputsNames         = null;
            object[] inputsValuesByName  = null;
            int      outputsCount        = 0;

            object[] outputsValuesByIndex = null;
            string[] outputsNames         = null;
            object[] outputsValuesByName  = null;
            object   originalReturnValue  = null;

            behavior.InvokeFunc = (IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) =>
            {
                argumentsCount         = input.Arguments.Count;
                argumentsValuesByIndex = Enumerable.Range(0, argumentsCount).Select(pi => input.Arguments[pi]).ToArray();
                argumentsNames         = Enumerable.Range(0, argumentsCount).Select(pi => input.Arguments.GetParameterInfo(pi).Name).ToArray();
                argumentsValuesByName  = argumentsNames.Select(an => input.Arguments[an]).ToArray();

                inputsCount         = input.Inputs.Count;
                inputsValuesByIndex = Enumerable.Range(0, inputsCount).Select(pi => input.Inputs[pi]).ToArray();
                inputsNames         = Enumerable.Range(0, inputsCount).Select(pi => input.Inputs.GetParameterInfo(pi).Name).ToArray();
                inputsValuesByName  = inputsNames.Select(an => input.Inputs[an]).ToArray();

                input.Inputs["param1"] = 11;
                input.Inputs[1]        = 13;
                input.Inputs["param4"] = 14;
                input.Inputs[3]        = 15;

                var result = getNext()(input, getNext);

                outputsCount         = result.Outputs.Count;
                outputsValuesByIndex = Enumerable.Range(0, outputsCount).Select(pi => result.Outputs[pi]).ToArray();
                outputsNames         = Enumerable.Range(0, outputsCount).Select(pi => result.Outputs.GetParameterInfo(pi).Name).ToArray();
                outputsValuesByName  = outputsNames.Select(an => result.Outputs[an]).ToArray();

                originalReturnValue = result.ReturnValue;

                result.Outputs[0]        = 82;
                result.Outputs["param4"] = 84;

                result.ReturnValue = 100;

                return(result);
            };

            proxy.AddInterceptionBehavior(behavior);

            int param2, param4;

            param4 = 4;
            var returnValue = ((ITypeWithAssertedParameterKinds)proxy).DoSomething(1, out param2, 3, ref param4, 5);

            Assert.AreEqual(100, returnValue);
            Assert.AreEqual(82, param2);
            Assert.AreEqual(84, param4);

            Assert.AreEqual(5, argumentsCount);
            CollectionAssertExtensions.AreEqual(new[] { 1, 0, 3, 4, 5 }, argumentsValuesByIndex);
            CollectionAssertExtensions.AreEqual(new[] { "param1", "param2", "param3", "param4", "param5" }, argumentsNames);
            CollectionAssertExtensions.AreEqual(new[] { 1, 0, 3, 4, 5 }, argumentsValuesByName);

            Assert.AreEqual(4, inputsCount);
            CollectionAssertExtensions.AreEqual(new[] { 1, 3, 4, 5 }, inputsValuesByIndex);
            CollectionAssertExtensions.AreEqual(new[] { "param1", "param3", "param4", "param5" }, inputsNames);
            CollectionAssertExtensions.AreEqual(new[] { 1, 3, 4, 5 }, inputsValuesByName);

            Assert.AreEqual(2, outputsCount);
            CollectionAssertExtensions.AreEqual(new[] { 25, 39 }, outputsValuesByIndex);
            CollectionAssertExtensions.AreEqual(new[] { "param2", "param4" }, outputsNames);
            CollectionAssertExtensions.AreEqual(new[] { 25, 39 }, outputsValuesByName);

            Assert.AreEqual(11 + 25 + 13 + 39 + 15, originalReturnValue);
        }
        public static void PerformTest(IInterceptingProxy proxy)
        {
            Mock<IInterceptionBehavior> behavior = new Mock<IInterceptionBehavior>();
            behavior.Setup(p => p.WillExecute).Returns(true);
            behavior.Setup(p => p.GetRequiredInterfaces()).Returns(Type.EmptyTypes);

            int argumentsCount = 0;
            object[] argumentsValuesByIndex = null;
            string[] argumentsNames = null;
            object[] argumentsValuesByName = null;
            int inputsCount = 0;
            object[] inputsValuesByIndex = null;
            string[] inputsNames = null;
            object[] inputsValuesByName = null;
            int outputsCount = 0;
            object[] outputsValuesByIndex = null;
            string[] outputsNames = null;
            object[] outputsValuesByName = null;
            object originalReturnValue = null;

            behavior.Setup(p => p.Invoke(It.IsAny<IMethodInvocation>(), It.IsAny<GetNextInterceptionBehaviorDelegate>()))
                .Returns((IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) =>
                {
                    argumentsCount = input.Arguments.Count;
                    argumentsValuesByIndex = Enumerable.Range(0, argumentsCount).Select(pi => input.Arguments[pi]).ToArray();
                    argumentsNames = Enumerable.Range(0, argumentsCount).Select(pi => input.Arguments.GetParameterInfo(pi).Name).ToArray();
                    argumentsValuesByName = argumentsNames.Select(an => input.Arguments[an]).ToArray();

                    inputsCount = input.Inputs.Count;
                    inputsValuesByIndex = Enumerable.Range(0, inputsCount).Select(pi => input.Inputs[pi]).ToArray();
                    inputsNames = Enumerable.Range(0, inputsCount).Select(pi => input.Inputs.GetParameterInfo(pi).Name).ToArray();
                    inputsValuesByName = inputsNames.Select(an => input.Inputs[an]).ToArray();

                    input.Inputs["param1"] = 11;
                    input.Inputs[1] = 13;
                    input.Inputs["param4"] = 14;
                    input.Inputs[3] = 15;

                    var result = getNext()(input, getNext);

                    outputsCount = result.Outputs.Count;
                    outputsValuesByIndex = Enumerable.Range(0, outputsCount).Select(pi => result.Outputs[pi]).ToArray();
                    outputsNames = Enumerable.Range(0, outputsCount).Select(pi => result.Outputs.GetParameterInfo(pi).Name).ToArray();
                    outputsValuesByName = outputsNames.Select(an => result.Outputs[an]).ToArray();

                    originalReturnValue = result.ReturnValue;

                    result.Outputs[0] = 82;
                    result.Outputs["param4"] = 84;

                    result.ReturnValue = 100;

                    return result;
                });

            proxy.AddInterceptionBehavior(behavior.Object);

            int param2, param4;
            param4 = 4;
            var returnValue = ((ITypeWithAssertedParameterKinds)proxy).DoSomething(1, out param2, 3, ref param4, 5);

            Assert.AreEqual(100, returnValue);
            Assert.AreEqual(82, param2);
            Assert.AreEqual(84, param4);

            Assert.AreEqual(5, argumentsCount);
            CollectionAssert.AreEqual(new[] { 1, 0, 3, 4, 5 }, argumentsValuesByIndex);
            CollectionAssert.AreEqual(new[] { "param1", "param2", "param3", "param4", "param5" }, argumentsNames);
            CollectionAssert.AreEqual(new[] { 1, 0, 3, 4, 5 }, argumentsValuesByName);

            Assert.AreEqual(4, inputsCount);
            CollectionAssert.AreEqual(new[] { 1, 3, 4, 5 }, inputsValuesByIndex);
            CollectionAssert.AreEqual(new[] { "param1", "param3", "param4", "param5" }, inputsNames);
            CollectionAssert.AreEqual(new[] { 1, 3, 4, 5 }, inputsValuesByName);

            Assert.AreEqual(2, outputsCount);
            CollectionAssert.AreEqual(new[] { 25, 39 }, outputsValuesByIndex);
            CollectionAssert.AreEqual(new[] { "param2", "param4" }, outputsNames);
            CollectionAssert.AreEqual(new[] { 25, 39 }, outputsValuesByName);

            Assert.AreEqual(11 + 25 + 13 + 39 + 15, originalReturnValue);
        }