2012-01-23 27 views
10

Tôi có một chương trình ứng dụng C#, hãy gọi nó là App.exe. Nó tham khảo một DLL có tên là A.dll mà lần lượt tham chiếu một DLL, cụ thể là, B.dll. Tuy nhiên cách thức mà chúng được tham chiếu có một chút khác biệt. Trong mã của A.dll, nó đã trực tiếp tham chiếu B.dll (bằng cách vào Project> References> Add B.dll). Tuy nhiên App.exe của tôi có mã để tải A.dll tại thời gian chạy bằng Assembly.Load(), v.v.Tham khảo một DLL từ một DLL khác

Vì vậy, để tóm tắt lại, App.exe ---- (thời gian tải) ---> A.dll - - (tham khảo trực tiếp) ---> B.dll

Tất cả ba thứ (App.exe, A.dll và B.dll) đều nằm trong cùng thư mục, giả sử ExeDir. Bây giờ những gì tôi muốn làm là, đặt A.dll và B.dll trong một thư mục con của ExeDir. Tôi có thể làm điều này bằng cách sử dụng một tệp App.config chỉ định đường dẫn của A.dll và yêu cầu App.exe tải A.dll từ đường dẫn đó. Càng xa càng tốt.

Tuy nhiên vấn đề là khi tôi làm điều này, .NET cho tôi một lỗi nói rằng nó không thể tìm thấy B.dll trong thư mục tương tự như A.dll. Nếu tôi di chuyển nó trở lại thư mục gốc (cùng thư mục với App.exe) thì nó hoạt động tốt. Có nghĩa là, tôi có thể đặt A.dll trong một thư mục phụ, nhưng B.dll cần phải được trong thư mục gốc.

Có cách nào để tôi có thể giữ cả hai tệp DLL trong thư mục con không?

Trả lời

9

Thêm một yếu tố <probing> trong app.config của bạn:

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

<configuration> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <probing privatePath="bin;bin2\subbin;bin3"/> 
     </assemblyBinding> 
    </runtime> 
</configuration> 
+0

Cảm ơn bạn đã trả lời D Stanley. Nhưng tôi có một chút mất mát ở đây. Bạn có thể cho tôi biết chính xác tôi phải làm gì ở đây không? Chỉ cần để xác định yếu tố này với đường dẫn lắp ráp? – Sach

+1

Có liên quan đến EXE của bạn. Ví dụ, trong ví dụ MSDN, binder sẽ tìm kiếm trong thư mục 'BIN' theo mặc định, nhưng cũng sẽ tìm kiếm thư mục' bin2', thư mục 'bin2 \ subbin' và thư mục' bin3'. Thay thế 'bin; bin2 \ subbin; bin3' bằng thư mục (liên quan đến EXE) mà A.dll và B.dll đang ở. Lưu ý rằng bạn không còn phải chỉ định đường dẫn đến A.dll nếu nó được bao gồm trong đường dẫn thăm dò. –

+0

Cảm ơn Stanley, tôi đã làm việc đó! Đó là lỗi của tôi, mặc dù tôi không giải thích được vấn đề hoàn chỉnh của tôi ở đây. Lý do tại sao tôi muốn các DLL trong các thư mục riêng biệt là tôi có thể có một số khác nhau A.dlls (nội dung khác nhau), và mỗi người trong số họ có thể tham khảo B.dlls. Vì vậy, tôi muốn thực hiện mã an toàn hơn, như vậy nếu A.dll khác nhau muốn tham khảo B.dll mà cũng có thể thay đổi bên trong. Nhưng có vẻ như nó không thể được thực hiện. Tuy nhiên, cảm ơn!Bạn đã trả lời câu hỏi ban đầu của tôi. – Sach

5

Bạn có thể giải quyết thủ công cụm B.DLL bằng cách cung cấp trình xử lý sự kiện cho sự kiện AppDomain.AssemblyResolve của AppDomain hiện tại.

currentDomain.AssemblyResolve += ResolveLostAssemblies; 

Sau đó cung cấp một thực hiện ResolveEventHandler:

private Assembly ResolveLostAssemblies(object sender, ResolveEventArgs args) 
{ 
    // Find the assembly referenced by args.Name, load it dynamically, and return it. 
} 

tôi đã tìm thấy rằng điều này cung cấp sự kiểm soát hầu hết trên đó lắp ráp được nạp và khi nào. Nó đặc biệt hoạt động tốt trong trường hợp bạn đang ứng dụng là có thể cắm được và mỗi plugin sống trong thư mục con riêng của chúng trong thư mục "plugins" (không nhất thiết phải là thư mục ứng dụng). Về mặt kỹ thuật, lắp ráp thậm chí không phải là một tập tin vật lý sử dụng phương pháp này. Mặc dù phương pháp của D Stanley thường được coi là tiêu chuẩn hơn.

+0

Cảm ơn Babcock! Tôi đã làm việc với phương pháp của Stanley. – Sach

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