views:

42

answers:

2

ok heres the deal, im grabbing all the methods from a webservice and providing a way to test them. so far we are displaying their methods and some of the methods only deal with ints and strings. that part is taken care of. (we can invoke methods correctly and parse results)

the problem is that some of these parameters needed for the method call are classes that are defined somewhere in the webservice and we have no way of knowing what they are. the only thing we do know is that those classes are composed of only strings and ints. (yay)

lets say im looking to make an instance that is of type "Agent" at runtime.

so far i have access to the service that was loaded at runtime that is in a different class. this works just fine

Proxy class:

.
.
.
CompilerParameters parms = new CompilerParameters(assemblyReferences);      
CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1);
// Checks For Errors
// add the web service method to our list of methods to test
//--------------------------------the following variables are class level ---------------------------
object service = results.CompiledAssembly.CreateInstance(serviceName);
Type types = service.GetType();
List<ConstructorInfo> listConstructors = (service as Types).GetType().GetConstructors().ToList();
List<MethodInfo> listMethods = types.GetMethods().ToList();

listMethods.Where(mi => mi.GetCustomAttributes(false).
    Where(at => at.GetType() == typeof(SoapDocumentMethodAttribute)).
    Count() > 0).ToList().ForEach(methodsInfo =>{
           //methods to test is a list of a wrapper class for methodInfos
            MethodsToTest.Add(new MethodTest(methodsInfo));
        });

now, in a different class im workin in. im trying to get an object of the type we need by invoking the method:

i am tryin to make an instance of this "Agent" class

private void populateParameterListView(){
            if (funcLBox.SelectedItem != null)
            {
                resultTBlock.Text = String.Empty; //our textbox
                paramLView.Items.Clear();
                ParameterUserInput pui = null; //a wrapper class for parameterinfo
                Proxy.MethodsToTest[index].info.ToList().ForEach(param =>
                {
                pui = new ParameterUserInput(param);
                paramLView.Items.Add(pui);
                //this will check if it is a system type or a custom type
                if (!pui.ParameterType.IsSealed) 
                { 
                   // this is where we want to be. nevermind the code above this
                   //temp in this case is "Agent"
                   string temp = Proxy.MethodsToTest[index].info.GetValue(0).ToString().Split(' ')[0];

                   MemberInfo[] mia = Proxy.types.GetMember(temp);
                   //get an object of the type we need by invoking the method
                }
            });

    }

as of now its trying to search for the members through the 'types' declared in the proxy by doing a get member on it. problem is that im pretty sure im still lookin in the wrong place for those members. can anyone see what im doing wrong? i know it has something to do with what im actually iterating over

A: 

OK, this might be a stretch, but Json for .Net libraries (json.codeplex.com) will let you construct object from any class.

For example (from their documentation)

Product product = new Product();

product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string output = JsonConvert.SerializeObject(product);

//{
//  "Name": "Apple",
//  "Expiry": "\/Date(1230375600000+1300)\/",
//  "Price": 3.99,
//  "Sizes": [
//    "Small",
//    "Medium",
//    "Large"
//  ]
//}

Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);

This will handle your ints and string easily.

The only issue is getting JsonConvert.DeserializeObject<T>(), which you can easily do with your reflection skills.

Edit: Here are the required reflection skills.

object ParseUserInput(string jsonInput)
{
  Type type = <get type instance somehow>

  var json = typeof(JsonConvert);
  var generic = json.GetMethods().Where(m => 
       m.Name == "DeserializeObject" &&
       m.GetParemeters().Count == 1).Single();
  var method = generic.MakeGenericMethod(type);

  return method.Invoke(null, jsonInput);
}
sukru
nice try, but im already taking care of ints and srings. im just not showing it. im trying to find the parameters to create the object that will be used as a parameter for the invocation of another method
Sotelo
Yes, this is exactly what you want. The DeserializeObject method allows you construct type of any class (parameters in your case) with little as information as possible. You just need to generate a JSON representation from the user input.
sukru
A: 

what i did was take the compiler results and try to look for the type there. i made the compiler results a class level variable that i reused later on.

CompilerResults = provider1.CompileAssemblyFromDom(parms, unit1);

i then accessed it and grabed the type of the class that i was looking for

CompilerResults.CompiledAssembly.GetType(temp)

in this case temp is the name of the custom class that i was looking for in the webservice

after you get the type you can grab the constructors, properties and method infos

Sotelo