2016-04-23 2 views
2

У меня есть атрибут request, который я украшаю некоторыми службами, но мне нужно передать в него общий тип из-за некоторой логики, происходящей внутри него. Это выглядит примерно так:Передача/выставление T на фильтр запроса ServiceStack

[SomeAttribute(typeof(MyClass))] 

Это хорошо работает, но если я что-то такое, как ...

[SomeAttribute<MyClass>] 

... Я получить «Аннотации не может быть общим» компиляции время.

Внутри мой атрибут выполнения логики, мне нужно сделать следующее:

someClass.doSomething<MyClass>(someString); 

Итак, мой вопрос ...

  • Могу ли я бросить MyClass в той или иной форме T так что я могу использовать его таким образом?
  • Есть ли другой способ пропускать 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 (« ключ »)', где я пытаюсь получить к. О, и используя Mono, FYI ... Имеет смысл? И еще раз спасибо! – napo

+1

@napo Ему нужно вызвать метод-оболочку, который возвращает 'object' вместо генерирующего ответа' T', посмотрите [ServiceGatewayExtensions] (https://github.com/ServiceStack/ServiceStack/blob/f4c9606b17dae06c7af193d7661dfa2b31d8b722/src /ServiceStack.Client/ServiceGatewayExtensions.cs#L30), который по сути делает то же самое. Это работает точно так же в Mono. В противном случае вы можете вызвать его с отражением напрямую, т. Е. Без кэширования делегата, например: 'genericMi.Invoke (this.cache, new [] {someString})'. – mythz

 Смежные вопросы

  • Нет связанных вопросов^_^