2012-01-21 19 views
6

Để thử nghiệm tôi đã sử dụng một ứng dụng Console với mã nguồn sau đây:Compile trong thời gian chạy (thế hệ dll) bên trong một ứng dụng 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); 
    } 

Với mã này bên trong một ứng dụng giao diện điều khiển tôi có thể làm cho nó hoạt động và AutoGen Tệp .dll được tạo, từ thời điểm đó tôi có thể lập hóa đơn các phương thức của máy tính.

Sự cố của tôi xảy ra khi tôi làm cùng mã nhưng bên trong ứng dụng MVC 3. Tôi có thể bắt ngoại lệ nếu tôi sử dụng biến sau.

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

'compileResult1.CompiledAssembly' ném một ngoại lệ kiểu System.IO.FileNotFoundException'

Tôi cũng cố gắng sử dụng Server.MapPath ("~/bin /") nói với thư mục đầu ra .

Ai đó có thể giúp tôi ở đây? Cảm ơn bạn

UPDATE 1 Tôi đưa điều khoản thư mục để người dùng đúng để viết, vì vậy đó không phải là vấn đề.

+1

Còn tham chiếu thì sao? Tất cả họ có ở đó không? –

+0

Bạn đang đề cập đến cái nào? – Dryadwoods

+0

Biên dịch nó 'InMemory'. – leppie

Trả lời

0

Tôi cũng đã cố gắng sử dụng Server.MapPath ("~/bin /") để thông báo cho thư mục đầu ra.

Làm thế nào Chính xác thì bạn cố gắng vì các công việc sau cho tôi:

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

Và đây là mã kiểm tra đầy đủ của tôi:

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

Chỉ muốn chỉ ra rằng trước khi làm tôi này hy vọng bạn hoàn toàn nhận thức được rằng bằng cách viết thư cho thư mục bin, về cơ bản bạn đang giết và bỏ AppDomain của ứng dụng web mỗi lần bạn chạy mã này. Vì vậy, nếu bạn thực sự muốn thực thi một số mã động bạn có thể xem xét biên dịch assembly trong bộ nhớ.

+0

Cảm ơn câu trả lời, về việc ghi vào thư mục bin: Tôi thực sự cần nó, bởi vì tôi đang tạo trong thời gian chạy một số dịch vụ web. Tôi có một khu vực mà người dùng có thể thêm các đối tượng động và tự động tôi cần cung cấp một dịch vụ web cho nó. Vì vậy, cho rằng tôi thực sự cần phải có tất cả các tập tin trên đĩa. – Dryadwoods

+0

@emanyalpsid, OK, tôi chỉ muốn chỉ ra để ghi lại. Vì việc khởi động lại miền ứng dụng có lẽ không phải là thứ mà hầu hết mọi người muốn xem. –

+0

Vâng, đó là một điểm quan trọng. Bạn có biết một số cách khác cho tôi để tạo ra các dịch vụ web (tôi cần 2 tập tin: * .asmx trên root và * .dll) Tôi nghĩ rằng tôi cần phải đặt * .dll trong thư mục bin, đây là lựa chọn duy nhất ? – Dryadwoods

Các vấn đề liên quan