Lazy is a valuable addition to the .Net 4 framework, offering a standardized method for lazy initialization. It’s a surprisingly straightforward concept that makes you wonder why you haven’t thought of it before.
In essence, Lazy instances act as proxies for instances of type T, delaying their creation until they’re first accessed via the Lazy.Value property.
For instance, instead of directly instantiating a potentially resource-intensive “CostlyObject,” we can use a Lazy instance and access its members through the .Value property:
| |
The complete code can be found at here.
While this approach is effective, it lacks transparency. The client code is directly exposed to the proxy object and needs to be adapted accordingly (e.g., using myLazy.Value.Whatever instead of myObject.Whatever). Although this might seem acceptable, “laziness” could be considered an implementation detail that should be hidden from the client.
Furthermore, this approach is incompatible with existing code. Since there’s no inheritance relationship between Lazy and T, a Lazy object cannot be seamlessly passed to code expecting a T object.
This situation immediately brings to mind the concepts of Dynamic Proxies and Interception. In this case, instead of intercepting calls for logging purposes, we aim to intercept them to trigger the creation of the real object.
This is where Castle DynamicProxy comes into play. Initially, using a Class Proxy seemed like a viable option. However, this approach is flawed. Since a class proxy inherits from the target class (T) and constructors in child classes need to call a base constructor, the costly object would be created prematurely, defeating the purpose of lazy initialization.
Given the limitations of class inheritance in this context, we need a different strategy: Interface implementation. As detailed in excellent tutorial, there are three primary options for interface proxies. Two of these options suffer from the same drawback as class proxies, as the generated proxy inherits from the proxied class. However, the third option, “Proxy without target,” offers a solution:
“Proxy without target. This one is tricky. You don’t supply target implementation for the interface. Dynamic Proxy generates it for you at runtime, using interceptors to provide behavior for its methods.”
This approach involves generating a proxy class that implements the interface and uses an interceptor to lazily create and reference the real class instance.
This implementation consists of two classes: one for generating the Proxy and another for the Interceptor.
| |
The constructor delegate passed to the Interceptor encapsulates the constructor invocation of the proxied class, mirroring the approach used by Lazy.
A comprehensive sample demonstrating this technique with a lazily created Repository is available at here (zip file including the necessary Castle Assembly: here).
It’s interesting to note that the following line in the interceptor seamlessly handles both method calls and property access:
| |
This consistency stems from the fact that the C# compiler translates properties into corresponding “get_X” and “set_X” methods, which are then invoked through invocation.Method when a property is accessed via the proxy.
For those who follow this blog regularly (although unlikely :-)), you might have noticed the connection between this entry and previous one.