Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# and AOP - AOPAlliance (Aspect-oriented programming) how does this work

I just had a very interesting experience with AOP in C#. I have a function with a return type List which is being intercepted and that's all well and good. However the interceptor function is a validator style function and can prevent the real function by being called and returning the boolean false.

So the code looks a little bit like this:

List<Update> updates = Manager.ValidateAndCreate();

// protected void Save(List<Update> updates) { ....
Save(updates);

The Method Interceptor looks like the following

public class ExceptionAdvice : AopAlliance.Intercept.IMethodInterceptor {

    public object Invoke(AopAlliance.Intercept.IMethodInvocation invocation) {

        if (isValid(invocation)) {
            return invocation.Proceed();
        } else {
            return false;
        }
    }

    private bool isValid( ...
 }

Now after validation fails the value of updates is actually a boolean not a List, I thought there would be some kind of runtime error here but there was not, so:

updates.GetType().Name == "Boolean"

But:

updates is bool == false

So save will still accept its mutated list of updates and will complain later on when you try to use it.

So how is this possible in a type safe language like C#? btw it's spring-aop.

Edit: Also this does compile and it does work i've stepped through it a few times now.

like image 931
Daniel Little Avatar asked Aug 26 '11 06:08

Daniel Little


1 Answers

I believe this is possible because Spring.Net is emitting proxy classes at runtime which skip compile time type checks.

It essentially implements a decorator pattern wrapping the original class and dynamically generating a new method implementation. In the dynamically generated proxy method the return type can be changed when it writes the IL, and .NET allows it because it doesn't check the type at runtime. At compile time of course it's also still perfectly valid. This leads to the rather weird scenario above whereby your static type is actually different to the runtime type.

The following is true because it's checking the actual runtime type, which can in cases resolve to Boolean.

updates.GetType().Name == "Boolean"

But the following fails because it's comparing the static type of the variable to Boolean, which it's not.

updates is bool == false

I would recommend that you don't change the type within Invoke.

like image 84
TheCodeKing Avatar answered Sep 19 '22 16:09

TheCodeKing