【问题标题】:Which `[InternalsVisibleTo]` for .NET Framework and .NET Standard / Core framework assemblies?.NET Framework 和 .NET Standard / Core 框架程序集的哪个“[InternalsVisibleTo]”?
【发布时间】:2018-05-25 11:08:12
【问题描述】:

我遇到了跨程序集/朋友程序集类型可见性的问题。

我有以下程序(我签名/强名称)。它告诉 Castle DynamicProxy(我正在使用 Castle.Core NuGet 包的 4.2.1 版)为我的接口 IFoo 创建一个代理。我还指定我的internal class InterfaceProxyBase 应该是代理类型的基类。

DynamicProxy 然后使用System.Reflection.Emit 创建代理类型。但显然,System.Reflection.Emit.TypeBuilder 无权访问InterfaceProxyBase

// [assembly: InternalsVisibleTo("?")]
//                               ^^^
// What do I need here for my program to work both on the .NET Framework 4.5+
// and on .NET Core / .NET Standard 1.3+?

using Castle.DynamicProxy;

class Program
{
    static void Main()
    {
        var generator = new ProxyGenerator();

        var options = new ProxyGenerationOptions
            {
                BaseTypeForInterfaceProxy = typeof(InterfaceProxyBase)  // <--
            };

        var proxy = generator.CreateInterfaceProxyWithoutTarget(
                typeof(IFoo),
                options,
                new Interceptor());
    }
}

public interface IFoo { }

internal abstract class InterfaceProxyBase { }

internal sealed class Interceptor : IInterceptor
{
    public void Intercept(IInvocation invocation) { }
}

Unhandled Exception: System.TypeLoadException: Access is denied: 'InterfaceProxyBase'.
   at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
   ...
   at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
   at Program.Main() in Program.cs

所以,显然我需要一个 [assembly: InternalsVisibleTo] 属性用于框架自己的程序集/程序集。我的程序(实际上是一个类库)同时针对 .NET 4.5 和 .NET Standard 1.3。

我需要哪些[assembly: InternalsVisibleTo] 属性(包括精确的公钥)才能使我的代码适用于上述平台/目标?


PS:我知道我可以通过将 InterfaceProxyBase 设为 public 并为外观用 [EditorBrowsable(Never)] 隐藏它来规避问题,但如果我没有,我真的不想公开这个内部类型到。

P.P.S.:如果将内部结构公开给框架程序集是一个非常糟糕的主意,出于安全考虑,请告诉我,然后我会很高兴地重新考虑我的方法。

【问题讨论】:

  • 你不能试试“Castle.Core”吗?结果如何?
  • @LexLi:这是我首先尝试的。使内部对 Castle.Core 可见并没有任何明显的效果。然后我查看了堆栈跟踪,发现异常是由框架内部的TypeBuilder触发的;不是城堡。我本来希望权限从 Castle 冒泡到框架中(那些讨厌的 LinkDemand 东西我从来没有真正理解过),但显然这不是它现在的工作方式。
  • 听起来你需要为 .NET Framework 设置为 mscorlib,为 .NET Core 设置为 System.Reflection.Emitdocs.microsoft.com/en-us/dotnet/api/… 但我想知道 Castle 是否为你提供了更好的方法。您能否尝试检查 TypeBuilder 在 Castle 中的使用方式(来自异常调用堆栈)?这可能会给你一些提示。
  • @LexLi:这可能值得一试。我显然已经尝试过mscorlibSystemSystem.CoreSystem.Reflection.Emit(在 .NET Core 上),困难在于知道要包含哪些公钥。

标签: .net .net-core castle-dynamicproxy base-class-library internalsvisibleto


【解决方案1】:

你应该为DynamicProxyGenAssembly2设置InternalsVisibleTo

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

DynamicProxyGenAssembly2 是由Castle.DynamicProxy 构建的临时程序集。此程序集包含从您的InterfaceProxyBase 继承的生成的代理类型。这就是为什么DynamicProxyGenAssembly2 应该可以访问InterfaceProxyBase 类型。可能的选项是添加InternalsVisibleTo 属性或公开InterfaceProxyBase

【讨论】:

  • 啊……当然!我误以为是框架程序集无法访问InterfaceProxyBase,而实际上是DynamicProxyGenAssembly2InterfaceProxyBase中生成的接口代理类型之间的继承关系触发了“拒绝访问”。您能否将此作为简短说明添加到您的答案中,然后我会将其标记为已接受的答案。
  • 我已将此注释添加到我的答案中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-04
  • 1970-01-01
  • 2019-10-01
  • 2020-08-13
  • 1970-01-01
相关资源
最近更新 更多