2017-11-16 29 views
6
  1. Có một ứng dụng (executor.exe) gọi các phương thức từ thư viện lớp (lib.dll) bằng cách sử dụng sự phản chiếu.
  2. executor.exe đã lắp ráp Newtonsoft.Json phiên bản 8.0 dưới dạng tài nguyên được nhúng.
  3. lib.dll có tham chiếu đến Newtonsoft.Json phiên bản 9.0.
  4. lib.dll có tham chiếu đến system.net.http.formatting phiên bản 4.0.0.21112, lần lượt đề cập đến Newtonsoft.Json 4.5.
  5. Tôi không có cơ hội sửa đổi tệp execor.exe.config (trừ thử nghiệm).

gì tôi muốn nhận được:Ngoại lệ "Phương thức không tìm thấy". Tại sao AppDomain.CurrentDomain.AssemblyResolve không hoạt động?

new JsonMediaTypeFormatter().SerializerSettings; 

gọi từ lib.dll. Nhưng nó không thành công với:

Phương pháp không tìm thấy: 'Newtonsoft.Json.JsonSerializerSettings System.Net.Http.Formatting.JsonMediaTypeFormatter.get_SerializerSettings()'

Những gì tôi đã cố gắng để làm:

  1. Xử lý AppDomain.CurrentDomain.AssemblyResolve (đã đăng ký chính xác, sử dụng ModuleInitializer). Nhưng nó không tăng lên. Sau khi tai nạn có 2 Newtonsoft.Json (với các phiên bản khác nhau) được tải vào AppDomain.
  2. Binding trong ứng dụng cấu hình:

    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" 
    culture="neutral" /> 
    <bindingRedirect oldVersion="4.0.0.0-5.0.0.0" newVersion="9.0.0.0" /> 
    

Vâng, nó hoạt động. Nhưng tôi không thể sử dụng giải pháp này. Sau khi vượt qua có 2 Newtonsoft.Json (với các phiên bản khác nhau) được nạp vào AppDomain.

  1. Tôi không hiểu tại sao các công trình này (oldversion = "8.0.0.0-9.0.0.0") nhưng:

    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> 
    <bindingRedirect oldVersion="8.0.0.0-9.0.0.0" newVersion="9.0.0.0" /> 
    

ngoại lệ "Phương pháp không tìm thấy "không ném. Sau khi vượt qua có 1 Newtonsoft.Json (9.0) được nạp vào AppDomain. Nhưng không thích hợp với tôi.

Tại sao AppDomain.CurrentDomain.AssemblyResolve không hoạt động? Tôi đoán vấn đề là trong 2 hội đồng nạp nhưng tôi không thể thay đổi hành vi này.

+0

Bạn đã nói phiên bản 8 được lưu trữ dưới dạng tài nguyên được nhúng. Tại sao? Nó được sử dụng như thế nào? – Evk

Trả lời

7

Tại sao AppDomain.CurrentDomain.AssemblyResolve không hoạt động?

Sự kiện AppDomain.CurrentDomain.AssemblyResolve được kích hoạt nếu độ phân giải không thành công. Nó không phải là trường hợp của bạn kể từ khi bạn nhìn thấy lắp ráp Newtonsoft.Json đã được tải trong miền ứng dụng.

Bạn bắt MissingMethodExceptionSystem.Net.Http.Formatting.JsonMediaTypeFormatter.get_SerializerSettings() trả về JsonSerializerSettings được khai báo trong Newtonsoft.Json phiên bản 4.5. Unfortunatelly, vì không có CLR JsonSerializerSettings từ Newtonsoft.Json 4.5 không giống nhau ở tất cả là JsonSerializerSettings từ Newtonsoft.Json 9.0.

Để khắc phục sự cố này, cơ chế chuyển hướng các phiên bản lắp ráp đã được giới thiệu (bindingRedirect mà bạn tham khảo).

ngoại lệ "Không tìm thấy phương thức". Sau khi vượt qua có 1 Newtonsoft.Json (9.0) được tải vào AppDomain. Nhưng không thích hợp với tôi.

Thực ra đó là giải pháp bạn nên tuân theo. Lựa chọn tốt nhất của bạn là chỉ có một assembly Newtonsoft.Json được nạp vào miền ứng dụng và có cấu hình chuyển hướng phiên bản.

Tại sao bạn sẽ phát minh lại bánh xe và cố gắng tìm giải pháp khác với các ưu đãi nền tảng? Nếu vì một số lý do lạ bạn bị cấm sửa đổi cấu hình ứng dụng, bạn có thể thêm chuyển hướng lắp ráp ở mức máy Xem chi tiết article để biết chi tiết. Nhưng chuyển hướng phiên bản lắp ráp là cách thức vĩnh viễn DLL hell problem được sửa trong .Net. Sử dụng bất kỳ cách giải quyết khác (ngay cả khi bạn quản lý để tìm chúng) sẽ làm cho bạn không tốt.

3

Nếu bạn không thể áp dụng chuyển hướng ràng buộc, bạn cũng có thể tải cụm chính xác về phương pháp sử dụng khởi động ứng dụng Assembly.LoadFrom. Trong phương pháp chính tìm thấy Newtonsoft.Json dlls và tải một với phiên bản bạn cần. Điều đó nên tránh tải lắp ráp với phiên bản không chính xác. Hãy cho tôi biết nếu bạn muốn tôi cung cấp đoạn mã cho bạn.

+0

Có vẻ như nó sẽ không giải quyết vấn đề của OP. Từ câu hỏi nó rõ ràng rằng lắp ráp cần thiết được nạp trong miền ứng dụng và tải phiên bản 4.5 đầu tiên không sửa MissingMethodException. – CodeFuller

+0

@CodeFuller, tôi nghĩ rằng tải v4.5 đầu tiên sẽ ngăn không cho tải v.9.0 và giải quyết vấn đề. Đó là cơ bản những gì liên kết chuyển hướng nào. Nó có thể gây ra các vấn đề khác mặc dù, khó dự đoán. Từ làm thế nào tôi hiểu được công việc của chuyển hướng ràng buộc cho OP ông nên tải v9.0, không v4.5 với cách tiếp cận đề nghị của tôi. Và làm điều đó trước khi v4.5 được tải vào miền, tức là càng sớm càng tốt. –

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