Put aspects

In NetAspect, aspects can be put on fields/properties/methods/constructors. There is 2 ways to put an aspect on a member :

By attributes

Just consider the aspect as an attribute and put the attribute on the member.

The aspect :

public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforeMethod()
    {
        Called = true;
    }
}

Our business class :

public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int Value
    {
        get
        {
            return value;
        }
    }
    [Log]
    public int DivideBy(int v)
    {
        return value / v;
    }
}

By selecting the member

If you can't add an attribute to your member to weave, you can just declare a select method in your aspect.

The aspect :

public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforeMethod()
    {
        Called = true;
    }
    public static bool SelectMethod(MethodInfo method)
    {
        return method.Name == "DivideBy";
    }
}

Our business class :

public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int Value
    {
        get
        {
            return value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}

Interceptors

An interceptor is a method declared in the aspect and which will be called at certain moment after the weaving.
Some parameters can be added to the interceptor to get more information

The following interceptors are available :

For an aspect put on a method

BeforeMethod

This interceptor is executed before the code of the method is executed

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int Value
    {
        get
        {
            return value;
        }
    }
    [Log]
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforeMethod(object instance, MethodInfo method, object[] parameters, int v, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("DivideBy", method.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(12, v);
        Assert.AreEqual(32, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part1Sample1BeforeMethodPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"Method\Part1Sample1BeforeMethodPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    Assert.AreEqual(2, myInt.DivideBy(12));
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

AfterMethod

This interceptor is executed after the code of the method is executed

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int Value
    {
        get
        {
            return value;
        }
    }
    [Log]
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void AfterMethod(object instance, MethodInfo method, object[] parameters, int v, int result, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("DivideBy", method.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(12, v);
        Assert.AreEqual(2, result);
        Assert.AreEqual(31, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part1Sample2AfterMethodPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"Method\Part1Sample2AfterMethodPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    Assert.AreEqual(2, myInt.DivideBy(12));
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

OnExceptionMethod

This interceptor is executed when an exception is raised by the method

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int Value
    {
        get
        {
            return value;
        }
    }
    [Log]
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void OnExceptionMethod(object instance, MethodInfo method, object[] parameters, int v, Exception exception, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("DivideBy", method.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(0, v);
        Assert.AreEqual("DivideByZeroException", exception.GetType().Name);
        Assert.AreEqual(31, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part1Sample3OnExceptionMethodPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"Method\Part1Sample3OnExceptionMethodPossibilityTest.cs"));
    }
}
// The following code is working
{
    try
    {
        var myInt = new MyInt(24);
        myInt.DivideBy(0);
        Assert.Fail("Must raise an exception");
    }
    catch (DivideByZeroException)
    {
    }
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

OnFinallyMethod

This interceptor is executed after the code of the method is executed if an exception is raised or not

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int Value
    {
        get
        {
            return value;
        }
    }
    [Log]
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void OnFinallyMethod(object instance, MethodInfo method, object[] parameters, int v, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("DivideBy", method.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(12, v);
        Assert.AreEqual(31, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part1Sample4OnFinallyMethodPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"Method\Part1Sample4OnFinallyMethodPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    myInt.DivideBy(12);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

BeforeCallMethod

This interceptor is executed before calling the method

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    [Log]
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforeCallMethod(MyIntUser callerInstance, MyInt instance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, object[] parameters, int v, MethodBase callerMethod, MethodInfo method)
    {
        Called = true;
        Assert.NotNull(callerInstance);
        Assert.NotNull(callerInstance);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(32, lineNumber);
        Assert.AreEqual("Part6Sample1BeforeInstructionCallMethodPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(3, callerParameters.Length);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual("Compute", callerMethod.Name);
        Assert.AreEqual("DivideBy", method.Name);
        Assert.AreEqual(6, v);
    }
}
// The following code is working
{
    var user = new MyIntUser();
    Assert.AreEqual("Result : 2", user.Compute(12, 6, "Result : {0}"));
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

callerInstance

this parameter is used to have the instance of the object that call the weaved member

instance

this parameter is used to have the this of the weaved member

columnNumber

this parameter is used to get the column of the instruction that call our member

lineNumber

this parameter is used to get the line of the instruction that call our member

fileName

this parameter is used to get the file name of the instruction that call our membe

filePath

this parameter is used to get the file path of the instruction that call our membe

callerParameters

this parameter is used to have the parameters of the method that will call the weaved member

parameters

this parameter is used to get the values of the parameters of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

method

this parameter is used to get some information about the weaved method

AfterCallMethod

This interceptor is executed after calling the method

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    [Log]
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void AfterCallMethod(MyIntUser callerInstance, MyInt instance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, object[] parameters, int v, MethodBase callerMethod, MethodInfo method, int result)
    {
        Called = true;
        Assert.NotNull(callerInstance);
        Assert.NotNull(callerInstance);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(32, lineNumber);
        Assert.AreEqual("Part6Sample2AfterInstructionCallMethodPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(3, callerParameters.Length);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual("Compute", callerMethod.Name);
        Assert.AreEqual("DivideBy", method.Name);
        Assert.AreEqual(6, v);
        Assert.AreEqual(2, result);
    }
}
// The following code is working
{
    var user = new MyIntUser();
    Assert.AreEqual("Result : 2", user.Compute(12, 6, "Result : {0}"));
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

callerInstance

this parameter is used to have the instance of the object that call the weaved member

instance

this parameter is used to have the this of the weaved member

columnNumber

this parameter is used to get the column of the instruction that call our member

lineNumber

this parameter is used to get the line of the instruction that call our member

fileName

this parameter is used to get the file name of the instruction that call our membe

filePath

this parameter is used to get the file path of the instruction that call our membe

callerParameters

this parameter is used to have the parameters of the method that will call the weaved member

parameters

this parameter is used to get the values of the parameters of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

method

this parameter is used to get some information about the weaved method

result

this parameter is used to get the return value of the weaved method


For an aspect put on a constructor

BeforeConstructor

This interceptor is executed before the code of the constructor is executed

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    [Log]
    public MyInt(int intValue)
    {
        value = intValue;
    }
    public int Value
    {
        get
        {
            return value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforeConstructor(object instance, ConstructorInfo constructor, object[] parameters, int intValue, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual(".ctor", constructor.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(24, intValue);
        Assert.AreEqual(20, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part2Sample1BeforeConstructorPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"Constructor\Part2Sample1BeforeConstructorPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

AfterConstructor

This interceptor is executed after the code of the constructor is executed

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    [Log]
    public MyInt(int intValue)
    {
        value = intValue;
    }
    public int Value
    {
        get
        {
            return value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void AfterConstructor(object instance, ConstructorInfo constructor, object[] parameters, int intValue, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual(".ctor", constructor.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(24, intValue);
        Assert.AreEqual(19, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part2Sample2AfterConstructorPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"Constructor\Part2Sample2AfterConstructorPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    Assert.AreEqual(2, myInt.DivideBy(12));
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

OnExceptionConstructor

This interceptor is executed when an exception is raised by the constructor

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    [Log]
    public MyInt(int intValue)
    {
        if (value == 0)
            throw new NotSupportedException();
        value = intValue;
    }
    public int Value
    {
        get
        {
            return value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void OnExceptionConstructor(object instance, ConstructorInfo constructor, object[] parameters, int intValue, Exception exception, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual(".ctor", constructor.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(0, intValue);
        Assert.AreEqual("NotSupportedException", exception.GetType().Name);
        Assert.AreEqual(19, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part2Sample3OnExceptionConstructorPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"Constructor\Part2Sample3OnExceptionConstructorPossibilityTest.cs"));
    }
}
// The following code is working
{
    try
    {
        new MyInt(0);
        Assert.Fail("Must raise an exception");
    }
    catch (NotSupportedException)
    {
    }
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

OnFinallyConstructor

This interceptor is executed after the code of the constructor is executed if an exception is raised or not

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    [Log]
    public MyInt(int intValue)
    {
        value = intValue;
    }
    public int Value
    {
        get
        {
            return value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void OnFinallyConstructor(object instance, ConstructorInfo constructor, object[] parameters, int intValue, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual(".ctor", constructor.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(24, intValue);
        Assert.AreEqual(19, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part2Sample4OnFinallyConstructorPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"Constructor\Part2Sample4OnFinallyConstructorPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    myInt.DivideBy(12);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

BeforeCallConstructor

This interceptor is executed before calling the constructor

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    [Log]
    public MyInt(int value)
    {
        this.value = value;
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforeCallConstructor(MyIntUser callerInstance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, object[] parameters, int value, MethodBase callerMethod, ConstructorInfo constructor)
    {
        Called = true;
        Assert.NotNull(callerInstance);
        Assert.AreEqual(".ctor", constructor.Name);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(31, lineNumber);
        Assert.AreEqual("Part8Sample1BeforeInstructionCallMethodPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(3, callerParameters.Length);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual("Compute", callerMethod.Name);
        Assert.AreEqual(12, value);
    }
}
// The following code is working
{
    var user = new MyIntUser();
    Assert.AreEqual("Result : 2", user.Compute(12, 6, "Result : {0}"));
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

callerInstance

this parameter is used to have the instance of the object that call the weaved member

columnNumber

this parameter is used to get the column of the instruction that call our member

lineNumber

this parameter is used to get the line of the instruction that call our member

fileName

this parameter is used to get the file name of the instruction that call our membe

filePath

this parameter is used to get the file path of the instruction that call our membe

callerParameters

this parameter is used to have the parameters of the method that will call the weaved member

parameters

this parameter is used to get the values of the parameters of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

AfterCallConstructor

This interceptor is executed after calling the constructor

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    [Log]
    public MyInt(int value)
    {
        this.value = value;
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void AfterCallConstructor(MyIntUser callerInstance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, object[] parameters, int value, MethodBase callerMethod, ConstructorInfo constructor)
    {
        Called = true;
        Assert.NotNull(callerInstance);
        Assert.NotNull(constructor);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(31, lineNumber);
        Assert.AreEqual("Part8Sample2AfterInstructionCallMethodPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(3, callerParameters.Length);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual("Compute", callerMethod.Name);
        Assert.AreEqual(12, value);
    }
}
// The following code is working
{
    var user = new MyIntUser();
    Assert.AreEqual("Result : 2", user.Compute(12, 6, "Result : {0}"));
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

callerInstance

this parameter is used to have the instance of the object that call the weaved member

columnNumber

this parameter is used to get the column of the instruction that call our member

lineNumber

this parameter is used to get the line of the instruction that call our member

fileName

this parameter is used to get the file name of the instruction that call our membe

filePath

this parameter is used to get the file path of the instruction that call our membe

callerParameters

this parameter is used to have the parameters of the method that will call the weaved member

parameters

this parameter is used to get the values of the parameters of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method


For an aspect put on a property

BeforePropertyGetMethod

This interceptor is executed before the code of the property is executed

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    [Log]
    public int Value
    {
        get
        {
            return value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforePropertyGetMethod(object instance, PropertyInfo property, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("Value", property.Name);
        Assert.AreEqual(28, lineNumber);
        Assert.AreEqual(17, columnNumber);
        Assert.AreEqual("Part3Sample1BeforePropertyGetPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"PropertyGet\Part3Sample1BeforePropertyGetPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    Assert.AreEqual(24, myInt.Value);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

AfterPropertyGetMethod

This interceptor is executed after the code of the property is executed

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    [Log]
    public int Value
    {
        get
        {
            return value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void AfterPropertyGetMethod(object instance, PropertyInfo property, int result, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("Value", property.Name);
        Assert.AreEqual(24, result);
        Assert.AreEqual(27, lineNumber);
        Assert.AreEqual(17, columnNumber);
        Assert.AreEqual("Part3Sample2AfterProeprtyGetPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"PropertyGet\Part3Sample2AfterProeprtyGetPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    Assert.AreEqual(24, myInt.Value);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

OnExceptionPropertyGetMethod

This interceptor is executed when an exception is raised by the property

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    [Log]
    public int Value
    {
        get
        {
            if (value == 0)
                throw new NotSupportedException("Must not be 0");
            return value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void OnExceptionPropertyGetMethod(object instance, PropertyInfo property, Exception exception, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("Value", property.Name);
        Assert.AreEqual("NotSupportedException", exception.GetType().Name);
        Assert.AreEqual(28, lineNumber);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual("Part3Sample3OnExceptionPropertyGetPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"PropertyGet\Part3Sample3OnExceptionPropertyGetPossibilityTest.cs"));
    }
}
// The following code is working
{
    try
    {
        var myInt = new MyInt(0);
        int val = myInt.Value;
        Assert.Fail("Must raise an exception");
    }
    catch (NotSupportedException)
    {
    }
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

OnFinallyPropertyGetMethod

This interceptor is executed after the code of the property is executed if an exception is raised or not

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    [Log]
    public int Value
    {
        get
        {
            return value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void OnFinallyPropertyGetMethod(object instance, PropertyInfo property, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("Value", property.Name);
        Assert.AreEqual(27, lineNumber);
        Assert.AreEqual(17, columnNumber);
        Assert.AreEqual("Part3Sample4OnFinallyPropertyGetPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"PropertyGet\Part3Sample4OnFinallyPropertyGetPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    int val = myInt.Value;
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

BeforePropertySetMethod

This interceptor is executed before the code of the property is executed

The sample :

// Our business class
public class MyInt
{
    private int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    [Log]
    public int Value
    {
        set
        {
            this.value = value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforePropertySetMethod(object instance, PropertyInfo property, int propertyValue, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("Value", property.Name);
        Assert.AreEqual(32, propertyValue);
        Assert.AreEqual(28, lineNumber);
        Assert.AreEqual(17, columnNumber);
        Assert.AreEqual("Part4Sample1BeforePropertySetPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"PropertySet\Part4Sample1BeforePropertySetPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    myInt.Value = 32;
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

AfterPropertySetMethod

This interceptor is executed after the code of the property is executed

The sample :

// Our business class
public class MyInt
{
    private int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    [Log]
    public int Value
    {
        set
        {
            this.value = value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void AfterPropertySetMethod(object instance, PropertyInfo property, int propertyValue, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("Value", property.Name);
        Assert.AreEqual(32, propertyValue);
        Assert.AreEqual(27, lineNumber);
        Assert.AreEqual(17, columnNumber);
        Assert.AreEqual("Part4Sample2AfterPropertySetPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"PropertySet\Part4Sample2AfterPropertySetPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    myInt.Value = 32;
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

OnExceptionPropertySetMethod

This interceptor is executed when an exception is raised by the property

The sample :

// Our business class
public class MyInt
{
    private int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    [Log]
    public int Value
    {
        set
        {
            if (value == 0)
                throw new NotSupportedException("Must not be 0");
            this.value = value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void OnExceptionPropertySetMethod(object instance, PropertyInfo property, Exception exception, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("Value", property.Name);
        Assert.AreEqual("NotSupportedException", exception.GetType().Name);
        Assert.AreEqual(28, lineNumber);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual("Part4Sample3OnExceptionPropertySetPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"PropertySet\Part4Sample3OnExceptionPropertySetPossibilityTest.cs"));
    }
}
// The following code is working
{
    try
    {
        var myInt = new MyInt(0);
        myInt.Value = 0;
        Assert.Fail("Must raise an exception");
    }
    catch (NotSupportedException)
    {
    }
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

OnFinallyPropertySetMethod

This interceptor is executed after the code of the property is executed if an exception is raised or not

The sample :

// Our business class
public class MyInt
{
    private int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    [Log]
    public int Value
    {
        set
        {
            this.value = value;
        }
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void OnFinallyPropertySetMethod(object instance, PropertyInfo property, int propertyValue, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.AreEqual(typeof(MyInt), instance.GetType());
        Assert.AreEqual("Value", property.Name);
        Assert.AreEqual(12, propertyValue);
        Assert.AreEqual(27, lineNumber);
        Assert.AreEqual(17, columnNumber);
        Assert.AreEqual("Part4Sample4OnFinallyPropertySetPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"PropertySet\Part4Sample4OnFinallyPropertySetPossibilityTest.cs"));
    }
}
// The following code is working
{
    var myInt = new MyInt(24);
    myInt.Value = 12;
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

BeforeGetProperty

This interceptor is executed before the code of the property is executed

The sample :

// Our business class
public class MyInt
{
    public MyInt(int value)
    {
        Value = value;
    }
    [Log]
    private int Value
    {
        get;
        set;
    }
    public int DivideBy(int v)
    {
        return Value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforeGetProperty(MyInt callerInstance, MyInt instance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, MethodBase callerMethod, PropertyInfo property)
    {
        Called = true;
        Assert.AreEqual(callerInstance, instance);
        Assert.NotNull(callerInstance);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(39, lineNumber);
        Assert.AreEqual("Part7Sample1BeforeInstructionGetPropertyPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(1, callerParameters.Length);
        Assert.AreEqual("DivideBy", callerMethod.Name);
        Assert.AreEqual("Value", property.Name);
    }
}
// The following code is working
{
    var classToWeave_L = new MyInt(12);
    classToWeave_L.DivideBy(6);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

AfterGetProperty

This interceptor is executed after the code of the property is executed

The sample :

// Our business class
public class MyInt
{
    public MyInt(int value)
    {
        Value = value;
    }
    [Log]
    private int Value
    {
        get;
        set;
    }
    public int DivideBy(int v)
    {
        return Value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void AfterGetProperty(MyInt callerInstance, MyInt instance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, MethodBase callerMethod, PropertyInfo property, int propertyValue)
    {
        Called = true;
        Assert.AreEqual(callerInstance, instance);
        Assert.NotNull(callerInstance);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(39, lineNumber);
        Assert.AreEqual("Part7Sample2AfterInstructionGetPropertyPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(1, callerParameters.Length);
        Assert.AreEqual("DivideBy", callerMethod.Name);
        Assert.AreEqual("Value", property.Name);
        Assert.AreEqual(12, propertyValue);
    }
}
// The following code is working
{
    var classToWeave_L = new MyInt(12);
    classToWeave_L.DivideBy(6);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

callerInstance

this parameter is used to have the instance of the object that call the weaved member

instance

this parameter is used to have the this of the weaved member

columnNumber

this parameter is used to get the column of the first instruction in the weaved method

lineNumber

this parameter is used to get the line of the first instruction in the weaved method

fileName

this parameter is used to get the file name of the weaved method

filePath

this parameter is used to get the file path of the weaved method

callerParameters

this parameter is used to have the parameters of the method that will call the weaved member

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

propertyValue

this parameter is used to get the value of the property

BeforeUpdateProperty

This interceptor is executed before the code of the property is executed

The sample :

// Our business class
public class MyInt
{
    [Log]
    private int Value
    {
        get;
        set;
    }
    public void UpdateValue(int intValue)
    {
        Value = intValue;
    }
    public int DivideBy(int v)
    {
        return Value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforeUpdateProperty(MyInt callerInstance, MyInt instance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, MethodBase callerMethod, PropertyInfo property, int newPropertyValue)
    {
        Called = true;
        Assert.AreEqual(callerInstance, instance);
        Assert.NotNull(callerInstance);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(34, lineNumber);
        Assert.AreEqual("Part7Sample3BeforeInstructionSetPropertyPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(1, callerParameters.Length);
        Assert.AreEqual("UpdateValue", callerMethod.Name);
        Assert.AreEqual("Value", property.Name);
        Assert.AreEqual(6, newPropertyValue);
    }
}
// The following code is working
{
    var classToWeave_L = new MyInt();
    classToWeave_L.UpdateValue(6);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

callerInstance

this parameter is used to have the instance of the object that call the weaved member

instance

this parameter is used to have the this of the weaved member

columnNumber

this parameter is used to get the column of the first instruction in the weaved method

lineNumber

this parameter is used to get the line of the first instruction in the weaved method

fileName

this parameter is used to get the file name of the weaved method

filePath

this parameter is used to get the file path of the weaved method

callerParameters

this parameter is used to have the parameters of the method that will call the weaved member

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

newPropertyValue

this parameter is used to get the value of the value that will be affected to the property

AfterUpdateProperty

This interceptor is executed after the code of the property is executed

The sample :

// Our business class
public class MyInt
{
    [Log]
    private int Value
    {
        get;
        set;
    }
    public void UpdateValue(int intValue)
    {
        Value = intValue;
    }
    public int DivideBy(int v)
    {
        return Value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void AfterUpdateProperty(MyInt callerInstance, MyInt instance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, MethodBase callerMethod, PropertyInfo property, int newPropertyValue)
    {
        Called = true;
        Assert.AreEqual(callerInstance, instance);
        Assert.NotNull(callerInstance);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(34, lineNumber);
        Assert.AreEqual("Part7Sample4AfterInstructionSetPropertyPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(1, callerParameters.Length);
        Assert.AreEqual("UpdateValue", callerMethod.Name);
        Assert.AreEqual("Value", property.Name);
        Assert.AreEqual(6, newPropertyValue);
    }
}
// The following code is working
{
    var classToWeave_L = new MyInt();
    classToWeave_L.UpdateValue(6);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

callerInstance

this parameter is used to have the instance of the object that call the weaved member

instance

this parameter is used to have the this of the weaved member

columnNumber

this parameter is used to get the column of the first instruction in the weaved method

lineNumber

this parameter is used to get the line of the first instruction in the weaved method

fileName

this parameter is used to get the file name of the weaved method

filePath

this parameter is used to get the file path of the weaved method

callerParameters

this parameter is used to have the parameters of the method that will call the weaved member

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

newPropertyValue

this parameter is used to get the value of the value that will be affected to the property


For an aspect put on a field

BeforeGetField

This interceptor is executed before the code of the field is executed

The sample :

// Our business class
public class MyInt
{
    [Log]
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforeGetField(MyInt callerInstance, MyInt instance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, MethodBase callerMethod, FieldInfo field)
    {
        Called = true;
        Assert.AreEqual(callerInstance, instance);
        Assert.NotNull(callerInstance);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(38, lineNumber);
        Assert.AreEqual("Part5Sample1BeforeInstructionGetFieldPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(1, callerParameters.Length);
        Assert.AreEqual("DivideBy", callerMethod.Name);
        Assert.AreEqual("value", field.Name);
    }
}
// The following code is working
{
    var classToWeave_L = new MyInt(12);
    classToWeave_L.DivideBy(6);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

AfterGetField

This interceptor is executed after the code of the field is executed

The sample :

// Our business class
public class MyInt
{
    [Log]
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void AfterGetField(MyInt callerInstance, MyInt instance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, MethodBase callerMethod, FieldInfo field, int fieldValue)
    {
        Called = true;
        Assert.AreEqual(callerInstance, instance);
        Assert.NotNull(callerInstance);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(38, lineNumber);
        Assert.AreEqual("Part5Sample2AfterInstructionGetFieldPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(1, callerParameters.Length);
        Assert.AreEqual("DivideBy", callerMethod.Name);
        Assert.AreEqual("value", field.Name);
        Assert.AreEqual(12, fieldValue);
    }
}
// The following code is working
{
    var classToWeave_L = new MyInt(12);
    classToWeave_L.DivideBy(6);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

BeforeUpdateField

This interceptor is executed before the code of the field is executed

The sample :

// Our business class
public class MyInt
{
    [Log]
    private int value;
    public void UpdateValue(int intValue)
    {
        value = intValue;
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforeUpdateField(MyInt callerInstance, MyInt instance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, MethodBase callerMethod, FieldInfo field, int newFieldValue)
    {
        Called = true;
        Assert.AreEqual(callerInstance, instance);
        Assert.NotNull(callerInstance);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(33, lineNumber);
        Assert.AreEqual("Part5Sample3BeforeInstructionSetFieldPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(1, callerParameters.Length);
        Assert.AreEqual("UpdateValue", callerMethod.Name);
        Assert.AreEqual("value", field.Name);
        Assert.AreEqual(6, newFieldValue);
    }
}
// The following code is working
{
    var classToWeave_L = new MyInt();
    classToWeave_L.UpdateValue(6);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

callerInstance

this parameter is used to have the instance of the object that call the weaved member

instance

this parameter is used to have the this of the weaved member

columnNumber

this parameter is used to get the column of the first instruction in the weaved method

lineNumber

this parameter is used to get the line of the first instruction in the weaved method

fileName

this parameter is used to get the file name of the weaved method

filePath

this parameter is used to get the file path of the weaved method

callerParameters

this parameter is used to have the parameters of the method that will call the weaved member

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

field

this parameter is used to get some information about the field

newFieldValue

this parameter is used to get the value of the value that will be affected to the field

AfterUpdateField

This interceptor is executed after the code of the field is executed

The sample :

// Our business class
public class MyInt
{
    [Log]
    private int value;
    public void UpdateValue(int intValue)
    {
        value = intValue;
    }
    public int DivideBy(int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void AfterUpdateField(MyInt callerInstance, MyInt instance, int columnNumber, int lineNumber, string fileName, string filePath, object[] callerParameters, MethodBase callerMethod, FieldInfo field, int newFieldValue)
    {
        Called = true;
        Assert.AreEqual(callerInstance, instance);
        Assert.NotNull(callerInstance);
        Assert.AreEqual(13, columnNumber);
        Assert.AreEqual(33, lineNumber);
        Assert.AreEqual("Part5Sample4AfterInstructionSetFieldPossibilityTest.cs", fileName);
        Assert.AreEqual(fileName, Path.GetFileName(filePath));
        Assert.AreEqual(1, callerParameters.Length);
        Assert.AreEqual("UpdateValue", callerMethod.Name);
        Assert.AreEqual("value", field.Name);
        Assert.AreEqual(6, newFieldValue);
    }
}
// The following code is working
{
    var classToWeave_L = new MyInt();
    classToWeave_L.UpdateValue(6);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

callerInstance

this parameter is used to have the instance of the object that call the weaved member

instance

this parameter is used to have the this of the weaved member

columnNumber

this parameter is used to get the column of the first instruction in the weaved method

lineNumber

this parameter is used to get the line of the first instruction in the weaved method

fileName

this parameter is used to get the file name of the weaved method

filePath

this parameter is used to get the file path of the weaved method

callerParameters

this parameter is used to have the parameters of the method that will call the weaved member

The parameter name of the weaved method

this parameter is used to get the value of the parameter with the same name of the weaved method

field

this parameter is used to get some information about the field

newFieldValue

this parameter is used to get the value of the value that will be affected to the field


For an aspect put on a parameter

BeforeMethodForParameter

This interceptor is executed before the code of the method is executed

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int DivideBy([Log] int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void BeforeMethodForParameter(int parameterValue, MyInt instance, object[] parameters, ParameterInfo parameter, MethodInfo method, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.NotNull(instance);
        Assert.AreEqual("v", parameter.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(6, parameterValue);
        Assert.AreEqual("DivideBy", method.Name);
        Assert.AreEqual(36, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part8Sample1BeforeParameterPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"ParameterWeaving\Part8Sample1BeforeParameterPossibilityTest.cs"));
    }
}
// The following code is working
{
    var classToWeave_L = new MyInt(12);
    classToWeave_L.DivideBy(6);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

AfterMethodForParameter

This interceptor is executed after the code of the method is executed

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int DivideBy([Log] int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void AfterMethodForParameter(int parameterValue, MyInt instance, object[] parameters, ParameterInfo parameter, MethodInfo method, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.NotNull(instance);
        Assert.AreEqual("v", parameter.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(6, parameterValue);
        Assert.AreEqual("DivideBy", method.Name);
        Assert.AreEqual(36, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part8Sample2AfterParameterPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"ParameterWeaving\Part8Sample2AfterParameterPossibilityTest.cs"));
    }
}
// The following code is working
{
    var classToWeave_L = new MyInt(12);
    classToWeave_L.DivideBy(6);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :

OnExceptionMethodForParameter

This interceptor is executed when an exception is raised by the method

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int DivideBy([Log] int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void OnExceptionMethodForParameter(int parameterValue, MyInt instance, object[] parameters, ParameterInfo parameter, Exception exception, MethodInfo method, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.NotNull(instance);
        Assert.AreEqual("v", parameter.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(0, parameterValue);
        Assert.AreEqual("DivideByZeroException", exception.GetType().Name);
        Assert.AreEqual("DivideBy", method.Name);
        Assert.AreEqual(36, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part8Sample3OnExceptionParameterPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"ParameterWeaving\Part8Sample3OnExceptionParameterPossibilityTest.cs"));
    }
}
// The following code is working
{
    try
    {
        var classToWeave_L = new MyInt(12);
        classToWeave_L.DivideBy(0);
        Assert.Fail("Must Fail");
    }
    catch (Exception)
    {
        Assert.True(LogAttribute.Called);
    }
}

The following parameters are available for this interceptor :

OnFinallyMethodForParameter

This interceptor is executed after the code of the method is executed if an exception is raised or not

The sample :

// Our business class
public class MyInt
{
    private readonly int value;
    public MyInt(int value)
    {
        this.value = value;
    }
    public int DivideBy([Log] int v)
    {
        return value / v;
    }
}
// Our aspect
public class LogAttribute : Attribute
{
    public static bool Called;
    public bool NetAspectAttribute = true;
    public void OnFinallyMethodForParameter(int parameterValue, MyInt instance, object[] parameters, ParameterInfo parameter, MethodInfo method, int lineNumber, int columnNumber, string fileName, string filePath)
    {
        Called = true;
        Assert.NotNull(instance);
        Assert.AreEqual("v", parameter.Name);
        Assert.AreEqual(1, parameters.Length);
        Assert.AreEqual(6, parameterValue);
        Assert.AreEqual("DivideBy", method.Name);
        Assert.AreEqual(36, lineNumber);
        Assert.AreEqual(10, columnNumber);
        Assert.AreEqual("Part8Sample4OnFinallyParameterPossibilityTest.cs", fileName);
        Assert.True(filePath.EndsWith(@"ParameterWeaving\Part8Sample4OnFinallyParameterPossibilityTest.cs"));
    }
}
// The following code is working
{
    var classToWeave_L = new MyInt(12);
    classToWeave_L.DivideBy(6);
    Assert.True(LogAttribute.Called);
}

The following parameters are available for this interceptor :


An aspect is a class and that's why it is instantiated. There is 3 kinds of aspect life cycles

Transient

The aspect is instantiated each time you entered in the weaved member.

// The aspect
public class MyAspectAttribute : Attribute
{
    public static int i;
    public static string LifeCycle = "Transient";
    public bool NetAspectAttribute = true;
    public MyAspectAttribute()
    {
        i = 0;
    }
    public void BeforeMethod()
    {
        i++;
    }
}

// The class to weave
public class ClassToWeave
{
    [MyAspect]
    public void Weaved()
    {
    }
}

// This code is working
{
    var classToWeave = new ClassToWeave();
    classToWeave.Weaved();
    Assert.AreEqual(1, MyAspectAttribute.i);
    classToWeave.Weaved();
    Assert.AreEqual(1, MyAspectAttribute.i);
    var otherClassToWeave = new ClassToWeave();
    otherClassToWeave.Weaved();
    Assert.AreEqual(1, MyAspectAttribute.i);
}

Per instance

The aspect is instantiated one time by instance

// The aspect
public class ClassToWeave
{
    [MyAspect]
    public void Weaved()
    {
    }
}

// The class to weave
public class ClassToWeave
{
    [MyAspect]
    public void Weaved()
    {
    }
}

// This code is working
{
    var classToWeave = new ClassToWeave();
    classToWeave.Weaved();
    Assert.AreEqual(1, MyAspectAttribute.i);
    classToWeave.Weaved();
    Assert.AreEqual(2, MyAspectAttribute.i);
    var otherClassToWeave = new ClassToWeave();
    otherClassToWeave.Weaved();
    Assert.AreEqual(1, MyAspectAttribute.i);
}

Per type

The aspect is instantiated only one time in a static way

// The aspect
public class ClassToWeave
{
    [MyAspect]
    public void Weaved()
    {
    }
}

// The class to weave
public class ClassToWeave
{
    [MyAspect]
    public void Weaved()
    {
    }
}

// This code is working
{
    var classToWeave = new ClassToWeave();
    classToWeave.Weaved();
    Assert.AreEqual(1, MyAspectAttribute.i);
    classToWeave.Weaved();
    Assert.AreEqual(2, MyAspectAttribute.i);
    var otherClassToWeave = new ClassToWeave();
    otherClassToWeave.Weaved();
    Assert.AreEqual(3, MyAspectAttribute.i);
}

Assemblies to weave

By default, in NetAspect, only the assembly in which NetAspect is installed is weaved.

But you can tell to NetAspect to weave other assemblies thanks to the field AssembliesToWeave

// The aspect
public class MyAspectAttribute : Attribute
{
    public static DepClassWhichCallField Caller;
    public static IEnumerable AssembliesToWeave = new List {
        typeof(DepClassWhichCallField).Assembly
    };
    public bool NetAspectAttribute = true;
    public void BeforeUpdateField(DepClassWhichCallField callerInstance)
    {
        Caller = callerInstance;
    }
    public static bool SelectField(FieldInfo field)
    {
        return field.Name == "Field";
    }
}

// The class to weave
public class ClassToWeave
{
// Defined in another assembly
}

// This code is working
{
    Assert.IsNull(MyAspectAttribute.Caller);
    var classToWeave_L = new DepClassWhichCallField();
    classToWeave_L.CallField("value");
    Assert.AreEqual(classToWeave_L, MyAspectAttribute.Caller);
}