2008-10-03 24 views
6

Tôi đang cố gắng tải các hội đồng trong một miền ứng dụng riêng biệt, nhưng đang chạy vào một vấn đề rất lạ. Dưới đây là một số mã:Tải tập hợp vào AppDomain riêng biệt, nhận InvalidCastException

public static void LoadAssembly(string assemblyPath) 
    { 

     string pathToDll = Assembly.GetCallingAssembly().CodeBase; 
     AppDomainSetup domainSetup = new AppDomainSetup 
     { 
      PrivateBinPath = pathToDll 
     }; 

     AppDomain newDomain = AppDomain.CreateDomain("AssemblyLoader",null,domainSetup); 


     AssemblyLoader loader = (AssemblyLoader)newDomain.CreateInstanceFromAndUnwrap(
      pathToDll, 
      typeof(AssemblyLoader).FullName); 

    } 

AssemblyLoader là một lớp trong cùng một assembly như thế này, và nó được thừa hưởng từ MarshalByRef, tuy nhiên vì một lý do kỳ lạ, tôi nhận được một ngoại lệ cast mỗi khi tôi cố gắng chạy này. Tôi thậm chí còn hardcoded đường dẫn đến DLL thay vì sử dụng GetCallingAssembly() CodeBase nhưng tôi tiếp tục nhận được ngoại lệ này.

Tôi hiểu khó trả lời câu hỏi như thế này mà không thực sự nhìn thấy và có thêm thông tin, nhưng có thể ai đó đã gặp phải tình huống tương tự và biết "gotchas" phổ biến và những gì tôi nên tìm.

EDIT: Lý do tôi không muốn tải trực tiếp là vì đây chỉ là một phần của mã. Mục tiêu cuối cùng là lớp này sẽ có một phương thức nạp assembly, nhận GUID của họ và một số thông tin khác về chúng và lưu trữ chúng trong một cơ sở dữ liệu cho một dự án mà tôi đang làm việc. Do đó, nếu tôi tải bản lắp ráp này trong miền ứng dụng riêng biệt, tôi có thể tải những người khác ở đó và sau đó tải miền ứng dụng xuống. Không có điểm trong việc có tất cả các hội đồng này được tải trong suốt thời gian của ứng dụng, nếu tôi chỉ cần dữ liệu đó.

+0

Nếu lớp AssemblyLoader nằm trong cùng một assembly như thế này, tại sao bạn lại cố tải nó từ newDomain? Tại sao không chỉ tạo ra nó trực tiếp? –

+1

Đó là cách tải gián tiếp các plugin. Nếu phiên bản trình tải ở trong miền ứng dụng chính, bạn tạo phiên bản trong miền ứng dụng nước ngoài và yêu cầu tải phiên bản mà bạn quan tâm. Điều này ngăn các plugin của bạn không cần biết liệu họ có thể được xử lý bởi một miền ứng dụng riêng biệt. (tức là lấy từ MarshalByRefObject) Điều này giúp các quyết định thiết kế linh hoạt (ví dụ: Tạo lớp cơ sở trình cắm thêm cung cấp tất cả chức năng được chia sẻ cho các plugin.) –

Trả lời

0

Tôi không tin rằng cấu hình PrivateBinPath là cần thiết, ngoài ra bạn không cần phải sử dụng đường dẫn đến DLL, mà là tên đầy đủ của hội đủ điều kiện cho tham số đầu tiên; thử:

AssemblyLoader loader = (AssemblyLoader)newDomain.CreateInstanceFromAndUnwrap(
     typeof(AssemblyLoader).Assembly.FullName, 
     typeof(AssemblyLoader).FullName); 
+1

Câu trả lời sai. Tham số đầu tiên của CreateInstanceFromAndUnwrap() là một đường dẫn và tên tệp, không phải là một tên assembly.CreateInstanceAndUnwrap(), tuy nhiên, là một tên lắp ráp, nhưng điều đó không giúp người hỏi bởi vì nó sẽ chỉ giải quyết cho cùng một đường dẫn và tên tập tin. – Timwi

+0

http://msdn.microsoft.com/en-us/library/y7h7t2a2.aspx – TheXenocide

2

(EDIT: sau khi đọc ngoại lệ nhất định, thay đổi câu trả lời hoàn toàn)

Có vẻ vấn đề là cuộc gọi CreateInstanceFromAndUnwrap, trong đó sử dụng ngữ nghĩa LoadFrom của 'pathToDll'. Suzanne Cook detailed the possible sticking point trên blog của mình, nơi AppDomain ban đầu của bạn cố gắng gọi Load ("SomeAssembly, [...]") như trái ngược với LoadFrom ("pathToDll") khi cố gắng giải quyết các loại trong câu hỏi.

Lời khuyên của cô là móc sự kiện AssemblyResolve trên miền hiện tại để thực hiện LoadFrom chính xác để nhận loại. Một chút googling targetted mang lên a possible solution to the problem dựa trên gợi ý của Suzanne.

+0

Không, dưới đây là nội dung: Không thể truyền proxy trong suốt để nhập 'CompanyNamespaceTakenOut.AssemblyLoader – BFree

+0

Cập nhật để phản ánh điều đó. – user7116

0

Check-out this article.

Sử dụng mã trong bài viết đó tôi nhận được một đối tượng ứng dụng tên miền chéo. Tôi tóm tắt mọi thứ một chút với generics và có ba hội đồng. (tức là 1 định nghĩa giao diện, 1 xác định việc triển khai plugin và chương trình chính cho biết những gì cần tải chung.) Mã bài viết gốc rất dễ làm theo.

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