从字符串构建 DoWorkEventHandler

发布于 2024-11-15 21:35:09 字数 653 浏览 7 评论 0原文

我有一个行动列表。

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

这是填充在代码上的。

list.Add(new Action("Name", SomeRandomMethod));
...

当有人从该列表中选择一个操作时,它将执行相应的操作。

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

但我想从数据库定义和构建这个列表。那么,当我从数据库中获取的是带有方法名称的字符串时,应该如何创建带有 DoWorkEventHandler 参数的操作呢?

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.Add(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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧瑾黎汐 2024-11-22 21:35:09

有多种方法可以做到这一点。

您可以声明一个包含允许调用的所有方法名称的enum,然后在启动时使用反射构建一个将enums映射到methodinfo的字典' s。您可以将枚举存储在数据库中。

另一种选择是按如下方式装饰类/方法:

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

查找要调用的方法时,您将从数据库中获取类 ID,然后使用反射来获取具有 [ContainsScriptableMethod] 的所有类具有正确 Id 的属性,然后执行相同的操作来查找方法。

如果只有少数定义的类具有可调用/编写脚本的方法,则您可以只拥有该方法的属性。

示例代码如下:

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

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;
        } 
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文