2010-02-02 1 views
1

Я создаю интерфейс, основанный на существующем интерфейсе для проблем WCF, но у меня есть «DefineParameter», не устанавливающий имена параметров (параметры метода созданного типа не имеют имени).
Вы видите причину?Причина, почему MethodBuilder.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; 
    } 

ответ

9

Я получил его, поэтому я дал вам знать.
Ответ в том, как я использовал функцию DefineParameter.
Функция GetParameters возвращает информацию о параметрах предоставленного метода.
Но функция DefineParameter установить параметр Информация для всех параметров (включая параметр возврата), так postions сдвиг: использование DefineParameter, позиция 0 ссылается на возвращаемый параметр, и параметры вызова начинаются в постион 1.

Смотрите исправление:

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

STFM (см фу .... ручной):

MethodBuilder.DefineParameter Method @ MSDN

Ура :)

+0

Спасибо, спасли мне некоторое время на чтение руководства :) –