Author Topic: Execute Method from String Name.  (Read 6456 times)

0 Members and 1 Guest are viewing this topic.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Execute Method from String Name.
« on: January 15, 2008, 03:50:01 PM »

Has anyone come across an algorithm  to execute a method in an assembly from it's string Name ?
ie

say the string value is "a_103" ; I want to  execute a_103().

OR

be able to assign a method object/ID to a variable name and execute the Method using the Variable Name ?


regards
kwb



kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Glenn R

  • Guest
Re: Execute Method from String Name.
« Reply #1 on: January 15, 2008, 03:57:53 PM »
Reflection is your friend on this one.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Execute Method from String Name.
« Reply #2 on: January 15, 2008, 04:10:33 PM »

thought it may be :-)
I'll have a play when I get a chance .. haven't delved into reflection programmatically.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MickD

  • King Gator
  • Posts: 3639
  • (x-in)->[process]->(y-out) ... simples!
Re: Execute Method from String Name.
« Reply #3 on: January 15, 2008, 04:14:38 PM »
Apart from reflection, perhaps a map/hash table??
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Glenn R

  • Guest
Re: Execute Method from String Name.
« Reply #4 on: January 15, 2008, 04:54:35 PM »
Apart from reflection, perhaps a map/hash table??

Mick,

How would you call, say, a string from that std::map/hashtable?

Cheers,
Glenn.

MickD

  • King Gator
  • Posts: 3639
  • (x-in)->[process]->(y-out) ... simples!
Re: Execute Method from String Name.
« Reply #5 on: January 15, 2008, 05:10:36 PM »
Was just a thought Glenn but can you assign a delegate to a map/hash table? This way the string would be key and the delegate the value if you like.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Chuck Gabriel

  • Guest
Re: Execute Method from String Name.
« Reply #6 on: January 15, 2008, 06:10:46 PM »
Kinda like an array of function pointers?  Interesting idea.

Glenn R

  • Guest
Re: Execute Method from String Name.
« Reply #7 on: January 15, 2008, 06:18:47 PM »
How would you tell said delegate to 'go do it's funky thang'...???

MickD

  • King Gator
  • Posts: 3639
  • (x-in)->[process]->(y-out) ... simples!
Re: Execute Method from String Name.
« Reply #8 on: January 15, 2008, 06:19:43 PM »
@Chuck

That's how I'd do it with C/C++, you might have to roll your own though, even a simple hand built linked list would work ok and would still be dynamic.
« Last Edit: January 15, 2008, 06:48:06 PM by MickD »
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

MickD

  • King Gator
  • Posts: 3639
  • (x-in)->[process]->(y-out) ... simples!
Re: Execute Method from String Name.
« Reply #9 on: January 15, 2008, 06:23:21 PM »
How would you tell said delegate to 'go do it's funky thang'...???

hmmm, perhaps when you get the value, pass it to a method that looks after that, something like

MethodToInvokeDelegate(GetsStringValue());

Where the method would be something like -

delegate = getDelegateFromHT(strkey);
delegate.Invoke(); //or something like that.

"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8740
  • AKA Daniel
Re: Execute Method from String Name.
« Reply #10 on: January 15, 2008, 07:25:53 PM »
Apart from reflection, perhaps a map/hash table??

Maybe something like what we did here?
http://www.theswamp.org/index.php?topic=18355.msg225522#msg225522

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8740
  • AKA Daniel
Re: Execute Method from String Name.
« Reply #11 on: January 15, 2008, 09:16:53 PM »
or like this  :-o

Code: [Select]
public class Commands : IExtensionApplication
  {
    public static Dictionary<string, MethodInfo> CommandTable = new Dictionary<string, MethodInfo>();

    [CommandMethod("LoadFile")]
    public void LoadFile()
    {
      Editor ed = AcAp.Application.DocumentManager.MdiActiveDocument.Editor;
      PromptResult pr = ed.GetString("Enter FileName");
      string filename = pr.StringResult;
      if (pr.Status == PromptStatus.OK)
      {
        Load(filename);
      }
    }
    [CommandMethod("ListCommands")]
    public static void ListCommands()
    {
      StringBuilder sb = new StringBuilder();
      foreach (var e in CommandTable)
      {
        sb.Append(e.Key);
        sb.Append(" ");
      }
      Editor ed = AcAp.Application.DocumentManager.MdiActiveDocument.Editor;
      ed.WriteMessage(sb.ToString());
    }

    [CommandMethod("ExecCommand")]
    public static void ExecCommand()
    {
      Editor ed = AcAp.Application.DocumentManager.MdiActiveDocument.Editor;
      PromptResult pr = ed.GetString("Enter Command Name");
      if (pr.Status == PromptStatus.OK)
      {
        MethodInfo method = CommandTable[pr.StringResult.ToUpper()] as MethodInfo;

        if (method != null)
        {
          try
          {
            method.Invoke(method, null);
          }
          catch (System.Exception ex)
          {
            ex.ToString();
          }
        }
      }
    }

    public void Initialize()
    {
      System.AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(OnAssemblyLoad);
    }

    public void Terminate()
    {
    }

    void OnAssemblyLoad(Object sender, AssemblyLoadEventArgs e)
    {
      ProcessAssembly(e.LoadedAssembly);
    }

    void Load(String fileName)
    {
      System.Reflection.Assembly.LoadFrom(fileName);
    }

    void ProcessAssembly(Assembly assembly)
    {
      Editor ed = AcAp.Application.DocumentManager.MdiActiveDocument.Editor;

      foreach (Type T in assembly.GetTypes())
      {
        foreach (MethodInfo M in T.GetMethods())
        {
          if (M.IsPublic && M.IsStatic)
          {
            CommandTable.Add(M.Name.ToUpper(), (MethodInfo)M);
          }
        }
      }
    }
  }

