2012-01-21 7 views
6

Para las pruebas he usado una aplicación de consola con el siguiente código:de compilación en tiempo de ejecución (generación DLL) dentro de una aplicación MVC 3

public string CODEInString = @"namespace MyNamespace.Generator 
            { 
             public class Calculator 
             { 
              public int Sum(int a, int b) 
              { 
               return a + b; 
              } 
             } 
            }"; 

    public void Create() 
    { 
     var provider = new CSharpCodeProvider(); 
     var cp = new CompilerParameters 
        { 
         GenerateInMemory = false, 
         OutputAssembly = "AutoGen.dll" 
        }; 
     provider.CompileAssemblyFromSource(cp, CODEInString); 
    } 

Con este código dentro de una aplicación de consola que puede hacer que funcione y la AutoGen Se crea el archivo .dll, desde ese punto puedo invocar los métodos de la calculadora.

Mi problema ocurre cuando hago el mismo código pero dentro de una aplicación MVC 3. Puedo atrapar la excepción si uso la siguiente variable.

var compileResult1 = provider.CompileAssemblyFromSource(cp, CODEInString); 

'compileResult1.CompiledAssembly' produjo una excepción de tipo System.IO.FileNotFoundException'

También probé a usar Server.MapPath ("~/bin /") para decirle al directorio de salida .

¿Alguien podría ayudarme aquí? Gracias

ACTUALIZA 1 di permisos de carpeta para el usuario correcto con el fin de escribir, por lo que no es el problema.

+1

¿Qué le parece las referencias? ¿Están todos allí? –

+0

¿A cuáles te refieres? – Dryadwoods

+0

Compilarlo 'InMemory'. – leppie

Respuesta

0

También intenté usar Server.MapPath ("~/bin /") para indicar el directorio de salida.

¿Cómo fue exactamente lo que intenta que debido a las siguientes obras para mí:

var cp = new CompilerParameters 
{ 
    GenerateInMemory = false, 
    OutputAssembly = Server.MapPath("~/bin/AutoGen.dll") 
}; 

Y aquí está mi pleno código de prueba:

public ActionResult Index() 
{ 
    var code = 
    @" 
     namespace MyNamespace.Generator 
     { 
      public class Calculator 
      { 
       public int Sum(int a, int b) 
       { 
        return a + b; 
       } 
      } 
     } 
    "; 
    var provider = new CSharpCodeProvider(); 
    var cp = new CompilerParameters 
    { 
     GenerateInMemory = false, 
     OutputAssembly = Server.MapPath("~/bin/AutoGen.dll") 
    }; 
    var cr = provider.CompileAssemblyFromSource(cp, code); 

    var calcType = cr.CompiledAssembly.GetType("MyNamespace.Generator.Calculator"); 
    var calc = Activator.CreateInstance(calcType); 
    var result = (int)calcType.InvokeMember("Sum", BindingFlags.InvokeMethod, null, calc, new object[] { 1, 2 }); 

    return Content("the result is " + result); 
} 

Sólo quería señalar que antes de hacer esto me Espero que sepa que al escribir en la carpeta bin básicamente está matando y descargando el AppDomain de su aplicación web cada vez que ejecuta este código. Entonces, si realmente desea ejecutar algún código dinámico, podría considerar compilar el ensamblaje en la memoria.

+0

Gracias por la respuesta, sobre la escritura en el directorio bin: Realmente lo necesito, porque estoy creando durante el tiempo de ejecución algunos servicios web. Tengo un área donde el usuario puede agregar objetos dinámicos y automáticamente necesito brindarle un servicio web. Entonces, para eso realmente necesito tener todos los archivos en el disco. – Dryadwoods

+0

@emanyalpsid, OK, solo quería señalarlo para el registro. Debido a que reiniciar el dominio de la aplicación probablemente no es algo que la mayoría de la gente le gustaría ver. –

+0

Sí, ese es un punto importante. ¿Sabrías de alguna otra manera para mí crear los servicios web (necesito 2 archivos: * .asmx en la raíz y * .dll) Creo que tengo que poner * .dll en la carpeta bin, esta es la única opción ? – Dryadwoods

Cuestiones relacionadas