2009-11-10 15 views
5

Tengo una aplicación .NET simple que se ejecuta como Servicio de Windows. decir que tiene una ClaseCreación de scripts de objetos .NET

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

Quiero crear una aplicación de consola en la que tendría que escribir comandos legibles por humanos simples como

run left 
walk right 

Más o menos como se hace en la consola de Windows. Me pregunto cuál es la mejor manera de implementar este mapeo. Un método directo es, por supuesto, crear tu propio analizador de cadenas con muchas instrucciones de conmutación, pero creo que si hay un método mejor y más rápido.

Respuesta

3

Esto podría ser demasiado para sus necesidades, pero creo que una manera robusta y flexible para hacerlo sería la creación de un par de meta-datos de atributos para decorar las clases es posible que desee llamar de su concha, algo así como:

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

Luego, durante el inicio de su cáscara, se cargan los ensamblados a través de la reflexión y buscar tipos marcados con el ScriptableClass atributo. Para cada uno de ellos, inspeccione sus métodos públicos buscando aquellos marcados con el atributo ScriptableMethod, y puede construir un diccionario de clases y sus métodos de secuencias de comandos (junto con información sobre los parámetros). Para el ejemplo anterior, tendría un comando 'MyClass.Run' que podría desde el shell. Cuando se recibe, el motor de creación de scripts creará/buscará una instancia de la clase y ejecutará el método.

La ventaja de este método es que no tendrá que modificar su motor de scripts cada vez que agregue nuevas clases o modifique métodos.

+0

+1, la mejor solución al problema. Las clases de atributo y el código de reflexión probablemente ni siquiera tomen más de 20 líneas. – erikkallen

1

Tal vez un PowerShell CommandLet sería una opción, aunque eso los obligaría a usted o a sus usuarios a PowerShell (que es un IMO shell superior).

2

Usted tiene dos opciones aquí:

  1. utilizar la reflexión para encontrar el método de la clase con el nombre approrpiate e invocando la misma.

  2. Use the command pattern, donde cada objeto de comando tendría un nombre y un método Run(). Puede encontrar fácilmente el comando deseado por su nombre, luego ejecútelo.

ACTUALIZACIÓN: aggreed, hay más de dos opciones (véase la respuesta de Guffa). Pero estos dos son los que hacen que el código sea más claro en mi humilde opinión.

2

No realmente. Existen otros métodos, pero si son mejores es principalmente cuestión de gustos, y para identificar una cadena no se puede hacer mucho más rápido que un cambio.

Si todos los métodos tienen los mismos parámetros, puede configurar un diccionario de cadenas y delegados.
Ejemplo:

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