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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With