2009-07-27 25 views
6

Tôi đã cố gắng giải quyết vấn đề này trong vài tuần qua và chưa tìm được giải pháp tốt; hy vọng tôi có thể nhận được câu trả lời ở đây.Đang tải 2 phiên bản lắp ráp tại thời điểm chạy

Tôi có hai hội đồng (ZA & ZB), cả hai đều trỏ đến một dự án/dll chung (ZC) nhưng có thể trên một phiên bản khác (tức là cùng tên dll, cùng một không gian tên, một số lớp có thể khác nhau) . Mỗi bản lắp ráp hoạt động bằng chính nó, tuy nhiên, nếu một bản được tải bởi người khác trong thời gian chạy (ví dụ: A tải B), thì tôi không thể làm cho nó hoạt động được. Cần giúp đỡ.

Dưới đây là các thiết lập:

  • ZA phụ thuộc vào ZC (phổ biến) phiên bản 1.1
  • ZB phụ thuộc vào phiên bản ZC 1,0

ZA cần tải nhu cầu để tải một cái gì đó trong ZB (mà phụ thuộc vào ZC), khi chạy.

ZA là ứng dụng chính. Dưới thư mục bin, có một thư mục bổ sung plugins/plugin-ZB mà theo đó tôi muốn đặt tất cả ZB và các phụ thuộc của nó (ZC).

Đây là những gì tôi đã cố gắng cho đến nay:

Assembly.Load() sử dụng cùng một phiên bản của dll - làm việc tốt.

Assembly.Load() sử dụng các phiên bản khác nhau của dll - ZB tải, nhưng khi phương thức chạy, tôi nhận được một phương pháp không được tìm thấy ngoại lệ.

AppDomain.Load() gặp lỗi không tìm thấy tệp; Tôi thậm chí còn sử dụng các đại biểu để giải quyết hội đồng.

Một số chi tiết liên quan đến ZC: - một số phương pháp là tĩnh công cộng (một số thì không). Ví dụ. Log.Log("hello"); - một số có thể trả về giá trị (nguyên thủy hoặc đối tượng). - một số phương thức không tĩnh (và trả về giá trị).

Trợ giúp? - TIA

Trả lời

1

Ngoài lời khuyên tuyệt vời của Jonathan Allen, một cách "cổ điển" hơn để giải quyết vấn đề là bằng cách tải 2 phiên bản trong 2 AppDomanis khác nhau. Sau đó bạn có thể sử dụng .NET Remoting để làm cho hai AppDomains comunicate. Vì vậy, ZA nên tạo một Appdomain mới, tải trong AppDomain ZB này và gọi một số hoạt động trong ZB thông qua Remoting. Lưu ý rằng .NET Remoting có một số yêu cầu về các lớp mà bạn muốn sử dụng (kế thừa từ MarshalByRef), và tạo một AppDomain là một hoạt động tốn kém.

Hy vọng sự trợ giúp này

+0

"Bạn chỉ có thể có một phiên bản của một lắp ráp cho một AppDomain" là không đúng sự thật. Thậm chí có thể tham khảo hai phiên bản của một hội đồng từ một hội đồng duy nhất, tra cứu bí danh bên ngoài để biết thêm thông tin, đây là điều đầu tiên bật lên trên Google với một ví dụ về tính năng: http://blogs.msdn.com/ b/ansonh/archive/2006/09/28/extern-alias-walkthrough.aspx – Graham

+0

Sử dụng hai AppDomains là một giải pháp cho vấn đề được mô tả. – Graham

+0

Bạn đã đúng, hãy trả lời câu trả lời! –

0

Tôi đã có hai phiên bản của cùng một cụm được nạp cùng một lúc. Nó đã xảy ra với một kịch bản giống như bạn mô tả nó.

Bạn phải thuyết phục thời gian chạy để tải cùng một phiên bản ZC cho cả ZA và ZB. Tôi đã tìm thấy hai cách để làm điều đó:

  1. Sử dụng phần tử bindingRedirect trong tệp App.config của bạn. Có một số chi tiết trong this question.
  2. Sử dụng sự kiện AppDomain.AssemblyResolve. Có một số chi tiết trong this answer.

Vấn đề duy nhất với AppDomain.AssemblyResolve là nó chỉ kích hoạt khi thời gian chạy không thể tìm thấy phiên bản được yêu cầu. Nếu cả hai phiên bản đều có sẵn, thì bạn sẽ phải sử dụng bindingRedirect. Tôi đã sử dụng sự kiện AppDomain.AssemblyResolve và sau đó thêm kiểm tra an toàn để đảm bảo phiên bản phù hợp đã được tải bằng cách xem qua bộ sưu tập hội đồng tham chiếu của hội đồng. Nếu không, tôi phàn nàn với người dùng rằng một phiên bản cũ của thư viện nằm xung quanh và cho họ biết nó đang ở đâu.

+1

Điều này không tải hai phiên bản khác nhau, nó tải cùng phiên bản hai lần. –

+1

Khi tôi gặp sự cố này, @Cameron, thời gian chạy đã tải phiên bản 1.1 của ZC khi ZA bắt đầu. Sau đó, khi tôi nạp trình cắm ZB vào, thời gian chạy được nạp phiên bản 1.0 của ZC với nó. Đó là những gì tôi có nghĩa là bằng cách tải hai phiên bản khác nhau. Để làm cho ZA và ZB truyền các đối tượng từ ZC sang nhau, tôi phải làm cho cả hai đều tải cùng một phiên bản ZC. Đó là những gì tôi mô tả làm thế nào để làm trong câu trả lời của tôi. Tôi đã hiểu sai câu hỏi ban đầu chưa? –

3
m_Assembly1 = Reflection.Assembly.LoadFile(IO.Path.Combine(System.Environment.CurrentDirectory, "Old Version\Some.dll")) 
    m_Assembly2 = Reflection.Assembly.LoadFile(IO.Path.Combine(System.Environment.CurrentDirectory, "New Version\Some.dll")) 

    Console.WriteLine("Old Version: " & m_Assembly1.GetName.Version.ToString) 
    Console.WriteLine("New Version: " & m_Assembly2.GetName.Version.ToString) 

    m_OldObject = m_Assembly1.CreateInstance("FullClassName") 
    m_NewObject = m_Assembly2.CreateInstance("FullClassName") 

Từ đây trở đi tôi đã sử dụng kết buộc muộn và/hoặc phản ánh để chạy thử nghiệm của mình.

.NET: Load two version of the same DLL

+0

Lời khuyên tuyệt vời! không biết điều đó –

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