main
1using System;
2using Castle.DynamicProxy;
3using gorilla.infrastructure.container;
4using gorilla.utility;
5
6namespace solidware.financials.infrastructure
7{
8 static public class Lazy
9 {
10 static public T load<T>() where T : class
11 {
12 return load(Resolve.the<T>);
13 }
14
15 static public T load<T>(Func<T> get_the_implementation) where T : class
16 {
17 return create_proxy_for<T>(create_interceptor_for(get_the_implementation));
18 }
19
20 static IInterceptor create_interceptor_for<T>(Func<T> get_the_implementation) where T : class
21 {
22 return new LazyLoadedInterceptor<T>(get_the_implementation.memorize());
23 }
24
25 static T create_proxy_for<T>(IInterceptor interceptor) where T : class
26 {
27 return new ProxyGenerator().CreateInterfaceProxyWithoutTarget<T>(interceptor);
28 }
29
30 class LazyLoadedInterceptor<T> : IInterceptor
31 {
32 readonly Func<T> get_the_implementation;
33
34 public LazyLoadedInterceptor(Func<T> get_the_implementation)
35 {
36 this.get_the_implementation = get_the_implementation;
37 }
38
39 public void Intercept(IInvocation invocation)
40 {
41 var method = invocation.GetConcreteMethodInvocationTarget();
42 if( null== method)
43 {
44 invocation.ReturnValue = invocation.Method.Invoke(get_the_implementation(), invocation.Arguments);
45 }
46 else
47 {
48 invocation.ReturnValue = method.Invoke(get_the_implementation(), invocation.Arguments);
49 }
50 }
51 }
52 }
53}