2012-01-21 3 views
6

Для тестирования я использовал консольное приложение со следующим исходным кодом:Compile во время выполнения (DLL поколения) внутри приложения 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); 
    } 

С помощью этого кода внутри консольного приложения я могу заставить его работать и AutoGen .dll создается, с этого момента я могу запросить методы калькулятора.

Моя проблема возникает, когда я делаю тот же код, но внутри приложения MVC 3. Я могу поймать исключение, если я использую следующую переменную.

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

'compileResult1.CompiledAssembly' бросил исключение типа System.IO.FileNotFoundException»

Я также попытался использовать Server.MapPath ("~/бен /") сказать выходной каталог ,

Кто-то может мне помочь? Спасибо

UPDATE 1 Я дал разрешения на папки в правильном пользователем для того, чтобы писать, так что это не проблема.

+1

Как насчет ссылок? Они все там? –

+0

Которые вы имеете в виду? – Dryadwoods

+0

Скомпилируйте его «InMemory». – leppie

ответ

0

Я также попытался использовать Server.MapPath ("~/bin /"), чтобы указать выходной каталог.

Как именно вы пытаетесь что из-за следующие работы для меня:

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

А вот мой полный тестовый код:

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

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

+0

Спасибо за ответ, о написании в каталоге bin: мне это действительно нужно, потому что во время выполнения я создаю несколько веб-сервисов. У меня есть область, где пользователь может добавлять динамические объекты, и автоматически мне нужно предоставить веб-сервис для него. Итак, для этого мне действительно нужно иметь все файлы на диске. – Dryadwoods

+0

@emanyalpsid, ОК, я просто хотел указать на запись. Поскольку перезапуск домена приложения, вероятно, не то, что большинство людей хотели бы видеть. –

+0

Да, это важный момент. Вы знаете какой-нибудь другой способ создания веб-сервисов (мне нужно 2 файла: * .asmx в корне и * .dll). Я думаю, что мне нужно положить * .dll в папку bin, это единственный вариант ? – Dryadwoods

Смежные вопросы