In an another assembly

Code: [Select]

public class Class1
  {
    public static void Command1()
    {
      Editor ed = AcAp.Application.DocumentManager.MdiActiveDocument.Editor;
      ed.WriteMessage("From Command1");
    }
    public static void Command2()
    {
      Editor ed = AcAp.Application.DocumentManager.MdiActiveDocument.Editor;
      ed.WriteMessage("From Command2");
    }
  }
« Last Edit: January 15, 2008, 09:31:09 PM by Daniel »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Execute Method from String Name.
« Reply #12 on: January 15, 2008, 10:24:58 PM »
Thanks Dan ;
I'd anticipated that the methods would be in the same assembly, but a different class.
My initial thought was that I may be able to use this functionality in the Method tester I'm putting together in another thread here ... the selected string from a combo box would be 'invoked' ; saving the necessity of writing a unique case statement block for each assembly.

I'll have a good look when the dust settles locally :-)





kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

SomeCallMeDave

  • Guest
Re: Execute Method from String Name.
« Reply #13 on: January 15, 2008, 11:04:20 PM »
Better late than never, as they say.

Not as elegant as Dan's, but here is my take.

 In a simple Windows Form app with one textbox (default name) and 1 button (default name), it will invoke a method in the Form class or in another class

Code: [Select]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string Input = textBox1.Text;
            TestClass testClass = new TestClass();


            Type testClassTypes = testClass.GetType();
            Type thisTypes = this.GetType();

            System.Reflection.MethodInfo[] testClassInfo = testClassTypes.GetMethods();
            System.Reflection.MethodInfo[] thisInfo = thisTypes.GetMethods();

            foreach (MethodInfo newInfo in testClassInfo)
            {
                if (newInfo.Name == Input)
                {
                    string returnedData = (string)newInfo.Invoke(testClass, null);
                    MessageBox.Show(returnedData);
                }
            }
            foreach (MethodInfo newInfo in thisInfo)
            {
                if (newInfo.Name == Input)
                {
                    string returnedData = (string)newInfo.Invoke(this, null);
                    MessageBox.Show(returnedData);
                }
            }

           
        }
        public string Test1()
        {
            return "Test1";

        }

        public string Test2()
        {
            return "Test2";

        }

        public class TestClass
        {
            public string Test1()
            {
                return "Test1 from TestClass1";

            }

            public string Test2()
            {
                return "Test2 from TestClass2";

            }
        }


    }
}




It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8740
  • AKA Daniel
Re: Execute Method from String Name.
« Reply #14 on: January 15, 2008, 11:14:23 PM »
Another way  :-D

Code: [Select]
[assembly: ExtensionApplication(typeof(ExecMethod.Commands))]
[assembly: CommandClass(typeof(ExecMethod.Commands))]

namespace ExecMethod
{
  //
  public delegate void Foo();

  public class Commands : IExtensionApplication
  {
 
    public static Dictionary<string, Delegate> CmdDict = new Dictionary<string, Delegate>();

    [CommandMethod("DOIT")]
    public static void doit()
    {
      CmdDict["w00t"].DynamicInvoke();
      CmdDict["w01t"].DynamicInvoke();
    }

    public void Initialize()
    {
      CmdDict.Add("w00t", new Foo(StuffToExec.command1));
      CmdDict.Add("w01t", new Foo(StuffToExec.command2));
    }

    public void Terminate()
    {
    }

  }
}

another class

Code: [Select]
namespace ExecMethod
{
  public class StuffToExec
  {
    public static void command1()
    {
      Editor ed = AcAp.Application.DocumentManager.MdiActiveDocument.Editor;
      ed.WriteMessage("\nfrom command1()");
    }
    public static void command2()
    {
      Editor ed = AcAp.Application.DocumentManager.MdiActiveDocument.Editor;
      ed.WriteMessage("\nfrom command2()");
    }

  }
}

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8740
  • AKA Daniel
Re: Execute Method from String Name.
« Reply #15 on: January 15, 2008, 11:17:32 PM »
Nice work Dave !!


MickD

  • King Gator
  • Posts: 3639
  • (x-in)->[process]->(y-out) ... simples!
Re: Execute Method from String Name.
« Reply #16 on: January 15, 2008, 11:20:13 PM »
Dictionary, map/hashtable,... whatever :D

Nice one Daniel.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Execute Method from String Name.
« Reply #17 on: January 16, 2008, 12:00:16 AM »
This situation comes into play with a menu,
In vba I had to make a sub for every menu item and when you are dealing with hardware there may be 80 subs that end up calling another function, however I could never figure out how to call a function passing it a string from a menu.
Perhaps the answers in this thread will work for this as well.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Execute Method from String Name.
« Reply #18 on: January 16, 2008, 05:16:14 AM »

Thanks fellas .. that's heaps for me to play with .. when I get some time to spare.

your blood is worth bottling !
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.