C# ILGenerator:如何生成函数<&燃气轮机;作为论据通过

C# ILGenerator:如何生成函数<&燃气轮机;作为论据通过,c#,wrapper,reflection.emit,emit,ilgenerator,C#,Wrapper,Reflection.emit,Emit,Ilgenerator,我试图围绕由接口定义的服务创建一个代理包装器,以对服务的开发人员用户“隐藏”特定于客户端的调用代码 我已经能够生成包装器类本身的大部分内容,但现在正在努力为预先存在的客户机调用生成Func参数 示例TService有一个接口: public interface ITestService { public Task ServiceMethodAsync(); public Task<TestDTO> ServiceMethodWithResultAsync(); }

我试图围绕由接口定义的服务创建一个代理包装器,以对服务的开发人员用户“隐藏”特定于客户端的调用代码

我已经能够生成包装器类本身的大部分内容,但现在正在努力为预先存在的客户机调用生成Func参数

示例TService有一个接口:

public interface ITestService
{
    public Task ServiceMethodAsync();
    public Task<TestDTO> ServiceMethodWithResultAsync();
}
而首选的选择是,他们可以直接打电话:

var result = await service.ServiceMethodWithResultAsync(requestDTO);
因为这允许DI使用IService接口注入本地服务或my remote wrapper,开发人员不需要考虑它是远程服务还是本地服务

我目前让typebuilder生成所需的代码,以创建从客户机继承的包装类
baseType
,并针对它定义所有接口方法,但当前将null作为
Func操作传递

private static void DefineInterface(TypeBuilder typeBuilder, Type baseType, Type serviceInterfaceType)
{
    foreach (MethodInfo serviceMethod in serviceInterfaceType.GetMethods())
    {
        ParameterInfo[] parameters = serviceMethod.GetParameters();
        MethodBuilder methodBuilder = typeBuilder.DefineMethod(
            serviceMethod.Name,
            serviceMethod.Attributes ^ MethodAttributes.Abstract,
            serviceMethod.CallingConvention,
            serviceMethod.ReturnType,
            serviceMethod.ReturnParameter.GetRequiredCustomModifiers(),
            serviceMethod.ReturnParameter.GetOptionalCustomModifiers(),
            parameters.Select(p => p.ParameterType).ToArray(),
            parameters.Select(p => p.GetRequiredCustomModifiers()).ToArray(),
            parameters.Select(p => p.GetOptionalCustomModifiers()).ToArray());

        ILGenerator ilGenerator = methodBuilder.GetILGenerator();

        MethodInfo callAsyncMethod = getCallAsyncMethod(baseType, serviceMethod);

        ilGenerator.Emit(OpCodes.Ldarg_0); // Push "this"
        ilGenerator.Emit(OpCodes.Ldnull); // Push Func<> argument
        ilGenerator.Emit(OpCodes.Call, callAsyncMethod); // Call CallAsync on the base client
        ilGenerator.Emit(OpCodes.Ret);
    }
}
私有静态void DefineInterface(TypeBuilder、TypeBaseType、TypeServiceInterfaceType)
{
foreach(serviceInterfaceType.GetMethods()中的MethodInfo serviceMethod)
{
ParameterInfo[]parameters=serviceMethod.GetParameters();
MethodBuilder MethodBuilder=typeBuilder.DefineMethod(
serviceMethod.Name,
serviceMethod.Attributes^MethodAttributes.Abstract,
serviceMethod.CallingConvention,
serviceMethod.ReturnType,
serviceMethod.ReturnParameter.GetRequiredCustomModifiers(),
serviceMethod.ReturnParameter.GetOptionalCustomModifiers(),
parameters.Select(p=>p.ParameterType).ToArray(),
parameters.Select(p=>p.GetRequiredCustomModifiers()).ToArray(),
选择(p=>p.GetOptionalCustomModifiers()).ToArray();
ILGenerator ILGenerator=methodBuilder.GetILGenerator();
MethodInfo callAsyncMethod=getCallAsyncMethod(baseType,serviceMethod);
ilGenerator.Emit(操作码.Ldarg_0);//推送“this”
ilGenerator.Emit(OpCodes.Ldnull);//Push Func参数
ilGenerator.Emit(OpCodes.Call,callAsyncMethod);//在基本客户端上调用CallAsync
ilGenerator.Emit(操作码.Ret);
}
}
从这里开始,我有点纠结于如何准确地定义Func
service=>service.ServiceMethodWithResultAsync(requestDTO)
包括
requestDTO
参数,我期望/假设这些参数将出现在
Ldarg\u 1
Ldarg\u 2


非常感谢您的帮助。

我对IL不是很坚定。我更喜欢使用ExpressionTrees来创建动态lambda函数,但这不能用于创建整个类。如果您像在IL中创建一样编写一个示例实现,可能会有所帮助。运行编译器并使用任何反编译器查看创建的内容。也许你会得到你需要的提示。
var result = await service.ServiceMethodWithResultAsync(requestDTO);
private static void DefineInterface(TypeBuilder typeBuilder, Type baseType, Type serviceInterfaceType)
{
    foreach (MethodInfo serviceMethod in serviceInterfaceType.GetMethods())
    {
        ParameterInfo[] parameters = serviceMethod.GetParameters();
        MethodBuilder methodBuilder = typeBuilder.DefineMethod(
            serviceMethod.Name,
            serviceMethod.Attributes ^ MethodAttributes.Abstract,
            serviceMethod.CallingConvention,
            serviceMethod.ReturnType,
            serviceMethod.ReturnParameter.GetRequiredCustomModifiers(),
            serviceMethod.ReturnParameter.GetOptionalCustomModifiers(),
            parameters.Select(p => p.ParameterType).ToArray(),
            parameters.Select(p => p.GetRequiredCustomModifiers()).ToArray(),
            parameters.Select(p => p.GetOptionalCustomModifiers()).ToArray());

        ILGenerator ilGenerator = methodBuilder.GetILGenerator();

        MethodInfo callAsyncMethod = getCallAsyncMethod(baseType, serviceMethod);

        ilGenerator.Emit(OpCodes.Ldarg_0); // Push "this"
        ilGenerator.Emit(OpCodes.Ldnull); // Push Func<> argument
        ilGenerator.Emit(OpCodes.Call, callAsyncMethod); // Call CallAsync on the base client
        ilGenerator.Emit(OpCodes.Ret);
    }
}