mardi 12 avril 2016

Reflection: returned methods consist on undeclared parameters

A little setup: I'm trying to create a generic application that is reading and invoking WCF applications based on their ?singleWsdl. The class here is named WcfFactory.

I've created a solution consisting of a WCF service to test. The declared methods are as following (Interface)

[OperationContract]
string DoWork();

[OperationContract]
string Hello(string FirstName, string LastName);

[OperationContract]
int Power(int Number1, int Number2);

My console app that is consuming my library spits the following:

DoWork
Returns: System.String

Hello
 - FirstName (System.String, out: False, ref: False)
 - LastName (System.String, out: False, ref: False)
Returns: System.String

Power
 - Number1 (System.Int32, out: False, ref: False)
 - Number1Specified (System.Boolean, out: False, ref: False)
 - Number2 (System.Int32, out: False, ref: False)
 - Number2Specified (System.Boolean, out: False, ref: False)
 - PowerResult (System.Int32&, out: True, ref: True)
 - PowerResultSpecified (System.Boolean&, out: True, ref: True)
Returns: System.Void

The SingleWsdl also isn't revealing anything spectacular:

<xs:element name="DoWork">
    <xs:complexType>
        <xs:sequence/>
    </xs:complexType>
</xs:element>
<xs:element name="DoWorkResponse">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="DoWorkResult" nillable="true" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="Hello">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="FirstName" nillable="true" type="xs:string"/>
            <xs:element minOccurs="0" name="LastName" nillable="true" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="HelloResponse">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="HelloResult" nillable="true" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="Power">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="Number1" type="xs:int"/>
            <xs:element minOccurs="0" name="Number2" type="xs:int"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="PowerResponse">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="PowerResult" type="xs:int"/>
        </xs:sequence>
    </xs:complexType>
</xs:element></xs:schema>

(apologies, pretty print failed to pretify)

I retrieve a list of Methods which I store in a MethodInfo[] object. On this I call MethodInfo[0].GetParameters();

Why is it working for the unparameterized function and for the function containing the strings, but not for the integer one?

And how can I resolve this?

Any help is greatly appreciated.

For completeness, the part of code that is filling my console application (it's already partially filled for dynamic objects)

foreach(var param in meth.GetParameters())
{
    if(fact.assemblyTypes.Where(x => x.Name == param.ParameterType.Name).Count() == 1)
    {
         #region Stuck

         Type typ = fact.assemblyTypes[1].GetType();
         //getparams<fact.assemblyTypes[1]>getparams();

         var instance = Activator.CreateInstance(fact.assemblyTypes[1]);

         var propertyNamesFromInstance = instance.GetType().GetProperties()
             .Where(p => p.CanWrite)
             .OrderBy(x => x.Name)
             .Select(x => x.Name);

         foreach (var test in propertyNamesFromInstance)
         {
             PropertyInfo prop = instance.GetType()
                 .GetProperty(test, BindingFlags.Public | BindingFlags.Instance);
             if (null != prop && prop.CanWrite)
             {
                 try
                 {
                     Console.WriteLine(String.Format("- [{0}]: {1} ({2})"
                                , param.ParameterType.Name, prop.Name,     
                                prop.PropertyType));
                     //prop.SetValue(instance, Convert.ChangeType(d2Reader[test].ToString(), prop.PropertyType), null);
                  }
                  catch
                  { // property not in scope 
                  }
              }
          }

          #endregion                    
     }
     else
     {
          Console.WriteLine(String.Format(" - {0} ({1}, out: {2})",
                  param.Name, 
                  param.ParameterType.FullName,
                  param.ParameterType.IsByRef));
     }
}





Aucun commentaire:

Enregistrer un commentaire