Inheritance: IAroundInvoke
        public void ShouldCallInstanceAroundInvokeProvider()
        {
            Type modifiedTargetType = GetModifiedTargetType();
            var instance = Activator.CreateInstance(modifiedTargetType);
            var aroundInvoke = new SampleAroundInvoke();
            var provider = new SampleAroundInvokeProvider(aroundInvoke);

            IModifiableType modified = (IModifiableType)instance;
            modified.AroundInvokeProvider = provider;
            MethodInfo targetMethod = modifiedTargetType.GetMethod("DoSomething");

            targetMethod.Invoke(instance, null);

            Assert.IsTrue(aroundInvoke.BeforeInvokeWasCalled);
            Assert.IsTrue(aroundInvoke.AfterInvokeWasCalled);
        }
        public void ShouldCallStaticAroundInvokeProvider()
        {
            Type modifiedTargetType = GetModifiedTargetType();
            var instance = Activator.CreateInstance(modifiedTargetType);
            var aroundInvoke = new SampleAroundInvoke();
            var provider = new SampleAroundInvokeProvider(aroundInvoke);

            AroundInvokeMethodCallRegistry.AddProvider(provider);

            MethodInfo targetMethod = modifiedTargetType.GetMethod("DoSomething");

            targetMethod.Invoke(instance, null);

            Assert.IsTrue(aroundInvoke.BeforeInvokeWasCalled);
            Assert.IsTrue(aroundInvoke.AfterInvokeWasCalled);
        }
        public void ShouldInvokeClassAroundInvokeProviderIfInterceptionIsEnabled()
        {
            var aroundInvoke = new SampleAroundInvoke();
            var provider = new SampleAroundInvokeProvider(aroundInvoke);

            Action<object> condition = (instance) =>
            {
                Assert.IsNotNull(instance);

                AroundMethodBodyRegistry.AddProvider(provider);
                instance.Invoke("DoSomething");

                Assert.IsTrue(aroundInvoke.BeforeInvokeWasCalled);
                Assert.IsTrue(aroundInvoke.AfterInvokeWasCalled);
            };

            Test(condition);
        }
        public void ShouldInvokeAroundInvokeProviderIfInterceptionIsEnabled()
        {
            var aroundInvoke = new SampleAroundInvoke();
            var provider = new SampleAroundInvokeProvider(aroundInvoke);
            Action<object> condition = (instance) =>
            {
                Assert.IsNotNull(instance);

                var modifiedInstance = (IModifiableType)instance;
                modifiedInstance.AroundInvokeProvider = provider;

                instance.Invoke("DoSomething");

                Assert.IsTrue(aroundInvoke.BeforeInvokeWasCalled);
                Assert.IsTrue(aroundInvoke.AfterInvokeWasCalled);
            };

            Test(condition);
        }
        public void ShouldInterceptStaticMethodWithAroundInvokeProvider()
        {
            Func<MethodReference, bool> methodFilter = m => m.Name == "DoSomething";

            var aroundInvoke = new SampleAroundInvoke();
            var provider = new SampleAroundInvokeProvider(aroundInvoke);

            AroundMethodBodyRegistry.AddProvider(provider);
            Action<Type> doTest = type =>
                                      {
                                          var doSomethingMethod = type.GetMethod("DoSomething");
                                          Assert.IsNotNull(doSomethingMethod);

                                          doSomethingMethod.Invoke(null, new object[0]);
                                          Assert.IsTrue(aroundInvoke.BeforeInvokeWasCalled);
                                          Assert.IsTrue(aroundInvoke.AfterInvokeWasCalled);
                                      };

            Test("SampleLibrary.dll", "SampleStaticClassWithStaticMethod", methodFilter, doTest);
        }
        public void ShouldNotInterceptConstructorsWhenIntereptingAllMethodCalls()
        {
            var modifiedTargetType = GetModifiedTargetType((name,type)=>type.InterceptAllMethodCalls());
            var instance = Activator.CreateInstance(modifiedTargetType);
            var aroundInvoke = new SampleAroundInvoke();
            var provider = new SampleAroundInvokeProvider(aroundInvoke);

            AroundInvokeMethodCallRegistry.AddProvider(provider);
            MethodInfo targetMethod = modifiedTargetType.GetMethod("DoSomething");
            targetMethod.Invoke(instance, null);

            Assert.IsTrue(aroundInvoke.BeforeInvokeWasCalled);
            Assert.IsTrue(aroundInvoke.AfterInvokeWasCalled);
        }
        public void ShouldNotInvokeClassAroundInvokeProviderIfInterceptionIsDisabled()
        {
            var aroundInvoke = new SampleAroundInvoke();
            var provider = new SampleAroundInvokeProvider(aroundInvoke);

            Action<object> condition = (instance) =>
            {
                Assert.IsNotNull(instance);

                var modified = (IModifiableType)instance;
                modified.IsInterceptionDisabled = true;

                AroundMethodBodyRegistry.AddProvider(provider);
                instance.Invoke("DoSomething");

                Assert.IsFalse(aroundInvoke.BeforeInvokeWasCalled);
                Assert.IsFalse(aroundInvoke.AfterInvokeWasCalled);
            };

            Test(condition);
        }
        public void ShouldNotImplementIModifiableTypeOnStaticClasses()
        {
            Func<MethodReference, bool> methodFilter = m => m.Name == "DoSomething";

            var aroundInvoke = new SampleAroundInvoke();
            var provider = new SampleAroundInvokeProvider(aroundInvoke);

            AroundMethodBodyRegistry.AddProvider(provider);
            Action<Type> doTest = type =>
            {
                var doSomethingMethod = type.GetMethod("DoSomething");
                Assert.IsNotNull(doSomethingMethod);
                Assert.IsFalse(type.GetInterfaces().Contains(typeof(IModifiableType)));
            };

            Test("SampleLibrary.dll", "SampleStaticClassWithStaticMethod", methodFilter, doTest);
        }