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}