Компиляция во время выполнения (генерация dll) внутри приложения MVC 3 - PullRequest
6 голосов
/ 21 января 2012

Для тестирования я использовал консольное приложение со следующим исходным кодом:

    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 ("~ / bin /") для указания выходного каталога.

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

ОБНОВЛЕНИЕ 1 Я дал права доступа к папке нужному пользователю для записи, так что это не проблема.

1 Ответ

0 голосов
/ 21 января 2012

Я также пытался использовать 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 вашего веб-приложения каждый раз, когда вы запускаете этот код.Поэтому, если вы действительно хотите выполнить какой-то динамический код, вы можете скомпилировать сборку в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...