开发者

how to make an instance of an unknown class to use as a parameter for a method invocation using reflection?

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.E开发者_如何学Cmpty; //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


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);
}


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