Создание сценариев .NET-объектов - PullRequest
5 голосов
/ 10 ноября 2009

У меня есть простое приложение .NET, которое работает как служба Windows. Скажем, у него есть один класс

MyClass
{
  Run(Destination d)
  Walk(Destination d)
  Wash(Dishes d)
}

Я хочу создать консольное приложение, в котором я буду вводить простые удобочитаемые команды как

run left
walk right

Почти как в консоли для Windows. Интересно, как лучше всего реализовать это отображение? Прямые методы - это, конечно, создание собственного синтаксического анализатора строк с множеством операторов switch, но я думаю, что есть лучший и более быстрый метод.

Ответы [ 4 ]

3 голосов
/ 10 ноября 2009

Это может быть слишком много для ваших нужд, но я думаю, что надежный и гибкий способ сделать это - создать пару атрибутов метаданных для украшения классов, которые вы, возможно, захотите вызывать из вашей оболочки, что-то вроде:

[ScriptableClass]
public class MyClass
{
     [ScriptableMethod(typeof (Destination),typeof(int))]
     public void Run (Destination f, int distance) {}
}

Затем во время запуска вашей оболочки вы загружаете свои сборки с помощью отражения и ищите типы, отмеченные атрибутом ScriptableClass . Для каждого из них вы проверяете их общедоступные методы на предмет поиска тех, которые помечены атрибутом ScriptableMethod , и вы можете создать словарь классов и их методы для работы с сценариями (вместе с информацией о параметрах). Для предыдущего примера у вас будет команда «MyClass.Run», которую вы можете использовать из оболочки. При получении ваш механизм сценариев создаст / выполнит поиск экземпляра класса и выполнит метод.

Преимущество этого метода заключается в том, что вам не нужно будет изменять ваш движок сценариев каждый раз, когда вы добавляете новые классы или модифицируете методы.

2 голосов
/ 10 ноября 2009

У вас есть два варианта:

  1. Используйте отражение, чтобы найти метод класса с именем approrpiate и вызвать его.

  2. Используйте шаблон команды , где каждый объект команды будет иметь имя и метод Run(). Вы можете легко найти нужную команду по имени, а затем запустить ее.

ОБНОВЛЕНИЕ : Согласен, есть более двух вариантов (см. Ответ Гуффы). Но именно эти два делают код более понятным ИМХО.

2 голосов
/ 10 ноября 2009

Не совсем. Существуют и другие методы, но если они лучше, это в основном дело вкуса, и для идентификации строки вы не можете сделать это намного быстрее, чем переключатель.

Если все методы имеют одинаковые параметры, вы можете настроить словарь строк и делегатов.
Пример:

var methods = new Dictionary<string, Action<int>>();
methods.Add("run", n => MyClass.Run(n));
methods.Add("walk", n => MyClass.Walk(n));
methods.Add("wash", n => MyClass.Wash(n));

string cmd = "run";
int param = 42;
if (methods.ContainsKey(cmd)) {
   methods[cmd](param);
} else {
  Console.WriteLine('Say what, human?');
}
1 голос
/ 10 ноября 2009

Возможно, PowerShell CommandLet подойдет, хотя это ограничит вас или ваших пользователей PowerShell (который является превосходной IMO оболочки).

...