温莎城堡内部可见到 Silverlight

发布于 2024-10-02 02:14:33 字数 2360 浏览 1 评论 0原文

我正在使用 Castle Windsor for SL v2.5.1.0。我让它代理内部类(当然接口是公共的,但实现是内部的,因此消费者只知道接口)。

我在程序集中使用以下属性和内部类。

[assembly: InternalsVisibleTo("Castle.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")]
[assembly: InternalsVisibleTo("Castle.Windsor, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

在完整的 .NET 4.0 模式下,使用 .NET 4.0 Castle 程序集,这工作正常,并且我的类型可以正常代理。在 Silverlight 中,使用 Silverlight Castle 程序集,我得到:

Type ConsoleApplication4.MyTypeToBeProxied is not public. Can not create proxy for types that are not accessible.

另外,只是在解决问题时,添加以下内容似乎没有什么区别...:

[assembly: InternalsVisibleTo("System.Core, PublicKey=00000000000000000400000000000000")]
[assembly: InternalsVisibleTo("System.Core, PublicKey=" +
"00240000048000009400000006020000002400005253413100040000010001008d56c76f9e8649" +
"383049f383c44be0ec204181822a6c31cf5eb7ef486944d032188ea1d3920763712ccb12d75fb7" +
"7e9811149e6148e5d32fbaab37611c1878ddc19e20ef135d0cb2cff2bfec3d115810c3d9069638" +
"fe4be215dbf795861920e5ab6f7db2e2ceef136ac23d5dd2bf031700aec232f6c6b1c785b4305c" +
"123b37ab")]

并且我还在运行时验证了 SL 中动态托管程序集的名称实际上仍然是DynamicProxyGenAssembly2。

有什么想法吗?谢谢。

编辑

我发现了我认为的问题:

Castle for .NET 4.0 有:

private bool IsAccessible(Type target)
{
  //      ....
  return ((target.IsPublic || target.IsNestedPublic) || internalAndVisibleToDynProxy);

}

在 DefaultProxyBuilder...并且 SL 4 有

private bool IsAccessible(Type target)
{
    target.IsNested();
    return (target.IsPublic || target.IsNestedPublic);
}

这可以在 Castle 源代码中修复吗?或者我是否需要/应该对 DefaultProxyFactory 进行子类化?

I'm using Castle Windsor for SL v2.5.1.0. I have it proxy internal classes (the interfaces are public of course, but the implementation is internal, so that the consumer is only aware of the interface).

I'm using the following attributes in my assembly with the internal classes

[assembly: InternalsVisibleTo("Castle.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")]
[assembly: InternalsVisibleTo("Castle.Windsor, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

In full .NET 4.0 mode, with the .NET 4.0 Castle assemblies, this works fine and my types are proxied OK. In Silverlight, with the Silverlight Castle assemblies, I get:

Type ConsoleApplication4.MyTypeToBeProxied is not public. Can not create proxy for types that are not accessible.

Also, just in troubleshooting the problem, adding the following seems to make no difference...:

[assembly: InternalsVisibleTo("System.Core, PublicKey=00000000000000000400000000000000")]
[assembly: InternalsVisibleTo("System.Core, PublicKey=" +
"00240000048000009400000006020000002400005253413100040000010001008d56c76f9e8649" +
"383049f383c44be0ec204181822a6c31cf5eb7ef486944d032188ea1d3920763712ccb12d75fb7" +
"7e9811149e6148e5d32fbaab37611c1878ddc19e20ef135d0cb2cff2bfec3d115810c3d9069638" +
"fe4be215dbf795861920e5ab6f7db2e2ceef136ac23d5dd2bf031700aec232f6c6b1c785b4305c" +
"123b37ab")]

and I've also verified at runtime that the name of the dynamically hosted assembly in SL is still in fact DynamicProxyGenAssembly2.

Any ideas? Thanks.

EDIT:

I found the problem I think:

Castle for .NET 4.0 has:

private bool IsAccessible(Type target)
{
  //      ....
  return ((target.IsPublic || target.IsNestedPublic) || internalAndVisibleToDynProxy);

}

in the DefaultProxyBuilder...and SL 4 has

private bool IsAccessible(Type target)
{
    target.IsNested();
    return (target.IsPublic || target.IsNestedPublic);
}

Is this something that can be fixed in the Castle source? Or do I need to/should I sub-class the DefaultProxyFactory?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

疯到世界奔溃 2024-10-09 02:14:33

我在这方面有一些运气。老实说,我不确定为什么,但我无法重现 Krzysztof 描述的问题。我怀疑...也许...这与我的程序集是 SN'd 的事实有关...这需要我进行额外的更改...但是一旦我这样做了,我就能够解决代理问题用于 SL 测试应用程序中的内部类(具有公共接口)。

我必须对 Castle.Core 源代码进行的唯一更改是使 ModuleScope.moduleBuilderModuleScope.moduleBuilderWithStrongName 字段受保护而不是私有。但同样,这只是必要的,以便我可以在 SL 中定义 SN 动态程序集,而 Castle.Core 中的 ModuleScope 对 SL 禁用了该程序集。所以,现在我有一个自定义 ModuleScope,如下所示:

    private class StrongNameModuleScope : ModuleScope
    {
        public StrongNameModuleScope()
        {
            var assemblyName = new AssemblyName("DynamicProxyGenAssembly2");
            // copied from another one of my SN assemblies (plus GetName() on assembly is security critical so I can't pull it off the executing assembly)
            byte[] publicKey = Convert.FromBase64String(@"ACQAAASAAACUAAAABgIAAAAkAABSU0ExAAQAAAEAAQBvwWquPXQG9zfemS8uDsFdGDScOCSjZ9aFsQDtrrAqKzvlxEGMz3t9Q9M3X9NKqy1ouLZi+sX8yVDafX+UnygFWWfOBosw9nGwG61MTKEhEjdKH0rECahGIXY+ETdNY64HduuH/BIbEs/RDhrrH2hiqGrOGb6AghD1sZ6g0A1qkg==");
            assemblyName.SetPublicKey(publicKey);
            AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            ModuleBuilder module = assembly.DefineDynamicModule("DynamicProxyGenAssembly2");
            moduleBuilder = module;
            moduleBuilderWithStrongName = module;
        }
    }

和一个自定义 DefaultProxyBuilder:

    /// <summary>
    ///   A custom IProxyBuilder copies from the full .NET Castle implementation that allows for proxies of internal types where the InternalsVisibleToAttribute is applied.
    /// </summary>
    private class DefaultProxyBuilder : IProxyBuilder
    {
       ...
        // Methods
        public DefaultProxyBuilder()
            : this(new StrongNameModuleScope())
        {
        }
       ...
        private static bool IsAccessible(Type target)
        {
            bool isTargetNested = target.IsNested;
            bool isNestedAndInternal = isTargetNested && (target.IsNestedAssembly || target.IsNestedFamORAssem);
            bool internalAndVisibleToDynProxy = ((!target.IsVisible && !isTargetNested) || isNestedAndInternal) && InternalsHelper.IsInternalToDynamicProxy(target.Assembly);
            return ((target.IsPublic || target.IsNestedPublic) || internalAndVisibleToDynProxy);
        }
    }

和一个自定义 DefaultProxyFactory:

  /// <summary>
    ///   A simple DefaultProxyFactory to wrap the modified DefaultProxyBuilder.
    /// </summary>
    private class DefaultProxyFactory : global::Castle.Windsor.Proxy.DefaultProxyFactory
    {
        public DefaultProxyFactory()
        {
            generator = new ProxyGenerator(new DefaultProxyBuilder());
        }
    }

和容器设置:

        container = new WindsorContainer();

        container.Kernel.ProxyFactory = new DefaultProxyFactory();

我不太喜欢修改 Castle.Core 源,所以我真的很想听听您的想法 Krzysztof...如果此解决方案不适用于其他测试用例,您是否可以保护这些字段?

I had some luck with this. To be honest, I'm not sure why, but I couldn't reproduce the problem described by Krzysztof. I suspect...maybe...it has something to do with the fact that my assemblies are SN'd...which required me to make an additional change...but once I did, I was able to get proxies resolved for internal classes (with public interfaces) in a SL test application.

The only change I had to make to the Castle.Core source was to make the fields ModuleScope.moduleBuilder and ModuleScope.moduleBuilderWithStrongName protected instead of private. But again, that was only necessary so that I could define a SN'd dynamic assembly in SL, which is disabled for SL by the ModuleScope in Castle.Core. So, now I have a custom ModuleScope as follows:

    private class StrongNameModuleScope : ModuleScope
    {
        public StrongNameModuleScope()
        {
            var assemblyName = new AssemblyName("DynamicProxyGenAssembly2");
            // copied from another one of my SN assemblies (plus GetName() on assembly is security critical so I can't pull it off the executing assembly)
            byte[] publicKey = Convert.FromBase64String(@"ACQAAASAAACUAAAABgIAAAAkAABSU0ExAAQAAAEAAQBvwWquPXQG9zfemS8uDsFdGDScOCSjZ9aFsQDtrrAqKzvlxEGMz3t9Q9M3X9NKqy1ouLZi+sX8yVDafX+UnygFWWfOBosw9nGwG61MTKEhEjdKH0rECahGIXY+ETdNY64HduuH/BIbEs/RDhrrH2hiqGrOGb6AghD1sZ6g0A1qkg==");
            assemblyName.SetPublicKey(publicKey);
            AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
            ModuleBuilder module = assembly.DefineDynamicModule("DynamicProxyGenAssembly2");
            moduleBuilder = module;
            moduleBuilderWithStrongName = module;
        }
    }

And a custom DefaultProxyBuilder:

    /// <summary>
    ///   A custom IProxyBuilder copies from the full .NET Castle implementation that allows for proxies of internal types where the InternalsVisibleToAttribute is applied.
    /// </summary>
    private class DefaultProxyBuilder : IProxyBuilder
    {
       ...
        // Methods
        public DefaultProxyBuilder()
            : this(new StrongNameModuleScope())
        {
        }
       ...
        private static bool IsAccessible(Type target)
        {
            bool isTargetNested = target.IsNested;
            bool isNestedAndInternal = isTargetNested && (target.IsNestedAssembly || target.IsNestedFamORAssem);
            bool internalAndVisibleToDynProxy = ((!target.IsVisible && !isTargetNested) || isNestedAndInternal) && InternalsHelper.IsInternalToDynamicProxy(target.Assembly);
            return ((target.IsPublic || target.IsNestedPublic) || internalAndVisibleToDynProxy);
        }
    }

And a custom DefaultProxyFactory:

  /// <summary>
    ///   A simple DefaultProxyFactory to wrap the modified DefaultProxyBuilder.
    /// </summary>
    private class DefaultProxyFactory : global::Castle.Windsor.Proxy.DefaultProxyFactory
    {
        public DefaultProxyFactory()
        {
            generator = new ProxyGenerator(new DefaultProxyBuilder());
        }
    }

And the container setup:

        container = new WindsorContainer();

        container.Kernel.ProxyFactory = new DefaultProxyFactory();

I'm not so fond of having had to modify the Castle.Core sources, so I'd really like to hear your thoughts Krzysztof...maybe could you just make those fields protected if this solution doesn't work for other test cases?

鹿港小镇 2024-10-09 02:14:33

我可能完全没有根据,但你不是在寻找 IncludeNonPublicTypes() 吗?

来自文档

注册非公共类型

默认情况下,只会注册从程序集外部可见的类型。如果要包含非公共类型,则必须首先指定程序集,然后调用 IncludeNonPublicTypes

container.Register(
    AllTypes.FromThisAssembly()
        .IncludeNonPublicTypes()
        .BasedOn<NonPublicComponent>()
);

I may be totally off base here, but aren't you looking for IncludeNonPublicTypes()?

From the documentation:

Registering non-public types

By default only types visible from outside of the assembly will be registered. If you want to include non-public types, you have to start with specifying assembly first, and then call IncludeNonPublicTypes

container.Register(
    AllTypes.FromThisAssembly()
        .IncludeNonPublicTypes()
        .BasedOn<NonPublicComponent>()
);
隔纱相望 2024-10-09 02:14:33

原因是 Silverlight 安全模型不允许我们为内部类型构建代理,即使使用 InternalsVisibleTo 也是如此。

The reason for that is that Silverlight security model does not allow us to build a proxy for an internal type, even with InternalsVisibleTo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文