It is customary to conceive any large application to be composed of several logical layers. It is also a practice to reduce the coupling between the layers. Typically, one would create an interface for each class of each layer and they would be coupled to the downstream layer classes only though interfaces.
You would also typically want to unit test each class in each layer. By definition, each of unit test would test a method of only one class and not the downstream classes it depends on. To achieve this , one would need to mock out the instances of the classes which the class being unit-tested depends on. To bring all of this to play effectively, you need to implement the Dependency Injection pattern in your application. Dependency injection is provided by Unity application block.
The application we talked about earlier has in addition to a lot of business logic, several pieces of cross cutting logic – logic applicable to all classes – like logging, tracing, authorization, validation etc. The code for these concerns are usually generic. It would be an awful amount of work to implement these generic pieces of code in every class (or a group of classes) of your application. What you really need is some way to stitch these concerns into the application without disturbing the application code too much. This style of programming is called Aspect Oriented programming (sort of). This capability is provided by the Policy Injection Application block.
Now, to me, both aspects discussed above are very important to any application. In other words, any application would need both dependency injection along with some type of aspect orientation (or policy injection or interception). The question really is – how do you really bring them together?
I am assuming that you are familiar with these blocks I just mentioned. To have rubber meet the road, we really need to marry IContainer.Resolve<T> and PolicyInjection.Create<T>(). This was not possible as of EL 4.0 and left me hoping. It is possible now – with EL 4.1 (along Unity 1.2). The interception capability comes as a extension which can be associated with the Unity container. Therefore, you can have policies associated with the container which govern which call handlers are added. The real beauty is this – the application classes really work with the IContainer interface. In an actual environment, you need to associate the container which has the correct dependencies and interception policies. The unit testing environment would basically replace the container with one where the Interception extension is not applied, and therefore, the unit tests would not really execute any cross-cutting logic (of course, you can choose otherwise). Neat!
I have just started to dabble with this ability, and a lot of questions still need to be answered. One that comes immediately from the top of my mind is performance. When a class is set to be intercepted, what would be the performance overhead, and what would be the overhead based on the type of interceptor (TransparentProxyInterceptor, VirtualMethodInterceptor or InterfaceInterceptor)? Obviously, there are no definitive answers and it all depends on the policies and handlers you add to your application. I have a reason to believe that the cost of interception is not usually so high, that is deemed only for academic purposes. One would need to perform relevant tests to ratify the same in her application on the representative environment. The second question, but seemingly more subtle, is instancing. The new interception features either work on the RealProxy based interception, or dynamic code generation. Obviously, it would be more efficient to reuse these instances at runtime instead of generating them for every call. Now, if you have singleton instancing, the real question is about thread safety. How does a dynamically generated instance serve multiple request threads at a time – as it happens in web applications in production?
Having opened these questions, I would write up a follow-up post which hopefully addresses these. In the meantime, I will dabble with more scenarios using these new capabilities, and keep you posted.