Skip to content

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.

Example:

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();
	    }
    }