2012-02-08 10 views
68

OK、今は本当に混乱しています。Castle DynamicProxy - GTRとして使用されるGTPを含むプロキシ作成時の失敗

私はもともとthis problemを持っていました。これはポスターによると、最新のRhino.MocksライブラリにILMergedされたCastle.DynamicProxyのバージョンに関する問題です。主題に関するいくつかの当局によると、それは最新の城で修正されていますが、そのライブラリは新しいRhinoに登場していません。ほとんどの人は、「ちょうどRhinoのソースと最新のCastleをダウンロードし、独自のバージョンを構築する」と言っています。

だから、私はそれを正確に行いました。私はAyendeのGitHubからRhinoのトランクソースのZIPを取得し、それを開いて構築しました。その後、良い少しTDDerのように、私は(最新の城は、いくつかの重要な参照の変更を必要とし、コアにDynamicProxyを折るので)私の変更が働いていたことを確認するユニットテストを作成しました:

[Test] 
    public void MockOfInterfaceMethodWithInterfaceGTR() 
    { 
     var mock = mocks.DynamicMock<ITestRestrictedInterface>(); 
     Assert.NotNull(mock); 
     Expect.Call(mock.TestMethod(new Object2())).IgnoreArguments().Return(5); 
     mocks.ReplayAll(); 
     Assert.AreEqual(5, mock.TestMethod(new Object2())); 
    } 

... 

internal interface ITestGenericInterface<TRest> where TRest:IObject1 
{ 
    int TestMethod<T>(T input) where T : TRest; 
} 

internal interface ITestRestrictedInterface:ITestGenericInterface<IObject2> { } 

internal interface IObject1 { } 
internal interface IObject2:IObject1 { } 

internal class Object2:IObject2 { } 

私の中で実行した結果、最新のRhinoを使用して独自のプロダクションコードを作成しますか?

System.TypeLoadException:メソッド 'のtestMethod' タイプ の 'ITestRestrictedInterfaceProxy83ad369cdf41472c857f61561d434436' アセンブリから 'DynamicProxyGenAssembly2、バージョン= 0.0.0.0、文化=中立、 なPublicKeyToken = nullの' 暗黙的にしようとした次のようなメッセージで失敗より弱いタイプのパラメータ制約を持つインターフェイスメソッド を実装します。

...しかし、このテストをコピーしてRhino.Mocks.Testsプロジェクトのフィクスチャに貼り付けると、参照されたライブラリに変更を加えることなく、テストがパスします。私はダウンロードしたソースをゼロに変更しました。私はテストメソッドと関連するインターフェース/オブジェクトの両方をゼロに変更しました。私は新しいRhino.Mocks DLLを作成しました。これは、キャッスルライブラリをマージすることなく、キャッスルライブラリをコピーして私のプロダクションソリューションに戻し、テストを再実行しましたが、同じメッセージで失敗します。

WTF?

+2

このスレッドで特定された問題に関連している可能性があります。 http://stackoverflow.com/questions/6012420/why-does-this-generics-scenario-cause-a-typeloadexception?おそらく、それがまったく動作しているという事実は、そのスレッドに書かれている回避策に関係しているのかもしれません。おそらく、あなたのモックはパスシナリオでインターフェイスを明示的に(何とか)明示的に(むしろ暗黙的に)実装するのではないでしょうか? –

+2

ちょっとしたグーグルがこの[投稿](http:// platinumdogs。私/ 2010/04/09/c-implementing-generic-method-of-generic-interface-causes-runtime-exception /)は、コンパイラのバグを示しています。これがあなたの問題に当てはまるかどうかはわかりませんが、一見価値があります。彼らはまた、そのポストの解決策を持っています。 – jduncanator

+0

そのバグはずっと前に修正されているようです。 –

答えて

4

私は城の専門家やコンパイラの第一人者ないんだけど、私は問題がRhinoMocks.Testsアセンブリの内側に隠されている魔法の少しであると信じて:

https://github.com/ayende/rhino-mocks/blob/master/Rhino.Mocks.Tests/TestInfo.cs

using System.Runtime.CompilerServices; 
using Rhino.Mocks; 

[assembly: InternalsVisibleTo(RhinoMocks.StrongName)] 

から部品番号、which has this issue documentedを使用しているとき、私は同様の問題を見てきました

/// <summary> 
/// Used for [assembly: InternalsVisibleTo(RhinoMocks.StrongName)] 
/// Used for [assembly: InternalsVisibleTo(RhinoMocks.NormalName)] 
/// </summary> 
public static class RhinoMocks 
{ 
    /// <summary> 
    /// Strong name for the Dynamic Proxy assemblies. Used for InternalsVisibleTo specification. 
    /// </summary> 
    public const string StrongName = 
     "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"; 

    /// <summary> 
    /// Normal name for dynamic proxy assemblies. Used for InternalsVisibleTo specification. 
    /// </summary> 
    public const string NormalName = "DynamicProxyGenAssembly2"; 

    /// <summary> 
    /// Logs all method calls for methods 
    /// </summary> 
    public static IExpectationLogger Logger = new NullLogger(); 
} 

:完全のために、RhinoMocks.StrongNameは次のように定義されます。

キャッスルのDynamicProxyは、新しいタイプを動的に派生させる必要がありますが、あなたのアセンブリに内部のインタフェースを表示するための可視性がありません。 DynamicProxyGenAssembly2にInternalsVisibleToをテストライブラリに追加するだけで問題は解決します。

+1

OPは彼の質問に答えるかどうかは分からなかったので、あなたはこれに答える努力を示すためにバウンティを得る。 – CloudyMarble

関連する問題