C # RealProxy: универсальные методы? - PullRequest
5 голосов
/ 31 октября 2010

Я пытаюсь обработать вызов универсального метода через RealProxy, но я не могу найти информацию о фактическом типе универсального параметра, используемого в перехваченном вызове метода. Выдержка из кода:

    public override IMessage Invoke(IMessage msg)
    {
        ...
        string methodName = (string)msg.Properties["__MethodName"];
        Type[] parameterTypes = (Type[])msg.Properties["__MethodSignature"];
        object[] args = (object[])msg.Properties["__Args"];

        MethodInfo method = typeToProxy.GetMethod(methodName, parameterTypes);
        ...

Допустим, я проксирую интерфейс типа

interface IFactory
{
   TService Create<TService>()
}

Когда я вызываю прокси

proxied.Create<MyClass>()

Я хочу иметь возможность узнать, что универсальный параметр имеет тип MyClass. Возможно ли это через RealProxy?

Ответы [ 2 ]

6 голосов
/ 31 октября 2010

Есть отличная MSDN статья о RealProxy, которую я рекомендую вам прочитать.Помимо прочего, он вводит MethodCallMessageWrapper, что избавляет вас от необходимости работать непосредственно со словарем Properties.Из последнего вы можете получить MethodBase, который в свою очередь содержит общие аргументы:

internal class MyProxy : RealProxy
{
   private object m_instance;    
   private MyProxy( object instance ) : base( typeof( IFactory) )
   {
      m_instance = instance;
   }

  public override IMessage Invoke( IMessage message )
  {
     IMethodCallMessage methodMessage =
        new MethodCallMessageWrapper( (IMethodCallMessage) message );

     // Obtain the actual method definition that is being called.
     MethodBase method = methodMessage.MethodBase;

     Type[] genericArgs = method.GetGenericArguments(); //This is what you want

     return new ReturnMessage(...);
  }

  ...
}
3 голосов
/ 31 октября 2010

Для вызовов методов аргумент IMessage должен быть IMethodMessage, который имеет свойство MethodBase:

public override IMessage Invoke(IMessage message)
{
    IMethodMessage methodMessage = message as IMethodMessage;
    if (methodMessage != null)
    {
         MethodBase method = methodMessage.MethodBase;
         Type[] genericArgs = method.GetGenericArguments();

         ...
    }
    else
    {
        // not a method call
    }
}
...