Skip to content

Commit 8e60922

Browse files
committed
Mark proxy assembly with IgnoresAccessChecksToAttribute to allow implementing non public interfaces
1 parent 97dc207 commit 8e60922

File tree

4 files changed

+47
-1
lines changed

4 files changed

+47
-1
lines changed

src/NHibernate/Proxy/FieldInterceptorProxyBuilder.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,16 @@ public static TypeInfo CreateProxyType(System.Type baseType)
6565
nameof(baseType));
6666
}
6767

68+
#if NETFX || NETCOREAPP2_0
69+
var assemblyNamesToIgnoreAccessCheck =
70+
interfaces.Where(i => !i.IsVisible)
71+
.Select(i => i.Assembly.GetName().Name)
72+
.Distinct();
73+
foreach (var a in assemblyNamesToIgnoreAccessCheck)
74+
ProxyBuilderHelper.GenerateInstanceOfIgnoresAccessChecksToAttribute(assemblyBuilder, a);
75+
#else
6876
interfaces.RemoveWhere(i => !i.IsVisible);
77+
#endif
6978

7079
var typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes, parentType, interfaces.ToArray());
7180

src/NHibernate/Proxy/NHibernateProxyBuilder.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,17 @@ public TypeInfo CreateProxyType(System.Type baseType, IReadOnlyCollection<System
7575
interfaces.Add(baseType);
7676
}
7777

78+
#if NETFX || NETCOREAPP2_0
79+
var assemblyNamesToIgnoreAccessCheck =
80+
interfaces.Where(i => !i.IsVisible)
81+
.Select(i => i.Assembly.GetName().Name)
82+
.Distinct();
83+
foreach (var a in assemblyNamesToIgnoreAccessCheck)
84+
ProxyBuilderHelper.GenerateInstanceOfIgnoresAccessChecksToAttribute(assemblyBuilder, a);
85+
#else
7886
interfaces.RemoveWhere(i => !i.IsVisible);
79-
87+
#endif
88+
8089
var typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes, parentType, interfaces.ToArray());
8190

8291
var lazyInitializerField = typeBuilder.DefineField("__lazyInitializer", LazyInitializerType, FieldAttributes.Private);

src/NHibernate/Proxy/ProxyBuilderHelper.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.Linq;
1212
using System.Reflection;
1313
using System.Reflection.Emit;
14+
using System.Runtime.CompilerServices;
1415
using System.Runtime.Serialization;
1516
using System.Security;
1617
using NHibernate.Util;
@@ -21,6 +22,7 @@ internal static class ProxyBuilderHelper
2122
{
2223
private static readonly ConstructorInfo ObjectConstructor = typeof(object).GetConstructor(System.Type.EmptyTypes);
2324
private static readonly ConstructorInfo SecurityCriticalAttributeConstructor = typeof(SecurityCriticalAttribute).GetConstructor(System.Type.EmptyTypes);
25+
private static readonly ConstructorInfo IgnoresAccessChecksToAttributeConstructor = typeof(IgnoresAccessChecksToAttribute).GetConstructor(new[] {typeof(string)});
2426

2527
internal static readonly MethodInfo SerializableGetObjectDataMethod = typeof(ISerializable).GetMethod(nameof(ISerializable.GetObjectData));
2628
internal static readonly MethodInfo SerializationInfoSetTypeMethod = ReflectHelper.GetMethod<SerializationInfo>(si => si.SetType(null));
@@ -174,6 +176,18 @@ internal static MethodBuilder GenerateMethodSignature(string name, MethodInfo me
174176
return methodBuilder;
175177
}
176178

179+
internal static void GenerateInstanceOfIgnoresAccessChecksToAttribute(
180+
AssemblyBuilder assemblyBuilder,
181+
string assemblyName)
182+
{
183+
// [assembly: System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute(assemblyName)]
184+
var customAttributeBuilder = new CustomAttributeBuilder(
185+
IgnoresAccessChecksToAttributeConstructor,
186+
new object[] {assemblyName});
187+
188+
assemblyBuilder.SetCustomAttribute(customAttributeBuilder);
189+
}
190+
177191
private static System.Type ResolveTypeConstraint(MethodInfo method, System.Type typeConstraint)
178192
{
179193
if (typeConstraint != null && typeConstraint.IsGenericType)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// ReSharper disable once CheckNamespace
2+
namespace System.Runtime.CompilerServices
3+
{
4+
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
5+
public class IgnoresAccessChecksToAttribute : Attribute
6+
{
7+
public string AssemblyName { get; }
8+
9+
public IgnoresAccessChecksToAttribute(string assemblyName)
10+
{
11+
AssemblyName = assemblyName;
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)