Reflection.Emit参数传递

时间:2011-11-07 14:17:44

标签: c# wcf reflection.emit

我想为WCF服务创建一个自动生成的代理,这样我就可以避免手动创建服务代理。

使用反射发射,我创建了动态类生成的完整循环(从汇编到方法),我的方法生成代码如下:

        bool isVoid;

        if ((isVoid = (methodInfo.ReturnType != typeof(void))))
            generator.DeclareLocal(methodInfo.ReturnType);

        generator.Emit(OpCodes.Ldarg_0);
        var channelProperty = baseType.GetMethod(ChannelPropertyGetName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty);

        generator.EmitCall(OpCodes.Call, channelProperty, null);

        for (short index = 0; index < parameters.Count(); index++)
            generator.Emit(OpCodes.Ldarg, (index + 1));

        generator.Emit(OpCodes.Callvirt, methodInfo);

        if (isVoid)
        {
            generator.Emit(OpCodes.Stloc_0);
            generator.Emit(OpCodes.Ldloc_0);
        }

        generator.Emit(OpCodes.Ret);

我也有服务和适当的服务合同如下:

[ServiceContract]
public interface INamingService
{
    /// <summary>
    /// Resolve a name
    /// </summary>
    [OperationContract(Name = "GetName")]
    string GetName(string name);

}

但是当我尝试通过指定的名称(非空)从此服务中检索值时,我看到来自客户端调用的参数为null。因此,据我所知,我在Emit中犯了一个错误,参数没有通过。

有人可以告诉我,如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

以下是一些小问题:

  1. isVoid似乎是一个糟糕的名字,因为它表明方法没有返回void。
  2. 您对本地的使用似乎是不必要的 - 您只是存储它,然后立即重新加载该值。
  3. 我不明白你为什么要使用EmitCall来获取属性getter;您几乎肯定会使用Emit代替(请参阅the documentation)。
  4. 但是,我不明白为什么你认为这个问题与你的IL一代有关;对我来说,听起来你更有可能

    1. 错误地声明您的动态方法,或
    2. 以某种方式错误连接代理。