Skip to content

Commit f81fcc1

Browse files
Implement a static IFieldInterceptorAccessor
1 parent fb544b0 commit f81fcc1

File tree

7 files changed

+410
-139
lines changed

7 files changed

+410
-139
lines changed

src/AsyncGenerator.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@
196196
name: LinqReadonlyTestsContext
197197
- conversion: Ignore
198198
name: MultiThreadRunner
199+
- conversion: Ignore
200+
name: PeVerifier
199201
- conversion: Ignore
200202
hasAttributeName: IgnoreAttribute
201203
- conversion: NewType

src/NHibernate.Test/Async/DynamicProxyTests/PeVerifyFixture.cs

Lines changed: 0 additions & 133 deletions
This file was deleted.

src/NHibernate.Test/DynamicProxyTests/PeVerifyFixture.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
using System;
2-
using System.IO;
32
using System.Reflection;
43
using System.Reflection.Emit;
54
using NUnit.Framework;
65
using NHibernate.Proxy.DynamicProxy;
6+
using NHibernate.Test.ProxyTest;
77

88
namespace NHibernate.Test.DynamicProxyTests
99
{

src/NHibernate.Test/DynamicProxyTests/PeVerifier.cs renamed to src/NHibernate.Test/ProxyTest/PeVerifier.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
using System.IO;
44
using NUnit.Framework;
55

6-
namespace NHibernate.Test.DynamicProxyTests
6+
namespace NHibernate.Test.ProxyTest
77
{
88
// utility class to run PEVerify.exe against a saved-to-disk assembly, similar to:
99
// http://stackoverflow.com/questions/7290893/is-there-an-api-for-verifying-the-msil-of-a-dynamic-assembly-at-runtime
10-
public partial class PeVerifier
10+
public class PeVerifier
1111
{
1212
private string _assemlyLocation;
1313
private string _peVerifyPath;

src/NHibernate.Test/StaticProxyTest/StaticProxyFactoryFixture.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
using System.Collections.Generic;
22
using NHibernate.Proxy;
33
using NUnit.Framework;
4+
#if NETFX
5+
using System;
6+
using System.Reflection;
7+
using System.Reflection.Emit;
8+
using NHibernate.Proxy.DynamicProxy;
9+
using NHibernate.Test.ProxyTest;
10+
#endif
411

512
namespace NHibernate.Test.StaticProxyTest
613
{
@@ -24,5 +31,90 @@ public void CanCreateProxyForClassWithInternalInterface()
2431
var proxy = factory.GetProxy(1, null);
2532
Assert.That(proxy, Is.Not.Null);
2633
}
34+
35+
#if NETFX
36+
[Test]
37+
public void VerifyFieldInterceptorProxy()
38+
{
39+
var proxyBuilderType = typeof(StaticProxyFactory).Assembly.GetType("NHibernate.Proxy.FieldInterceptorProxyBuilder", true);
40+
var proxyBuilder = proxyBuilderType.GetMethod("CreateProxyType");
41+
Assert.That(proxyBuilder, Is.Not.Null, "Failed to find method CreateProxyType");
42+
var proxyBuilderAssemblyBuilder = proxyBuilderType.GetField("ProxyAssemblyBuilder", BindingFlags.NonPublic | BindingFlags.Static);
43+
Assert.That(proxyBuilderAssemblyBuilder, Is.Not.Null, "Failed to find assembly builder field");
44+
45+
const string assemblyName = "VerifyFieldInterceptorProxy";
46+
var assemblyBuilder = new SavingProxyAssemblyBuilder(assemblyName);
47+
48+
var backupAssemblyBuilder = proxyBuilderAssemblyBuilder.GetValue(null);
49+
proxyBuilderAssemblyBuilder.SetValue(null, assemblyBuilder);
50+
try
51+
{
52+
proxyBuilder.Invoke(null, new object[] { typeof(TestClass) });
53+
}
54+
finally
55+
{
56+
proxyBuilderAssemblyBuilder.SetValue(null, backupAssemblyBuilder);
57+
}
58+
59+
new PeVerifier($"{assemblyName}.dll").AssertIsValid();
60+
}
61+
62+
public class SavingProxyAssemblyBuilder : IProxyAssemblyBuilder
63+
{
64+
private readonly string _assemblyName;
65+
66+
public SavingProxyAssemblyBuilder(string assemblyName)
67+
{
68+
_assemblyName = assemblyName;
69+
}
70+
71+
public AssemblyBuilder DefineDynamicAssembly(AppDomain appDomain, AssemblyName name)
72+
{
73+
return appDomain.DefineDynamicAssembly(
74+
new AssemblyName(_assemblyName),
75+
AssemblyBuilderAccess.RunAndSave,
76+
TestContext.CurrentContext.TestDirectory);
77+
}
78+
79+
public ModuleBuilder DefineDynamicModule(AssemblyBuilder assemblyBuilder, string moduleName)
80+
{
81+
return assemblyBuilder.DefineDynamicModule(moduleName, $"{_assemblyName}.mod", true);
82+
}
83+
84+
public void Save(AssemblyBuilder assemblyBuilder)
85+
{
86+
assemblyBuilder.Save($"{_assemblyName}.dll");
87+
}
88+
}
89+
#endif
90+
91+
public interface IPublicTest
92+
{
93+
int Id { get; }
94+
}
95+
96+
public class PublicInterfaceTestClass : IPublicTest
97+
{
98+
public virtual int Id { get; set; }
99+
}
100+
101+
[Test]
102+
public void CanGenerateValidFieldInterceptorProxyWithAdditionalInterface()
103+
{
104+
var factory = new StaticProxyFactory();
105+
factory.PostInstantiate(
106+
typeof(PublicInterfaceTestClass).FullName,
107+
typeof(PublicInterfaceTestClass),
108+
// By way of the "proxy" attribute on the "class" mapping, an interface to use for the
109+
// lazy entity load proxy instead of the persistentClass can be specified. This is "translated" into
110+
// having an additional interface in the interface list, instead of just having INHibernateProxy.
111+
// (Quite a loosy semantic...)
112+
// The field interceptor proxy ignores this setting, as it does not delegate its implementation
113+
// to an instance of the persistentClass, and so cannot implement interface methods.
114+
new HashSet<System.Type> {typeof(INHibernateProxy), typeof(IPublicTest)},
115+
null, null, null);
116+
var fieldProxy = factory.GetFieldInterceptionProxy(null);
117+
Assert.That(fieldProxy, Is.InstanceOf<PublicInterfaceTestClass>());
118+
}
27119
}
28120
}

0 commit comments

Comments
 (0)