forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLazyInitializer.cs
86 lines (79 loc) · 2.99 KB
/
LazyInitializer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Reflection;
using Castle.DynamicProxy;
using NHibernate.Proxy;
using NHibernate.Proxy.Poco;
using NHibernate.Type;
using NHibernate.Engine;
namespace NHibernate.ByteCode.Castle
{
/// <summary>
/// A <see cref="ILazyInitializer"/> for use with the Castle Dynamic Class Generator.
/// </summary>
[Serializable]
[CLSCompliant(false)]
public class LazyInitializer : BasicLazyInitializer, global::Castle.DynamicProxy.IInterceptor
{
private static readonly MethodInfo Exception_InternalPreserveStackTrace =
typeof(Exception).GetMethod("InternalPreserveStackTrace", BindingFlags.Instance | BindingFlags.NonPublic);
#region Instance
public bool _constructed;
/// <summary>
/// Initializes a new <see cref="LazyInitializer"/> object.
/// </summary>
/// <param name="entityName"></param>
/// <param name="persistentClass">The Class to Proxy.</param>
/// <param name="id">The Id of the Object we are Proxying.</param>
/// <param name="getIdentifierMethod"></param>
/// <param name="setIdentifierMethod"></param>
/// <param name="componentIdType"></param>
/// <param name="session">The ISession this Proxy is in.</param>
public LazyInitializer(string entityName, System.Type persistentClass, object id,
MethodInfo getIdentifierMethod, MethodInfo setIdentifierMethod,
IAbstractComponentType componentIdType, ISessionImplementor session)
:base(entityName, persistentClass, id, getIdentifierMethod, setIdentifierMethod, componentIdType, session)
{
}
/// <summary>
/// Invoke the actual Property/Method using the Proxy or instantiate the actual
/// object and use it when the Proxy can't handle the method.
/// </summary>
/// <param name="invocation">The <see cref="IInvocation"/> from the generated Castle.DynamicProxy.</param>
public virtual void Intercept(IInvocation invocation)
{
try
{
if (_constructed)
{
// let the generic LazyInitializer figure out if this can be handled
// with the proxy or if the real class needs to be initialized
invocation.ReturnValue = base.Invoke(invocation.Method, invocation.Arguments, invocation.Proxy);
// the base LazyInitializer could not handle it so we need to Invoke
// the method/property against the real class
if (invocation.ReturnValue == InvokeImplementation)
{
invocation.ReturnValue = invocation.Method.Invoke(GetImplementation(), invocation.Arguments);
return;
}
else
{
return;
}
}
else
{
// TODO: Find out equivalent to CGLIB's 'method.invokeSuper'.
return;
}
}
catch (TargetInvocationException tie)
{
// Propagate the inner exception so that the proxy throws the same exception as
// the real object would
Exception_InternalPreserveStackTrace.Invoke(tie.InnerException, new Object[] { });
throw tie.InnerException;
}
}
#endregion
}
}