From 78c0b36f8ed48d95055c812cf0da9638db677150 Mon Sep 17 00:00:00 2001 From: Alexander Zaytsev Date: Sat, 21 Jul 2018 00:24:15 +1200 Subject: [PATCH] Mark proxy assembly with IgnoresAccessChecksToAttribute to allow implementing non public interfaces --- src/NHibernate/Proxy/NHibernateProxyBuilder.cs | 11 ++++++++++- src/NHibernate/Proxy/ProxyBuilderHelper.cs | 14 ++++++++++++++ .../Util/IgnoresAccessChecksToAttribute.cs | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/NHibernate/Util/IgnoresAccessChecksToAttribute.cs diff --git a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs index 82b8d0647e8..8514ac7dc14 100644 --- a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs +++ b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs @@ -75,8 +75,17 @@ public TypeInfo CreateProxyType(System.Type baseType, IReadOnlyCollection !i.IsVisible) + .Select(i => i.Assembly.GetName().Name) + .Distinct(); + foreach (var a in assemblyNamesToIgnoreAccessCheck) + ProxyBuilderHelper.GenerateInstanceOfIgnoresAccessChecksToAttribute(assemblyBuilder, a); +#else interfaces.RemoveWhere(i => !i.IsVisible); - +#endif + var typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes, parentType, interfaces.ToArray()); var lazyInitializerField = typeBuilder.DefineField("__lazyInitializer", LazyInitializerType, FieldAttributes.Private); diff --git a/src/NHibernate/Proxy/ProxyBuilderHelper.cs b/src/NHibernate/Proxy/ProxyBuilderHelper.cs index 3466dbdc270..94af19db95d 100644 --- a/src/NHibernate/Proxy/ProxyBuilderHelper.cs +++ b/src/NHibernate/Proxy/ProxyBuilderHelper.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Reflection; using System.Reflection.Emit; +using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Security; using NHibernate.Util; @@ -21,6 +22,7 @@ internal static class ProxyBuilderHelper { private static readonly ConstructorInfo ObjectConstructor = typeof(object).GetConstructor(System.Type.EmptyTypes); private static readonly ConstructorInfo SecurityCriticalAttributeConstructor = typeof(SecurityCriticalAttribute).GetConstructor(System.Type.EmptyTypes); + private static readonly ConstructorInfo IgnoresAccessChecksToAttributeConstructor = typeof(IgnoresAccessChecksToAttribute).GetConstructor(new[] {typeof(string)}); internal static readonly MethodInfo SerializableGetObjectDataMethod = typeof(ISerializable).GetMethod(nameof(ISerializable.GetObjectData)); internal static readonly MethodInfo SerializationInfoSetTypeMethod = ReflectHelper.GetMethod(si => si.SetType(null)); @@ -181,6 +183,18 @@ internal static MethodBuilder GenerateMethodSignature(string name, MethodInfo me return methodBuilder; } + internal static void GenerateInstanceOfIgnoresAccessChecksToAttribute( + AssemblyBuilder assemblyBuilder, + string assemblyName) + { + // [assembly: System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute(assemblyName)] + var customAttributeBuilder = new CustomAttributeBuilder( + IgnoresAccessChecksToAttributeConstructor, + new object[] {assemblyName}); + + assemblyBuilder.SetCustomAttribute(customAttributeBuilder); + } + private static System.Type ResolveTypeConstraint(MethodInfo method, System.Type typeConstraint) { if (typeConstraint != null && typeConstraint.IsGenericType) diff --git a/src/NHibernate/Util/IgnoresAccessChecksToAttribute.cs b/src/NHibernate/Util/IgnoresAccessChecksToAttribute.cs new file mode 100644 index 00000000000..c159f5afae6 --- /dev/null +++ b/src/NHibernate/Util/IgnoresAccessChecksToAttribute.cs @@ -0,0 +1,14 @@ +// ReSharper disable once CheckNamespace +namespace System.Runtime.CompilerServices +{ + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + public class IgnoresAccessChecksToAttribute : Attribute + { + public string AssemblyName { get; } + + public IgnoresAccessChecksToAttribute(string assemblyName) + { + AssemblyName = assemblyName; + } + } +}