C# RealProxy:泛型方法?

5

我正在尝试通过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 可以实现吗?


可以通过反射来查询泛型类型。 - fhj
试图找出确切的泛型类有点违背了拥有泛型类的目的。你为什么需要知道这个类? - Albin Sunnanbo
@Albin,我正在为一个依赖注入框架编写工厂方法代理。类似于Windsor的类型化工厂设施(http://kozmic.pl/archive/2009/12/24/castle-typed-factory-facility-reborn.aspx)。 - Igor Brejc
2个回答

6

有一篇非常好的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(...);
  }

  ...
}

没问题!但我仍然建议你阅读这篇文章,它真的很好。 - Ohad Schneider
链接坏了,太糟糕了! - Guge
@Guge谢谢你的发现,已经用Wayback Machine链接替换了。 - Ohad Schneider

3

对于方法调用,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
    }
}

Ruben,我测试了你的代码,它很好用,谢谢,点赞。很抱歉我无法接受两个答案。 - Igor Brejc
1
由于 IMethodCallMessage 实现了 IMethodMessage,而 MethodCallMessageWrapperIMethodCallMessage 的简单包装器,因此我们的答案基本上归结为相同的代码。 - Ohad Schneider

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接