2009-01-19 32 views
5

Phát biểu sự cố: Triển khai hệ thống trình cắm cho phép các cụm liên kết được ghi đè (tránh khóa tệp). Trong. Net, các assembly cụ thể có thể không được load, chỉ toàn bộ các AppDomain có thể được dỡ bỏ.Làm cách nào để triển khai plugin .net mà không cần sử dụng AppDomains?

Tôi đăng bài này vì khi tôi đang cố giải quyết vấn đề, mọi giải pháp đều đề cập đến việc sử dụng nhiều AppDomain. Nhiều AppDomain rất khó triển khai đúng, ngay cả khi được cấu trúc ở đầu dự án.

Ngoài ra, AppDomains không hoạt động đối với tôi vì tôi cần chuyển Loại trên tên miền làm cài đặt cho hoạt động InvokeWorkflow của Máy chủ giọng nói worfklow. Thật không may, việc gửi một kiểu trên các tên miền khiến cho assembly được đưa vào AppDomain cục bộ.

Ngoài ra, điều này có liên quan đến IIS. IIS có một thiết lập Shadow Copy cho phép một assembly thực thi được ghi đè trong khi nó được nạp vào bộ nhớ. Vấn đề là (ít nhất là dưới XP, không thử nghiệm trên các máy chủ sản xuất 2003) khi bạn lập trình tải một assembly, shadow copy không hoạt động (vì bạn đang nạp DLL, chứ không phải IIS).

Trả lời

8
  1. Kiểm tra xem lắp ráp đã được tải chưa (để tránh rò rỉ bộ nhớ gây ra do tải cùng một cụm lắp ráp một lần nữa).
  2. Nếu thiết bị không được tải, hãy đọc lắp ráp thành một mảng byte. Điều này sẽ ngăn chặn khóa tệp.
  3. Cung cấp các mảng byte như một đối số để Assembly.Load

Các mã sau đây giả sử bạn biết FullName của một assembly.

Assembly assembly = null; 

foreach(Assembly loadedAssembly in AppDomain.CurrentDomain.GetAssemblies()) 
    if (loadedAssembly.FullName == "foobar, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") 
     assembly = loadedAssembly; 

if(assembly == null) 
{ 
    byte[] studybin = System.IO.File.ReadAllBytes(@"C:\pathToAssembly\foobar.dll"); 
    assembly = Assembly.Load(studybin);     
} 

Lưu ý rằng nếu bạn đang cố gắng tìm một hội đồng cụ thể trong thư mục, bạn có thể chạy 'System.Reflection.AssemblyName.GetAssemblyName (path);' để xem liệu FullName có khớp với những gì bạn đang tìm kiếm hay không. 'GetAssemblyName (đường dẫn)' KHÔNG đưa assembly vào AppDomain hiện tại của bạn.

Cũng lưu ý rằng giải pháp này không thích hợp cho các ứng dụng chỉ hiếm khi khởi động lại và các hội đồng thay đổi với tần số cao. Mỗi lần lắp ráp được tải, bộ nhớ của ứng dụng của bạn sẽ tăng lên. Không có phương pháp để dỡ bỏ một hội đồng, do đó tùy chọn duy nhất để thu nhỏ việc sử dụng bộ nhớ là khởi động lại ứng dụng. Tuy nhiên, giới hạn này thường thích hợp hơn với hiệu suất lớn, bộ nhớ và tính phức tạp của mã phức tạp khi sử dụng nhiều miền ứng dụng. Giới hạn này cũng không thể tránh khỏi nếu bạn muốn làm việc với Type s.

+0

Tôi cho rằng điều này có nghĩa là bạn vẫn phải khởi động lại ứng dụng để sử dụng trình cắm mới sau khi đã được thay thế trên đĩa? Tôi đã bị ấn tượng rằng một khi một loại đã được tải, nó không thể thay đổi, ngay cả khi bạn tải lại lắp ráp. –

+3

Bạn có thể sử dụng loại mới cùng một lúc. Bạn không phải là kỹ thuật "nạp lại" lắp ráp. Thay vào đó, bạn đang tải lắp ráp mới cạnh nhau với cái cũ. Nếu các hội đồng thay đổi thường xuyên, cuối cùng bạn sẽ hết bộ nhớ và cần phải khởi động lại ứng dụng. –

2

Nếu bạn muốn cô lập addins của bạn, bạn phải ...

  1. Tạo một kiểu mở rộng MarshallByRefObject mà sẽ tương tác với addin của bạn (cho phép gọi nó FOOMASTER)
  2. Tạo mới appdomain (cho phép gọi nó là addinLand)
  3. Gọi addinLand.CreateInstanceAndUnwrap để tạo một thể hiện của FOOMASTER trong addinLand và nhận được một proxy trong lĩnh vực ứng dụng hiện tại
  4. Nói FOOMASTER để tải addins của bạn

Bây giờ addins của bạn được nạp trong addinLand và bạn có thể tương tác với họ từ tên miền ứng dụng chính của bạn thông qua proxy FOOMASTER của bạn. Khi phần bổ trợ của bạn bị lỗi, chúng sẽ không gỡ bỏ ứng dụng của bạn.

Quy trình thú vị và hơi khó hiểu của nó. Ban đầu tôi nghĩ ý tưởng là tải các addins của bạn và sau đó đưa chúng vào miền ứng dụng hiện tại như các proxy trong suốt, nhưng thiết kế tốt nhất là để các addins như các đối tượng đơn giản tương tác với các kiểu phức tạp hơn mà bạn tạo ra (FOOMASTER). MarshallByRefObject, được tải trong miền ứng dụng addinLand và các proxy trong suốt mà bạn tương tác với.

Chương 21 và 22 của CLR Qua C# rất hữu ích trong việc hiểu quy trình.

2

Nếu bạn quan tâm đến một phương pháp nghiêm túc để xây dựng hệ thống với kiến ​​trúc plugin, bạn có thể muốn xem MAF (Khung công tác được quản lý), hiện là một phần của Khuôn khổ .NET, cụ thể là Hệ thống. AddIn không gian tên.

Nó sẽ giúp bạn quản lý cách ly và phiên bản bổ sung, thậm chí khả năng tương thích ngược với hợp đồng.

Có một chút đường cong học tập ở đây, vì vậy đây có thể không chính xác những gì bạn đang tìm kiếm.

http://msdn.microsoft.com/en-us/library/bb384200.aspx

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