2012-11-18 30 views
5

Tôi đang nhúng một công cụ tập lệnh dựa trên Roslyn vào ứng dụng của tôi và bắt đầu phải đối mặt với một số vấn đề. Khi tải một tài liệu tham khảo vào công cụ của tôi, tôi làm như sauKhông tìm thấy hội đồng lúc chạy khi chạy tập lệnh Roslyn

var engine = new Roslyn.Scripting.CSharp.ScriptEngine(); 
engine.AddReference("MyAssemblyLocation"); 

Câu hỏi:

  1. Nếu MyAssemblyLocation lắp ráp là tham khảo hội khác, làm thế nào để tôi nói với Roslyn để tải chúng mà không làm một engine.AddReference("MyAssemblyLocation");
  2. Ứng dụng máy chủ trong đó kịch bản được cho là đang chạy đã nạp một số assembly mà tôi muốn sử dụng trong kịch bản, có cách nào để Roslyn tự móc vào các dll đã nạp trong bộ nhớ và không nạp các cá thể mới không?
  3. Cuối cùng, có một cách để nói Roslyn đệ quy nạp tất cả phụ thuộc của MyAssemblyLocation

Cảm ơn bạn.

Trả lời

6

1) Câu trả lời ngắn: bạn cần AddReference trên tất cả các hội đồng có loại bạn sẽ sử dụng trong tập lệnh.

Chi tiết: Trình biên dịch C# không đoán vị trí của tệp phụ thuộc. Tệp lắp ráp không chỉ định đường dẫn đầy đủ cho tất cả các phụ thuộc của nó. Nó chỉ chứa tên của họ và nói chung là không đủ cho trình biên dịch để có thể xác định vị trí tập tin lắp ráp.

Chi tiết khác: Có hai loại phụ thuộc. Tôi sẽ gọi chúng là các phụ thuộc thời gian biên dịch (a) và các phụ thuộc thời gian chạy (b).

(a) Giả sử bạn có "lớp công khai A: B {}" trong assembly A.dll, "public class B {}" trong assembly B.dll và script của bạn đang sử dụng A, giả sử bạn tạo mới Ví dụ: "new A()". Trình biên dịch yêu cầu bạn thêm tài liệu tham khảo cho cả A.dll và B.dll trong trường hợp này, vì A xuất phát từ B và trình biên dịch cần phân tích hệ thống phân cấp thừa kế của từng loại bạn sử dụng. Vì vậy, B.dll là một phụ thuộc thời gian biên dịch của kịch bản của bạn - trình biên dịch cần nó để phân tích kịch bản của bạn đúng cách.

(b) Hãy xem xét một ví dụ khác: "public class A {public object M() {return new B();}}" trong A.dll và cùng B.dll như trên. Bây giờ khi biên dịch "mới A(). M()" trình biên dịch không cần biết về B, vì tham chiếu đến B chỉ xảy ra trong phần thân của phương thức M và trình biên dịch không phân tích các phần của các phương thức đã nhập. Trong trường hợp này, nó đủ để thêm một tham chiếu đến A.dll để biên dịch tập lệnh. Khi kịch bản thực thi nó gọi phương thức M. Vào lúc đó CLR nạp assembly B. Điều này phức tạp một chút, vì vậy tôi sẽ bỏ qua chi tiết nhưng trong các kịch bản thông thường chúng ta có thể định vị assembly cho bạn, vì vậy bạn don ' t cần thêm tham chiếu một cách rõ ràng.

2) Tôi khuyên bạn nên sử dụng quá tải của AddReference nhận đối tượng Assembly. Một cái gì đó như: engine.AddReference (typeof (SomeTypeInAssemblyFoo) .Assembly) để tải Foo lắp ráp có chứa loại SomeTypeInAssemblyFoo.

3) Không đơn giản. Bạn có thể liệt kê tất cả các tham chiếu bằng cách sử dụng API Reflection hoặc Roslyn và tải từng tham chiếu.

Hãy đặt câu hỏi thêm nếu giải thích không rõ ràng hoặc bạn muốn biết thêm chi tiết.

+0

Câu trả lời hay, +1! – GETah

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