Skip to content

Instantly share code, notes, and snippets.

@sinairv
Created August 13, 2015 05:13
Show Gist options
  • Save sinairv/1753fbad698776bcdf00 to your computer and use it in GitHub Desktop.
Save sinairv/1753fbad698776bcdf00 to your computer and use it in GitHub Desktop.
A demo of unity interceptors
using Microsoft.Practices.Unity.InterceptionExtension;
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace UnityInterceptionTest01
{
// You can create your own custom behaviors by implementing the IInterceptionBehavior
// interface. The interception behaviors are added to a pipeline and are called for
// each invocation of that pipeline.
// You must provide an implementation of the two IInterceptionBehavior interface
// methods, Invoke and GetRequiredInterfaces, and set the WillExecute property.
// The WillExecute property indicate if the behavior perform any operation when invoked.
// The GetRequiredInterfaces method returns the interfaces required by the behavior for
// the intercepted objects. The Invoke method execute the behavior processing.
// The Invoke method has two parameters: input and getNext. The input parameter
// rapresents the current call to the original method, the getNext parameter is a
// delegate to execute to get the next delegate in the behavior chain.
public class Program
{
static void Main()
{
Console.WriteLine("No interception!");
NoInterceptionDemo();
//Measure(NoInterceptionDemo);
Console.ReadLine();
Console.WriteLine("Interface interception!");
InterfaceInterceptionDemo();
//Measure(InterfaceInterceptionDemo);
Console.ReadLine();
Console.WriteLine("Virtual Method interception!");
VirtualMethodInterceptorDemo();
//Measure(VirtualMethodInterceptorDemo);
Console.ReadLine();
Console.WriteLine("Transparent Proxy interception!");
TransparentProxyInterceptorDemo();
//Measure(TransparentProxyInterceptorDemo);
Console.ReadLine();
// Measurements average of 10000 runs:
// regular 0.3369 ms
// interface 0.7169 ms
// virtual 0.6989 ms
// transparent proxy 1.1148 ms
}
public static void Measure(Action act)
{
const int count = 10000;
var stopWatch = new Stopwatch();
stopWatch.Reset();
for (int i = 0; i < count; i++)
{
stopWatch.Start();
act();
stopWatch.Stop();
}
Console.WriteLine("Each took {0} ms", (decimal)stopWatch.ElapsedMilliseconds / count);
}
public static void NoInterceptionDemo()
{
var calculator = new Calculator();
var result = calculator.Add(2, 3);
Console.WriteLine(result);
}
public static void InterfaceInterceptionDemo()
{
var behaviour = new MyBehaviour();
var interceptor = new InterfaceInterceptor();
var calculator = new Calculator();
var calculatorProxy = Intercept.ThroughProxy<ICalculator>(calculator, interceptor, new[] { behaviour });
var result = calculatorProxy.Add(2, 3);
Console.WriteLine(result);
}
public static void TransparentProxyInterceptorDemo()
{
var behaviour = new MyBehaviour();
var interceptor = new TransparentProxyInterceptor();
var calculator = new Calculator();
var calculatorProxy = Intercept.ThroughProxy<ICalculator>(calculator, interceptor, new[] { behaviour });
var result = calculatorProxy.Add(2, 3);
Console.WriteLine(result);
}
public static void VirtualMethodInterceptorDemo()
{
var behaviour = new MyBehaviour();
var interceptor = new VirtualMethodInterceptor();
var calculatorProxy = Intercept.NewInstance(typeof(Calculator), interceptor, new[] { behaviour }) as Calculator;
var result = calculatorProxy.Add(2, 3);
Console.WriteLine(result);
}
}
public interface ICalculator
{
int Add(int a, int b);
}
public class Calculator : ICalculator
{
public virtual int Add(int a, int b)
{
Console.WriteLine("Adding {0} to {1}", a, b);
return a + b;
}
}
public class MyBehaviour : IInterceptionBehavior
{
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
Console.WriteLine("Before");
Console.WriteLine("-> {0}:{1}", input.MethodBase.DeclaringType, input.MethodBase.Name);
var methodReturn = getNext()(input, getNext);
Console.WriteLine("After");
return methodReturn;
}
public bool WillExecute
{
get { return true; }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment