MethodBuilder.DefineParameter无法设置参数名称的原因?

发布于 2024-08-19 15:15:33 字数 2627 浏览 4 评论 0原文

我正在基于 WCF 问题的现有接口创建一个接口,但我的“DefineParameter”未设置参数名称(创建类型的方法参数没有名称)。
你能看出原因吗?

    public static Type MakeWcfInterface(Type iService)
    {
        AssemblyName assemblyName = new AssemblyName(String.Format("{0}_DynamicWcf", iService.FullName));
        String moduleName = String.Format("{0}.dll", assemblyName.Name);
        String ns = iService.Namespace;
        if (!String.IsNullOrEmpty(ns)) ns += ".";

        // Create assembly
        var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);

        // Create module
        var module = assembly.DefineDynamicModule(moduleName, false);

        // Create asynchronous interface type
        TypeBuilder iWcfService = module.DefineType(
            String.Format("{0}DynamicWcf", iService.FullName),
            TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract
            );

        // Set ServiceContract attributes
        iWcfService.SetCustomAttribute(ReflectionEmitHelper.BuildAttribute<ServiceContractAttribute>(null,
            new Dictionary<string, object>() { 
                { "Name", iService.Name },
                }));

        iWcfService.SetCustomAttribute(ReflectionEmitHelper.BuildAttribute<ServiceBehaviorAttribute>(null,
            new Dictionary<string, object>() {
                    { "InstanceContextMode" , InstanceContextMode.Single }
                })
        );

        foreach (var method in iService.GetMethods())
        {
            BuildWcfMethod(iWcfService, method);
        }

        return iWcfService.CreateType();
    }


    private static MethodBuilder BuildWcfMethod(TypeBuilder target, MethodInfo template)
    {
        // Define method
        var method = target.DefineMethod(
            template.Name,
            MethodAttributes.Abstract | MethodAttributes.Virtual
             | MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.VtableLayoutMask | MethodAttributes.HideBySig,
            CallingConventions.Standard, 
            template.ReturnType,
            template.GetParameters().Select(p => p.ParameterType).ToArray()
            );

        // Define parameters
        foreach (ParameterInfo param in template.GetParameters())
        {
            method.DefineParameter(param.Position, ParameterAttributes.None, param.Name);
        }

        // Set OperationContract attribute
        method.SetCustomAttribute(ReflectionEmitHelper.BuildAttribute<OperationContractAttribute>(null, null));

        return method;
    }

I'm creating an interface based on an existing interface for WCF concerns, but I have the "DefineParameter" not setting the parameter names (method parameters of the created type have no name).
Can you see a reason why?

    public static Type MakeWcfInterface(Type iService)
    {
        AssemblyName assemblyName = new AssemblyName(String.Format("{0}_DynamicWcf", iService.FullName));
        String moduleName = String.Format("{0}.dll", assemblyName.Name);
        String ns = iService.Namespace;
        if (!String.IsNullOrEmpty(ns)) ns += ".";

        // Create assembly
        var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);

        // Create module
        var module = assembly.DefineDynamicModule(moduleName, false);

        // Create asynchronous interface type
        TypeBuilder iWcfService = module.DefineType(
            String.Format("{0}DynamicWcf", iService.FullName),
            TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract
            );

        // Set ServiceContract attributes
        iWcfService.SetCustomAttribute(ReflectionEmitHelper.BuildAttribute<ServiceContractAttribute>(null,
            new Dictionary<string, object>() { 
                { "Name", iService.Name },
                }));

        iWcfService.SetCustomAttribute(ReflectionEmitHelper.BuildAttribute<ServiceBehaviorAttribute>(null,
            new Dictionary<string, object>() {
                    { "InstanceContextMode" , InstanceContextMode.Single }
                })
        );

        foreach (var method in iService.GetMethods())
        {
            BuildWcfMethod(iWcfService, method);
        }

        return iWcfService.CreateType();
    }


    private static MethodBuilder BuildWcfMethod(TypeBuilder target, MethodInfo template)
    {
        // Define method
        var method = target.DefineMethod(
            template.Name,
            MethodAttributes.Abstract | MethodAttributes.Virtual
             | MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.VtableLayoutMask | MethodAttributes.HideBySig,
            CallingConventions.Standard, 
            template.ReturnType,
            template.GetParameters().Select(p => p.ParameterType).ToArray()
            );

        // Define parameters
        foreach (ParameterInfo param in template.GetParameters())
        {
            method.DefineParameter(param.Position, ParameterAttributes.None, param.Name);
        }

        // Set OperationContract attribute
        method.SetCustomAttribute(ReflectionEmitHelper.BuildAttribute<OperationContractAttribute>(null, null));

        return method;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

著墨染雨君画夕 2024-08-26 15:15:33

我明白了,所以我告诉你。
答案在于我使用 DefineParameter 函数的方式。
GetParameters 函数返回有关所提供方法的参数的信息。
但是 DefineParameter 函数为所有参数(包括返回参数)设置了参数信息,因此位置发生了变化:使用 DefineParameter,位置 0 引用返回参数,调用参数从位置 1 开始。

参见修复:

method.DefineParameter(param.Position+1, ParameterAttributes.None, param.Name);

STFM(参见 fu... . 手册):

MethodBuilder.DefineParameter 方法@ MSDN< /a>

干杯:)

I got it, so I let you know.
The answer is in the way I used the DefineParameter function.
The GetParameters function returns info about the parameters of a provided method.
But the DefineParameter function set parameter info for all parameters (including return parameter), so postions shift : using DefineParameter, position 0 references the return parameter, and call parameters begin at postion 1.

See the fix :

method.DefineParameter(param.Position+1, ParameterAttributes.None, param.Name);

STFM (see the fu.... manual) :

MethodBuilder.DefineParameter Method @ MSDN

Cheers :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文