2016-04-23 6 views
2

いくつかのサービスを装飾しているという要求属性がありますが、内部で何らかのロジックが発生しているため、ジェネリック型を渡す必要があります。それはそうのようになります。ServiceStackリクエストフィルタにTを渡す/公開する

[SomeAttribute(typeof(MyClass))] 

これはうまく動作しますが、私は、このような

[SomeAttribute<MyClass>] 

...として何かをしている場合...私は「注釈は、一般的なことはできません」取得しますコンパイル時間エラー。私の属性インサイド

は、ロジックを実行し、私は次のことを実行する必要があります。

someClass.doSomething<MyClass>(someString); 

だから、私の質問は...

  • は、私は私ができるのでTのいくつかのフォームにMyClassをキャストすることができていますそのように使う?
  • Tを属性に渡して別の方法でコンパイルエラーが発生することはありませんか?

ありがとうございます!

答えて

4

エラーメッセージには、.NETアノテーションは汎用ではありませんので、遅延バインドTypeのみを渡すことができます。遅延バインディングタイプから汎用的なメソッドを呼び出すための唯一の方法は、リフレクションを使用することで、例えば:

var mi = typeof(MyClass).GetMethod("doSomething"); 
var genericMi = mi.MakeGenericMethod(typeof(MyAttributeType)); 
var doSomethingFn = (Func<string, object>) genericMi.CreateDelegate(
    typeof(Func<string, object>)); 

その後、あなたはstringを取り、objectを返すジェネリックメソッドのコンパイル済みのデリゲートをキャッシュして呼び出すことができ、例:

object response = doSomethingFn(someString); 
+0

@mythz!だから、あなたはどこに行くのか見ていて、それはかなりいい意味です。しかし、あなたの例では、 'doSomethingFn'で' 'メソッドの引数は互換性がありません ''というランタイム例外がスローされます。 – napo

+0

PS:あなたはServiceStackの背後にいるので、もう少しコンテキストがあります。属性をキャッシュする実装をしようとしています。this.cache.Get ( "key") 'は私が取得しようとしている場所ですに。ああ、モノを使用して、FYI ... 意味がありますか?もう一度ありがとう! – napo

+1

@napo一般的な 'T'レスポンスの代わりに' object'を返すラッパーメソッドを呼び出す必要があります。[ServiceGatewayExtensions](https://github.com/ServiceStack/ServiceStack/blob/f4c9606b17dae06c7af193d7661dfa2b31d8b722/src /ServiceStack.Client/ServiceGatewayExtensions.cs#L30)、これは本質的に同じことをしています。これはMonoとまったく同じように動作します。さもなければ、代理人をキャッシュすることなく直接反映させることができます。例えば、 'genericMi.Invoke(this.cache、new [] {someString})'。 – mythz