C # and AOP - AOPAlliance (aspect-oriented programming) how it works

I had a very interesting experience with AOP in C #. I have a function with a return type of List that is intercepted and that everything is fine and good. However, the interceptor function is a validator style function and can prevent the real function by calling it and returning a boolean false.

So, the code looks something like this:

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

The method hook looks like this

 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 the check has failed, the value of the updates is actually a logical, not a list, I thought that there would be some kind of runtime error, but it wasn’t, so:

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

But:

 updates is bool == false 

That way, the save will still accept its mutated list of updates and will later complain when you try to use it.

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

Edit: It also compiles and it works, I’ve stepped through it several times already.

+6
source share
1 answer

I believe this is possible because Spring.Net emits proxy classes at runtime that skip compilation type checks.

It essentially implements a decorator pattern that wraps the original class and dynamically generates a new method implementation. In a dynamically generated proxy method, the return type can be changed when it writes IL, and .NET allows this because it does not check the type at run time. Of course, during compilation this is also quite true. This leads to a rather strange scenario above, in which your static type is actually different from the type of runtime.

The following is true because it checks the actual type of runtime, which can resolve the boolean in cases.

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

But the following fails, because it compares the static type of the variable with a Boolean, which is not.

 updates is bool == false 

I would recommend you not to change the type inside Invoke.

+6
source

Source: https://habr.com/ru/post/895940/


All Articles