开发者

Build a DoWorkEventHandler from a string

开发者 https://www.devze.com 2023-03-13 16:21 出处:网络
I have a list of Actions. public class Action { public string Name { get; set; } public DoWorkEventHandler DoWork{ get; set; }

I have a list of Actions.

public class Action {
    public string Name { get; set; }
    public DoWorkEventHandler DoWork{ get; set; }
}

That is populated on code.

list.Ad开发者_如何学JAVAd(new Action("Name", SomeRandomMethod));
...

When someone chooses an Action from that list it will execute the respective action.

private void ListBoxSelectionChanged(object sender, SelectionChangedEventArgs e) {
    var item = (Action) ListBoxScripts.SelectedItem;
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += item.DoWork;
    worker.RunWorkerAsync();
}

But I want to define and build this list from a DB. So How should I create an Action with a DoWorkEventHandler parameter when what I got from the DB is a string with the method name?


There are a number of ways you could do this.

You could declare an enum containing all method names that are allowed to be called, then on startup using reflection build a dictionary mapping enums to methodinfo's. You'd store the enum in the database.

Another option would be to decorate classes/methods as below:

[ContainsScriptableMethod("MyClassIdentifyingName"] // or a number
class MyUserScriptableMethods
{
    [ScriptableMethod("MyMethodIdentifyingName")] // Or just a number as an identifier
    void MyMethod()
    {
        // Do non-malicious stuff.
    }
}

When looking up a method to call you'd get a class ID from the database, then use reflection to get all classes that have the [ContainsScriptableMethod] attribute with the correct Id, then do the same for looking up the method.

You could just have an attribute for the method if there's only a few defined classes that have methods that can be called/scripted.

Example code below:

// Enumerate all classes with the ContainsScriptableMethod like so
foreach(var ClassWithAttribute in GetTypesWithAttribute(Assembly.GetExecutingAssembly(), typeof(ContainsScriptableMethodAttribute))
{
    // Loop through each method in the class with the attribute
    foreach(var MethodWithAttribute in GetMethodsWithAttribute(ClassWithAttribute, ScriptableMethodAttribute))
    {
        // You now have information about a method that can be called. Use Attribute.GetCustomAttribute to get the ID of this method, then add it to a dictionary, or invoke it directly.
    }
}

static IEnumerable<Type> GetTypesWithAttribute(Assembly assembly, Type AttributeType)
{
    foreach(Type type in assembly.GetTypes())
    {
        if (type.GetCustomAttributes(AttributeType, true).Length > 0)
        {
            yield return type;
        }
    }
} 

static IEnumerable<MethodInfo> GetMethodsWithAttribute(Type ClassType, Type AttributeType)
{
    foreach(var Method in ClassType.GetMethods())
    {
        if (Attribute.GetCustomAttribute(AttributeType) != null)
        {
            yield Method;
        } 
   }
}
0

精彩评论

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