Создайте DoWorkEventHandler из строки - PullRequest
1 голос
/ 16 июня 2011

У меня есть список действий.

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

Но я хочу определить и построить этот список из БД.Итак, как мне создать Action с параметром DoWorkEventHandler, если я получил из БД строку с именем метода?

1 Ответ

2 голосов
/ 16 июня 2011

Есть несколько способов сделать это.

Вы можете объявить enum, содержащий все имена методов, которые можно вызывать, а затем при запуске с помощью отражения построить словарное отображение enumsдо methodinfo х.Вы бы сохранили перечисление в базе данных.

Другой вариант - декорировать классы / методы, как показано ниже:

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

При поиске метода для вызова вы получите классИдентификатор из базы данных, затем используйте отражение, чтобы получить все классы, которые имеют атрибут [ContainsScriptableMethod] с правильным идентификатором, затем выполните то же самое для поиска метода.

Вы можете просто иметь атрибут для метода, еслиесть только несколько определенных классов, у которых есть методы, которые можно вызывать / создавать сценарии.

Пример кода ниже:

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