Alexander, which branch would you like the TypeLoadException PR against? We
are short on time at this moment so putting the PR together will take some
time. However, I have provided the details below, including the line of
code to reproduce.

The fix is for situations where we have something like
* class AbstractPersisentCollection : ILazyCollectionInitializer
* ILazyCollectionInitiatializer has a WasInitialized property
* AbstractPersistentCollection has a final WasInitialized property
* We create a proxy via ProxyFactory and ask it to provide the
ILazyCollectionInitialized interface.

In such a case the explicit interface implementation method created for the
proxy conflicts with the method on AbstractPersistentCollection and causes
the TypeLoadException.

The change, that follows, copies the .NET method attributes and naming for
explicitly implemented interface methods.

It may be interesting to note that using NewSlot or changing the name alone
both prevented the TypeLoadException as well, but I figured it was cleaner
to go with what .NET would do itself when generating the explicit interface
method definitions.

I realize there's no test case associated with it yet. To reproduce the
error you can do:

new ProxyFactory().CreateProxy(typeof(PersistentGenericBag<SomeEntity>),
new SomeInterceptor(), typeof(ILazyInitializedCollection))

The fix is included below:

 src/NHibernate/Proxy/ProxyBuilderHelper.cs | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/NHibernate/Proxy/ProxyBuilderHelper.cs
b/src/NHibernate/Proxy/ProxyBuilderHelper.cs
index 94af19db9..cd04ab4db 100644
--- a/src/NHibernate/Proxy/ProxyBuilderHelper.cs
+++ b/src/NHibernate/Proxy/ProxyBuilderHelper.cs
@@ -137,13 +137,29 @@ internal static MethodBuilder
GetObjectDataMethodBuilder(TypeBuilder typeBuilder
  internal static MethodBuilder GenerateMethodSignature(string name,
MethodInfo method, TypeBuilder typeBuilder)
  {
  //TODO: Should we use attributes of base method?
- var methodAttributes = MethodAttributes.Public |
MethodAttributes.HideBySig | MethodAttributes.Virtual;
+ MethodAttributes methodAttributes;
+         if (method.DeclaringType.IsInterface)
+ {
+ // These are the attributes used for an explicit interface method
implementation in .NET.
+ methodAttributes =
+ MethodAttributes.Private |
+ MethodAttributes.Final |
+ MethodAttributes.Virtual |
+ MethodAttributes.HideBySig |
+ MethodAttributes.NewSlot |
+ MethodAttributes.SpecialName;
+ // .NET uses an expanded name for explicit interface implementation
methods.
+ name = typeBuilder.FullName + "." + method.DeclaringType.FullName + "." +
name;
+ }
+ else
+ {
+ methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig |
MethodAttributes.Virtual;
+ }

  if (method.IsSpecialName)
  methodAttributes |= MethodAttributes.SpecialName;

  var parameters = method.GetParameters();
-
  var methodBuilder = typeBuilder.DefineMethod(
  name,
  methodAttributes,

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"nhibernate-development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to nhibernate-development+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to