2010-01-13 8 views
9

Gần đây tôi đã mua cuốn sách của Ayende Building DSLs in Boo (mua nó, đọc nó, nó thật tuyệt) nhưng tôi sẽ gặp phải vấn đề triển khai và tôi muốn xem mã được tạo ra trông như thế nào. Tôi thường sẽ sử dụng phản xạ để xem mã nhưng trong trường hợp này các hội đồng là năng động và chỉ trong bộ nhớ. Có cách nào để lưu hội đồng năng động vào đĩa để tôi có thể phản ánh chúng?Có thể lưu một cụm động vào đĩa không?

EDIT/trả lời của tôi:

Wow, phải mất một thời gian để trở lại thế này. Thật không may tôi đã để lại một chút quan trọng từ câu hỏi ban đầu.

Quan trọng Bit: Tôi đang sử dụng Ayende's RhinoDSL library như anh ta đề xuất trong sách. Tôi có quyền truy cập vào trình biên dịch boo trong lớp con của tôi về DslEngine mà trông như thế này:

public class JobEngine : DslEngine 
{ 
    protected override void CustomizeCompiler(Boo.Lang.Compiler.BooCompiler compiler, Boo.Lang.Compiler.CompilerPipeline pipeline, string[] urls) 
    { 
     pipeline.Insert(1, new ImplicitBaseClassCompilerStep(typeof (JobBase), "Prepare", "JobLanguage", "log4net", "Quartz")); 
    } 
} 

Để thay đổi nhất và nhận được những gì tôi muốn tôi cần phải thêm một dòng ...

public class JobEngine : DslEngine 
{ 
    protected override void CustomizeCompiler(Boo.Lang.Compiler.BooCompiler compiler, Boo.Lang.Compiler.CompilerPipeline pipeline, string[] urls) 
    { 
     compiler.Parameters.GenerateInMemory = false; // <--- This one. 
     pipeline.Insert(1, new ImplicitBaseClassCompilerStep(typeof (JobBase), "Prepare", "JobLanguage", "log4net", "Quartz")); 
    } 
} 

này gây ra trình biên dịch để kết xuất assembly vào thư mục ~ \ LocalSettings \ Temp của tôi và sau đó tôi có thể phản ánh nó. Điều quan trọng cần lưu ý là việc thay đổi đó gây ra phần còn lại của chương trình để phá vỡ (RhinoDSL không thể tìm thấy các hội đồng trong bộ nhớ vì tôi xuất chúng ra đĩa), vì vậy điều này chỉ hữu ích như một công cụ gỡ lỗi.

+0

Sử dụng serialization đối tượng XML?!. – serhio

+0

bạn có tạo các assembly đó thông qua CodeDom không? –

Trả lời

4

Tra cứu nơi BooCompiler được khởi tạo, thay đổi đường ống từ CompileToMemory để CompileToFile

+0

Đây là những gì cuối cùng đã dẫn tôi đến câu trả lời tôi cần để 1 chấp nhận cho bạn thưa ông. –

4

Có, lớp AssemblyBuilder có phương thức Save cho mục đích này. Bạn cần phải sử dụng chế độ thích hợp cho điều này, rất có thể là RunAndSave:

AssemblyBuilder builder = 
    AppDomain.CurrentDomain.DefineDynamicAssembly(
     name, AssemblyBuilderAccess.RunAndSave); 
// build assembly 
builder.Save(path); 
+0

Việc lắp ráp đã được xây dựng cho tôi trong bộ nhớ của Boo Compiler. Vì vậy, tôi không có quyền truy cập vào trình tạo ... –

+0

Đó là một hội đồng năng động và nếu nó chưa được lưu và tải từ đĩa, nên truyền tới 'AssemblyBuilder' trong trường hợp đó. –

+1

@David M: Hmm ... khi tôi truyền và nhấn phương thức lưu, tôi nhận được một InvalidOperationException nói rằng nó đã được lưu. –

0

Nếu bạn có thể nhận được Assembly khi chạy.

ví dụ:

Assembly assembly = typeof(YourDynamicType).Assembly; 

Sau đó bạn có thể cast lắp ráp này vào AssemblyBuilder và gọi phương thức Save.

AssemblyBuilder assemblyBuilder = (AssemblyBuilder)assembly; 
assemblyBuilder.Save(yourPath); 
+1

Trên thực tế các tác phẩm diễn viên, nhưng khi tôi chạy phương pháp lưu nó chết nói rằng hội đồng đã được lưu ... –

0

Có thể có một cách dễ dàng hơn để làm điều đó, nhưng nếu bạn không nhớ sử dụng WinDbg bạn có thể lưu bất kỳ nạp assembly quản lý từ bộ nhớ (WinDbg sử dụng các mô-đun hạn, nhưng nó hoạt động cho hội đồng quản lý cũng).

Sử dụng lệnh !savemodule có địa chỉ của hội đồng. Nếu bạn không có địa chỉ, hãy sử dụng lệnh lm vm có tên mô-đun. Sau đó bạn nhận được một hội đồng DLL thường xuyên, mà bạn có thể kiểm tra trong Reflector.

Tất nhiên bạn cũng có thể chỉ xem mã IL trong bộ nhớ.