Jacques
Jacques

Reputation: 7135

Use reflection to execute a method with parameters raising Exception in GetParameters

I have a console app that I'm testing the basic ability to enter a command such as: Edit

AddUser id=1 name=John surname=Doe

Edit The hypothetical method AddUser could look like this:

public AddUser(int id, string name, string surname
{
    //add code here to add user
}

Here's my code:

protected void Process(string command)
{
    //get the type
    Type type = this.GetType(); 

    //do a split on the command entered
    var commandStructure = command.Split(' ');

    try
    {
        //reassign the command as only the method name
        command = commandStructure[0];

        //remove the command from the structure
        commandStructure = commandStructure.Where(s => s != command).ToArray();

        //get the method
        MethodInfo method = type.GetMethod(command, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

        //if the method was found
        if (method != null)
        {
            Dictionary<string, ParameterInfo> dictionary = new Dictionary<string, ParameterInfo>();

            //**Here's where I get the exception that the key was not found in the** 
            //**dictionary**
            var parameters = method.GetParameters()
                .Select(p => dictionary[p.Name])
                .ToArray();

            //add code here to apply values found in the command to parameters found
            //in the command
            //...

            method.Invoke(this, parameters);
        }
        else
        {
            throw new Exception("No such command exists man! Try again.");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        Prompt();
        Wait();
    }
}

I was trying to understand the stack answer provided by Jon Skeet but couldn't get it working. I assume this is because I'm misunderstanding the discussion or use of his example.

So my question is: How do I get a list of parameters populated with the values entered by the user in the command prompt? The method part works, I'm successfully running methods that have no parameters, but when I added the code to handle parameters it got complicated.

Upvotes: 0

Views: 217

Answers (2)

jcharlesworthuk
jcharlesworthuk

Reputation: 1079

I think what you are trying to do is get a dictionary of the parameters that you can use, if your initial string contained a comma seperated list of parameters you could get it by doing something like this

Dictionary<string, string> dictionary = commandStructure[1].Split(',')
.ToDictionary(x => x.Split('=').First(), x => x.Split('=').Last());

But note the dictionary's value here is of type "string", because the inputs are coming in as string.

This would take an input such as

"GetUser id=1,name=tom,path=C"

And convert it to a dictionary with the keys "id", "name" and "path", and the values as "1", "tom" and "C". Then when you do

var parameters = method.GetParameters()
            .Select(p => dictionary[p.Name])
            .ToArray();

You will get an array of the values needed, which can be passed to method.Invoke();

Alternatively: If your original parameter list was seperated by spaces then your original "Split" statement would have split these, so now your commandStructure array would contain the method name and the parameters. The dictionary method would become:

Dictionary<string, string> dictionary = commandStructure.Skip(1)
.ToDictionary(x => x.Split('=').First(), x => x.Split('=').Last());

Upvotes: 1

Konrad Kokosa
Konrad Kokosa

Reputation: 16898

You probably want this:

dictionary = method.GetParameters()
                   .ToDictionary(x => x.Name, x => x);

in place of exception. But not sure why do you need it.

Upvotes: 0

Related Questions