.net 温莎城堡银光大道酒店

.net 温莎城堡银光大道酒店,.net,silverlight-4.0,castle-windsor,castle-dynamicproxy,.net,Silverlight 4.0,Castle Windsor,Castle Dynamicproxy,我正在为SL v2.5.1.0使用Castle Windsor。我有它的代理内部类(接口当然是公共的,但是实现是内部的,所以使用者只知道接口) 在我的程序集中,我将以下属性用于内部类 [assembly: InternalsVisibleTo("Castle.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB58

我正在为SL v2.5.1.0使用Castle Windsor。我有它的代理内部类(接口当然是公共的,但是实现是内部的,所以使用者只知道接口)

在我的程序集中,我将以下属性用于内部类

[assembly: InternalsVisibleTo("Castle.Core, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")]
[assembly: InternalsVisibleTo("Castle.Windsor, PublicKey=002400000480000094000000060200000024000052534131000400000100010077F5E87030DADCCCE6902C6ADAB7A987BD69CB5819991531F560785EACFC89B6FCDDF6BB2A00743A7194E454C0273447FC6EEC36474BA8E5A3823147D214298E4F9A631B1AFEE1A51FFEAE4672D498F14B000E3D321453CDD8AC064DE7E1CF4D222B7E81F54D4FD46725370D702A05B48738CC29D09228F1AA722AE1A9CA02FB")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
在完整的.NET 4.0模式下,使用.NET 4.0 Castle程序集,这可以正常工作,并且我的类型可以代理。在Silverlight,通过Silverlight城堡集会,我得到:

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 source中修复的东西吗?或者我需要/应该对DefaultProxyFactory进行子分类吗?

我在这里可能完全不正确,但您不是在寻找
includeNoPublicTypes()

:

注册非公共类型

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

container.Register(
AllTypes.FromThisAssembly()
.includeNoPublicTypes()
.BasedOn()
);

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

我在这方面有点运气。老实说,我不知道为什么,但我无法重现Krzysztof所描述的问题。我怀疑…可能…这与我的程序集是SN'd有关…这需要我做额外的更改…但一旦我做了,我就能够在SL测试应用程序中为内部类(带有公共接口)解析代理

我必须对Castle进行的唯一更改。核心源代码是将字段
ModuleScope.moduleBuilder
ModuleScope.moduleBuilder的strongName
设置为受保护而不是私有。但同样,这只是为了我能够在SL中定义SN'd动态程序集而必需的,它是由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);
        }
    }

我不太喜欢修改Castle.Core源代码,所以我很想听听你的想法Krzysztof…如果这个解决方案不适用于其他测试用例,也许你能保护这些字段吗?

不,我正在手动注册。该类型注册得很好,只是在代理生成时它崩溃了(因为上面引用的代码)。那我就不知道了。你真的不能公开你的课程:P。那么,从设计的角度来看,你有什么建议?我真的不希望我的代码的所有内部内容都暴露给消费者…只有接口。。。谢谢。有趣的旁注…我确实将.NET 4.0中的DefaultProxyBuilder复制到了我的代码中,然后用一个虚拟的ProxyFactory创建了我的Windsor容器,它用一个引用我的新DefaultProxyBuilder的ProxyGenerator来实例化generator字段…它在我的单元测试中工作!但我想当我尝试在SL运行时下运行它时,它不会起作用……是的,它在Silverlight安全沙箱中的Silverlight上失败了,至少在我运行测试时失败了。如果你找到了一个解决方案,我很乐意尝试一下。嗯,很有趣-所以我想这里的关键区别可能是你使用与你自己的程序集相同的密钥对生成的程序集进行签名,而通常如果DP生成强名称的程序集,则使用Castle的密钥对其进行签名。所以我猜,也许规则是,如果A将B作为好友,并且两者都使用相同的密钥签名,那么您可以在assebly B中使用程序集A的内部类型。感谢您的调查-将其放入问题跟踪程序中,我们将研究如何将其烘焙到vNext中。感谢您的快速跟进!另外,关于您的第一点,可能不是使用同一个密钥具有相关性……而是DP在SL版本中不会自行执行任何强签名(ShouldStrongName或类似属性的硬编码为false)……大概是因为SL没有StrongNameKeyPair类()…但这并没有阻止我简单地调用SetPublicKey并获得一个强命名的动态程序集:)…这可能正是使它工作的原因我终于有了一分钟的时间,并且能够通过在动态程序集上使用与InternalsVisibleTo程序集不同的公钥来生成拒绝访问异常。
    /// <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);
        }
    }
  /// <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();