forked from reflection-emit/Cauldron
-
Notifications
You must be signed in to change notification settings - Fork 18
Contructor interception
Reflection Emit edited this page Dec 15, 2017
·
1 revision
The IConstructorInterceptor interface provides three methods that resembles a try-catch-finally. The forth method OnBeforeInitialization is weaved before the base class call. Since the object is not created at this point, OnBeforeInitialization should be used with care. A class that implements this interface must also inherit from the Attribute class.
The interceptor attribute implementation:
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
public sealed class TestConstructorInterceptorA : Attribute, IConstructorInterceptor
{
public void OnBeforeInitialization(Type declaringType, MethodBase methodbase, object[] values)
{
}
public void OnEnter(Type declaringType, object instance, MethodBase methodbase, object[] values)
{
}
public void OnException(Exception e)
{
}
public void OnExit()
{
}
}
Your code:
public class ConstructorInterceptorTestClass
{
[TestConstructorInterceptorA]
public ConstructorInterceptorTestClass(string arg)
{
}
}
What gets compiled:
public ConstructorInterceptorTestClass(string arg)
{
var values = new object[]{ arg };
var constructorInterceptor = new TestConstructorInterceptorA();
constructorInterceptor.OnBeforeInitialization(typeof(ConstructorInterceptorTestClass), MethodBase.GetMethodFromHandle(methodof(ConstructorInterceptorTestClass..ctor()).MethodHandle, typeof(ConstructorInterceptorTestClass).TypeHandle), values);
base..ctor();
try
{
constructorInterceptor.OnEnter(typeof(ConstructorInterceptorTestClass), this, MethodBase.GetMethodFromHandle(methodof(ConstructorInterceptorTestClass..ctor()).MethodHandle, typeof(ConstructorInterceptorTestClass).TypeHandle), values);
}
catch (Exception e)
{
constructorInterceptor.OnException(e);
throw;
}
finally
{
constructorInterceptor.OnExit();
}
}