This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
|The latest Enterprise Library information can be found at the Enterprise Library site.|
|On this page:|
|What Is Interception? | Interception to Handle Cross Cutting Concerns - Exception Handling as a Cross Cutting Concern, Other Examples of Cross Cutting Concerns, Benefits of Applying Interception to Cross Cutting Concerns|
Since the invention of computers, programming languages have been evolving, and each improvement has increased the level of abstraction.
While modern programming languages such as C# 4.0 are much more powerful than their predecessors, you will find that programming is still as much about addressing technical programming issues as it is about addressing business requirements. Orthogonal issues such as authorization, exception handling, caching, and diagnostic logging often require a lot of code, which is frequently mixed with code that addresses actual business requirements.
In this chapter, we'll discuss an advanced programming technique called interception. When used properly, interception can help you to reduce the amount of code you'll have to write to solve technical programming issues and will allow you to focus on addressing actual business requirements.
Unity Interception has been available for the Microsoft® .NET Framework as an extension for Unity container for several years now. Now it is available for Microsoft Silverlight as well. Here, we'll discuss what interception is, why you might want to use it, and how you can apply Unity Interception and policy injection to Silverlight applications.
What Is Interception?
Interception is an advanced programming technique that allows you to intercept calls to an object so that you can add additional logic before or after the call. This interception process should be virtually transparent, so both the calling object and the target object can be oblivious to the interception process.
The following diagram shows how instance interception typically works:
The calling object will typically ask the Unity dependency container for a target object. However, it will not receive a real TargetObject, but rather an intercepting proxy that is impersonating the real TargetObject, for example, by implementing the same interface. This way the calling object does not know if it calls the real target object or the proxy. The TargetObject also doesn't know that the calls have been intercepted. The fact that both classes don't know this about the interception process allows you to add custom logic before or after a member call, without having to change either the calling object or the target object.
Interception is quite similar to using the decorator pattern. With a decorator you'll typically have to program a custom decorator class for each target object. However, Unity will dynamically generate the interceptor for you, so all you have to do is implement the custom behaviors.
Interception to Handle Cross Cutting Concerns
Interception is very well suited to implementing cross cutting concerns. A cross cutting concern is an aspect of programming that typically affects many parts of an application. One example of a cross cutting concern is handling exceptions at certain layers.
Exception Handling as a Cross Cutting Concern
If you implement exception handling directly in code, your classes will likely be mingled with logging statements. For example, in your user interface you will probably want to catch all unhandled exceptions, show a friendly error message to the user, and log the exception information. At service boundaries, where your application makes requests to external web services, you might want to translate any service exceptions into more friendly exception types that your application can more easily handle.
For relatively small applications it is usually not a problem to spread exception handling logic around the application. However, for larger enterprise applications this can cause serious problems.
While cross cutting concerns, such as exception handling, are very important to your application, they usually don't add any direct business value. If you have implemented exceptions only for exceptional cases, your application will likely function fine without exception logic—as long as nothing goes wrong, of course. But adding these exception handling statements to your business logic means that your code will be cluttered with try-catch statements, which makes it harder to read and harder to maintain.
Implementing cross cutting concerns such as exception handling directly in your code can also cause other issues for large, enterprise-scale applications. For example, not every developer will use the same level of diligence when applying exception handling. It's then likely that inconsistencies will arise in the exception handling code, with nasty stability problems resulting. If these inconsistencies were to occur not just in exception handling but also in other cross cutting concerns, such as authentication, the result could be major security problems.
The fact that these cross cutting concerns are spread throughout your application can make them very difficult to change. For example, if you have applied exception handling very diligently and most of your classes are handling exceptions, then it becomes a lot harder to change to a different exception handling strategy, because that would mean changing all of the classes that perform exception handling. Also, if you were to decide that you're not handling exceptions at the right locations in your application, then you would have to manually change all these classes to alter the locations where you are handling exceptions.
If you would have implemented exception handling using interception, then you would have been able to isolate your exception handling logic in specific interception behaviors and dynamically apply them where you need them.
Other Examples of Cross Cutting Concerns
Exception handling is only a single example of a cross cutting concern. Typical enterprise applications have dozens, such as:
- Logging and tracing information as it flows through your application.
- Executing calls to back-end web services under different security credentials.
- Authenticating calls to business components, so only authorized users can access them.
- Implementing validation logic on methods of your business components.
- Caching data retrieved from a web service or database.
Again, it's certainly possible to address all these cross cutting concerns directly in your code, but this will pollute your business logic with code that's not directly solving the business problem at hand.
Benefits of Applying Interception to Cross Cutting Concerns
There are several major benefits to using interception to solve certain cross cutting concerns. For example, if you want to authenticate all calls to your business components, you would typically need a lot less code to implement such a cross cutting concern using interception. Instead of having to add authentication code to each of your business components, you can write a single interception behavior that handles authentication and apply it to all your business components.
Another advantage is that your interception behaviors can often be easily reused in other places. In the case of the authentication behavior, if you later decide that calls to other components should also be authenticated, you can simply apply that interception behavior to those components as well.
The fact that you can easily apply a behavior to several classes also means that you'll get more consistency in your cross cutting concern. It's much easier to ensure that all calls to your business components are authenticated if you don't have to add authenticating code into each method. When using the interception behavior, the authentication is applied automatically.
Lastly, implementing authentication using interception also makes your application more maintainable. That's because the business logic is easier to read as it is not polluted with authentication statements; plus, you've also centralized authentication in a single location. This makes it much easier to change the way authentication is handled.
Last built: July 8, 2011