2012-07-31 13 views
5

¿Hay alguna forma de cargar un archivo .txt como clase, de lo que mi programa principal puede llamar funciones? Básicamente estoy tratando de agregar soporte de mod a mi aplicación simple, donde el usuario puede seleccionar opciones de cada archivo. El archivo sigue un formato similar (pero no el mismo), con un conjunto de vacíos (funciones) que se invocan en el programa principal.C# - Cargar un archivo de texto como clase

¿Cómo puedo hacer esto? ¿Es eso posible (probablemente no, respondiendo mi propia pregunta), considerando que no se compilará junto con el resto del programa?

Gracias!

+0

Es posible, pero tiene que invocar el compilador C# .. no trivial. Es más fácil requerir que sus mods se compilen en dlls, que luego puede cargar y llamar con reflexión. – Blorgbeard

+0

Probablemente tenga que analizar el uso de Roslyn – Prescott

Respuesta

6

Verme respuesta a esta pregunta: Compile a C# Array at runtime and use it in code?

Esencialmente, usted quiere tirar de su archivo de texto en el CodeDom y compilarlo. Después de eso, probablemente sería útil crear algunos métodos dinámicos como ayudantes de ejecución.

  • Recibe el archivo subido
  • a cabo cualquiera de validación necesarios en el archivo
  • Leer el archivo como una cadena en el CodeDom
  • acuerdo con cualquier error de compilador/estructura
  • Crear métodos de ayuda utilizando la expresión LINQ árboles o métodos dinámicos para que el enlace entre la nueva clase y el código existente se vincule con un objeto compilado (de lo contrario, todos los métodos nuevos deberían invocarse utilizando la reflexión)

var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } }); 
var cp = new CompilerParameters() { 
    GenerateExecutable = false, 
    OutputAssembly = outputAssemblyName, 
    GenerateInMemory = true 
}; 

cp.ReferencedAssemblies.Add("mscorlib.dll"); 
cp.ReferencedAssemblies.Add("System.dll"); 

StringBuilder sb = new StringBuilder(); 

// The string can contain any valid c# code 

sb.Append("namespace Foo{"); 
sb.Append("using System;"); 
sb.Append("public static class MyClass{"); 
sb.Append("}}"); 

// "results" will usually contain very detailed error messages 
var results = csc.CompileAssemblyFromSource(cp, sb.ToString()); 

También, ver este tema: Implementing a scripting language in C#. IronPython con el DLR podría ser adecuado para sus necesidades.

+0

Esa es la cuestión: no necesariamente quiero compilarlo, solo necesito que se ejecute como un script. – Scott

+1

Ya veo. FYI, los guiones también se compilan, sobre la marcha. Dependiendo de sus necesidades de rendimiento, la compilación dinámica puede ser adecuada, aunque la compilación de C# probablemente esté menos optimizada para las operaciones sobre la marcha. –

+0

¡Esto se ve muy bien, lo agregaré! ¡Gracias! – Scott

1

usen una estructura que se encarga de plugins

El Managed Extensibility Framework es justo lo que está buscando

http://mef.codeplex.com/

El Managed Extensibility Framework (MEF) es una capa de composición para .NET que mejora la flexibilidad, facilidad de mantenimiento y capacidad de prueba de aplicaciones grandes. MEF se puede utilizar para la extensión de complementos de terceros, o puede aportar los beneficios de una arquitectura tipo plugin poco compactada a las aplicaciones normales.

El MEF proporciona una arquitectura bien definida para admitir complementos en su aplicación.

texto DLL vs (Source Code)

Se espera que el desarrollador plugin para proporcionar una DLL que contiene el código del plugin. Sin embargo, si es necesario, puede compilar el código fuente en una DLL para ellos usando Roslyn. Tenga en cuenta que si desea admitir la recepción del código fuente del complemento, también deberá brindar asistencia para ayudar al usuario a lidiar con los errores del compilador y depurar el complemento dentro de su marco. Puede ser más inteligente pedirles que proporcionen una DLL.

+1

¿Funcionaría esto con un archivo .txt como clase? Creo que necesitaría básicamente compilarlo – Prescott

+0

@Prescott: actualicé mi respuesta para abordar ese punto. –

+0

¿Alguna actualización sobre esto? –

3

Puede cargar un archivo de texto y luego usar un compilador como servicio (Microsoft's pre-release Roslyn project o Mono.CSharp). Luego puede tomar las salidas compiladas y ejecutarlas en su programa.

Si es posible hacer que su usuario le proporcione un ensamblado compilado en lugar de un archivo fuente sin compilar, debe considerar Managed Extensibility Framework o Mono.Addins.

El segundo enfoque (conjuntos de extensión) me parece mejor por al menos dos razones: 1) su usuario puede usar cualquier entorno de desarrollo que quiera para asegurarse de que su código compila correctamente antes de entregárselo a usted, y 2) tiene menos trabajo que hacer para validar la entrada y manejar fallas.

+0

¡Gracias! Veré a Roslyn, hay algunos comentarios hablando de eso. – Scott

+2

No subestime Mono.CSharp: es un "producto terminado" cuya interfaz puede esperar que no cambie. La interfaz de Roslyn probablemente cambie entre el estado actual de CTP y su RTM final. Una vez que esté más cerca del envío, Roslyn podría ser una opción más apropiada para un proyecto .NET típico, pero recuerde que los ensamblados Mono se ejecutan en el CLR de Microsoft tan bien como cualquier otro ensamblaje. – sblom

Cuestiones relacionadas