AOP vs MVC FilterAttributes vs Interceptors [closed]
Asked Answered
T

2

8
  1. ASP.NET MVC proposes that use or extend built-in Authorization, Action, Result, Exception filters.
  2. 3th party .Net IoC containers (Unity, Ninject, Autofac) propose Interceptors
  3. 3th party AOP tools (Postsharp) propose their attributes.

Now, I'm messed up. May be I mix all of them. I would like to build robust code and stable methodology, what should I use?

Telmatelo answered 21/2, 2013 at 17:42 Comment(0)
Q
6

It all starts with good application design. When the design of your application is correct, there will be a lot less reason for you to interact with those AOP like features that your UI framework exposes (this holds for WCF as well).

When you hide all business logic behind a generic interface for instance, and pass command messages to it (as shown in this article), your Controllers will become thin wrappers that often do not much more than execute such business command. In that case you will be able to implement authorization and exception filtering by wrapping those business operations, leaving the UI code clean and free from attributes. Wrapping those cross-cutting concerns around business operations can be done with both interception or plain old decorators. This gives you much more flexibility and keeps your design SOLID (which has a lot of less obvious long term benefits).

Although code weaving tools as PostSharp have its use, you should be careful with them. They inject code into your assembly using a post-compile process. This makes it very painful to unit test those classes without hitting those aspects. You can't easily test those classes in isolation (which is a precondition for unit testing). Making your aspects dependent on some static variable, complicates both aspects and unit tests. Static variables make it hard to run unit tests in parallel and the use of global constants will require tests to tear down the changed global setting correctly to prevent other tests from being influenced.

Although code weaving tools result in performance that is often greater than interception, there is no performance gain compared to the use of decorators.

Quelpart answered 22/2, 2013 at 3:9 Comment(6)
How does compile time injection interfere with unit testing? You won't even unit test without compiling you know?Underact
@jfar: Your production code is weaved together with the aspects during compilation. Because of this you can't test your production code anymore in isolation. When a unit test calls some production code, the aspects will always be applied. In fact, you can't unit test, since by definition a unit test runs in isolation. What you'll have is an integration test. Like to undo your downvote now?Quelpart
Your code is ALWAYS weaved together by the compiler, production and unit test could possibly get different versions by the compiler so could any code with decorators or DI or anything. The flaw in this answer is that AOP or PostSharp does not effect unit testing in any unique or notable way.Underact
With PostSharp you apply a series of attributes, 1 for each behaviour you wish to apply. With DI you apply a series of Decorators, 1 for each behaviour you wish to apply. The difference here is simple. Unit testing PostSharp attributes is either all or nothing. With the decorator pattern you can individually test the underlying class and each decorator in isolation.Electroacoustics
@jfar: I probably can't convince you, but since you seem passionate about this subject, I advice you to read the book AOP in .NET by Matthew D. Groves and especially chapter 6 about unit testing. After reading, you will understand what I'm talking about.Quelpart
I think this should be accepted as answer. Using code weaving certainly is usable in some cases, like implementing INPC. For business logic like, transactions, validation, saving changes, etc. decorators are the way to go. Unit testing using code weaving is just not do able.Oakum
L
4

You cited three technologies that all intend to do the same: add functionalities to an existing codebase without modifying it.

ASP.NET MVC and DI both put limitations on where you can have aspects (named filters or interceptors) because the technology is only able to add the behaviors at some locations, given they cannot edit your code. Only compiler-based technologies such as PostSharp have the ability to add aspects everywhere. However, all three are implementations of AOP concepts.

Aspects have proven benefits over conventional object-oriented programming in many use cases. It is not true that every single problem can be solved by conventional OOP with better design at the same cost. It is correct, however, that AOP is not mainstream, and that there are costs and risks associated to using a non-mainstream technology (AOP was born in the 90s and OOP in the 60s). As with any innovation, different actors have different sensibility between risks and benefits, so may become early or late adopters.

AOP is not an obstacle to unit testing, but there is little shared experience on the topic. Generally, aspects must be tested as separate units of code. There are essential and non-essential aspects. Typically, business code must be tested together with essential aspects, but non-essential aspects must be disabled. You can disable aspects either statically at build time (just exclude some aspect from the build configuration), or at run time (make the aspect dependent on some static variable that you set to false during testing).

Leadin answered 26/2, 2013 at 9:26 Comment(3)
Can you reference any article that explains in more detail what essential and non-essential aspects are?Quelpart
@Quelpart I don't have a single article in mind. The concept of non-essential aspect is actually named "harmless advice" in the academic literature. It means that the aspect is purely orthogonal to its target (the base code) and can be removed without affecting its result. For instance, logging and performance monitoring are harmless, but transaction handling or INotifyPropertyChanged are not.Leadin
Check out slide 12 in this presentationPredominance

© 2022 - 2024 — McMap. All rights reserved.