2009-11-10 12 views
5

Mam prostą aplikację .NET, która działa jako usługa systemu Windows. powiedzieć, że ma jedną klasęObiekty skryptowe .NET

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

Chcę utworzyć aplikację konsoli, w którym chciałbym wpisać prosty czytelny dla człowieka nie komend jak

run left 
walk right 

Całkiem podobnie jak to zrobić w konsoli Windows. Zastanawiam się, jaki jest najlepszy sposób wdrożenia tego mapowania. Prostą metodą jest oczywiście tworzenie własnego parsera strun z wieloma instrukcjami przełączania, ale myślę, że jeśli istnieje lepsza i szybsza metoda.

Odpowiedz

3

To może być zbyt wiele dla swoich potrzeb, ale myślę, że silny i elastyczny sposób do zrobienia byłoby stworzenie kilka meta-danych atrybutów do dekorowania klas może chcesz zadzwonić ze swojej skorupy, coś jak:

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

Następnie podczas uruchamiania twojej powłoki, należy załadować zespoły poprzez refleksję i szukać typów oznaczonych ScriptableClass atrybutu. Dla każdego z nich sprawdza się ich publiczne metody wyszukiwania dla tych, które są oznaczone atrybutem ScriptableMethod i można zbudować słownik klas i ich skryptowalnych metod (wraz z informacjami o parametrach). W poprzednim przykładzie miałbyś polecenie "MyClass.Run", które możesz wykonać z powłoki. Po otrzymaniu, twój silnik skryptowy utworzy/przeszuka instancję klasy i wykona metodę.

Zaletą tej metody jest to, że nie trzeba modyfikować silnika skryptów za każdym razem, gdy dodaje się nowe klasy lub modyfikuje metody.

+0

+1, najlepsze rozwiązanie problemu. Klasy atrybutów i kod odbicia prawdopodobnie nie zajmują nawet więcej niż 20 linii. – erikkallen

1

Prawdopodobnie opcja PowerShell CommandLet byłaby opcją, chociaż ograniczyłoby to użytkownika lub użytkowników do PowerShell (który jest lepszym IMO powłoki).

2

Masz dwie możliwości:

  1. użyć refleksji, aby znaleźć metodę klasy z approrpiate nazwy i powołując go.

  2. Użyj the command pattern, gdzie każdy obiekt polecenia ma nazwę i metodę Run(). Możesz łatwo znaleźć żądane polecenie po nazwie, a następnie je uruchomić.

UPDATE: Aggreed istnieją więcej niż dwie opcje (patrz odpowiedź Guffa za). Ale te dwa to te, które czynią kod wyraźniejszym IMHO.

2

Niezupełnie. Istnieją inne metody, ale jeśli są one lepsze, to głównie kwestia gustu, a do identyfikacji napisu nie można zrobić go znacznie szybciej niż przełącznik.

Jeśli wszystkie metody mają takie same parametry, można ustawić słownik ciągów i delegatów.
Przykład:

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?'); 
}