7

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 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);
}

これは城のソースで修正できるものですか? または、DefaultProxyFactory をサブクラス化する必要がありますか?

4

3 に答える 3

2

私はこれで運が良かった。正直なところ、理由はわかりませんが、Krzysztof が説明した問題を再現できませんでした。たぶん...私のアセンブリがSN化されているという事実と関係があると思います...追加の変更を加える必要がありました...しかし、一度変更すると、プロキシを解決することができました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 さんのご意見をぜひお聞かせください...このソリューションが他のテスト ケースで機能しない場合は、これらのフィールドを保護していただけないでしょうか。 ?

于 2010-11-17T01:11:11.020 に答える
0

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

于 2010-11-11T21:52:47.240 に答える
0

私はここで完全に基地から外れているかもしれませんが、あなたは探していませんIncludeNonPublicTypes()か?

ドキュメントから

非公開型の登録

デフォルトでは、アセンブリの外部から見えるタイプのみが登録されます。非パブリック型を含める場合は、最初にアセンブリを指定してから、IncludeNonPublicTypes を呼び出す必要があります。

container.Register(
    AllTypes.FromThisAssembly()
        .IncludeNonPublicTypes()
        .BasedOn<NonPublicComponent>()
);
于 2010-11-11T17:41:48.480 に答える