Sự khác biệt giữa LoadFile và LoadFrom với .NET Assemblies?


126

Tôi đã xem tài liệu msDN và tôi vẫn hơi bối rối về sự khác biệt chính xác giữa việc sử dụng LoadFileLoadFromkhi tải một lắp ráp. Ai đó có thể cung cấp một ví dụ hoặc một sự tương tự để mô tả nó tốt hơn. Các tài liệu MSDN làm tôi bối rối hơn. Ngoài ra, ReflectionOnlyLoadFromcũng giống như LoadFromngoại trừ việc nó chỉ lắp ráp ở chế độ phản chiếu.

Vì trải nghiệm .NET của tôi không phải là tốt nhất, nên đây là một số câu hỏi liên quan đến tài liệu MSDN sử dụng LoadFile:

1) Có nghĩa là gì khi LoadFilekiểm tra các hội đồng có cùng Danh tính, nhưng được đặt trong các đường dẫn khác nhau? Danh tính (ví dụ) là gì?

2) Nó tuyên bố LoadFilekhông tải các tệp vào 'Bối cảnh LoadFrom' và không giải quyết các phụ thuộc bằng cách sử dụng đường dẫn tải. Điều này có nghĩa là gì, ai đó có thể cung cấp một ví dụ?

3) Cuối cùng, nó tuyên bố LoadFilelà hữu ích trong kịch bản giới hạn này vì LoadFrom không thể tải các cụm có cùng danh tính nhưng đường dẫn khác nhau; nó sẽ chỉ tải bản lắp ráp đầu tiên như vậy, một lần nữa đưa tôi đến cùng một câu hỏi, bản sắc lắp ráp là gì?


10
Nghiêm túc mà nói, đôi khi tôi cũng nghĩ rằng MS nên thuê những nhà văn giỏi hơn hoặc những người khác vì những câu không phải lúc nào cũng dễ hiểu ...
Tarik


1
@ColonelPanic MS có thể nói rằng mọi thứ đều được ghi lại ... nhưng với yếu tố trợ giúp của zeroooo.
Huyền thoại

Câu trả lời:


96

Điều này có làm rõ nó không?

// path1 and path2 point to different copies of the same assembly on disk:

Assembly assembly1 = Assembly.LoadFrom(path1);
Assembly assembly2 = Assembly.LoadFrom(path2);

// These both point to the assembly from path1, so this is true
Console.WriteLine(assembly1.CodeBase == assembly2.CodeBase);

assembly1 = Assembly.LoadFile(path1);
assembly2 = Assembly.LoadFile(path2);

// These point to different assemblies now, so this is false
Console.WriteLine(assembly1.CodeBase == assembly2.CodeBase);

Chỉnh sửa : để trả lời các câu hỏi bạn nêu ra trong câu hỏi sửa đổi của mình, bạn chắc chắn muốn đọc Suzanne Cook trên Danh tính hội .

Có rất nhiều quy tắc chi phối cách các hội đồng được tải, và một số trong số chúng phải thực hiện với cách chúng giải quyết các phụ thuộc - nếu Hội đồng của bạn phụ thuộc vào Hội đồng, .NET nên tìm đâu để tìm Hội đồng? Trong Cache hội toàn cầu, cùng một thư mục mà nó tìm thấy hộiA, hoặc một nơi nào khác hoàn toàn? Hơn nữa, nếu nó tìm thấy nhiều bản sao của hội đồng đó, nó nên chọn cái nào để sử dụng?

LoadFromcó một bộ quy tắc, trong khi LoadFilecó một bộ quy tắc khác. Thật khó để tưởng tượng nhiều lý do để sử dụng LoadFile, nhưng nếu bạn cần sử dụng sự phản chiếu trên các bản sao khác nhau của cùng một hội đồng, thì đó là dành cho bạn.


2
CodeBase có giống với Danh tính không?
Xaisoft

Không, tôi chỉ sử dụng CodeBase ở đây như một thuộc tính tùy ý của hội đồng để minh họa rằng phiên bản hội thứ hai đang trỏ đến tệp 'sai' (trong ví dụ đầu tiên). Tôi đang cập nhật câu trả lời của tôi với nhiều chi tiết hơn.
Jeff Sternal

1
Nó xóa nó đi một chút, nhưng path1 và path2 trỏ đến các bản sao khác nhau của cùng một cụm trên đĩa khi sử dụng LoadFrom và khi sử dụng LoadFile, path1 và path2 trỏ đến các cụm khác nhau. Một ví dụ về path1 và path2 sẽ là gì? Cảm ơn sự kiên nhẫn của bạn.
Xaisoft

Tại sao bạn kiểm tra hai tham chiếu chuỗi cho giá trị bằng string.Compare(x, y) == 0? Tôi nghĩ bạn muốn x == yở đó? Nếu vì những lý do mơ hồ mà bạn muốn kiểm tra sự bình đẳng phụ thuộc vào văn hóa, thì rõ ràng là viết rõ hơn string.Equals(x, y, StringComparison.CurrentCulture).
Jeppe Stig Nielsen

@JeffSternal Link trên "Suzanne Cook on the Identity" dường như bị phá vỡ ở đây ...
Martin Verjans

61

Từ blog của Suzanne Cook :

LoadFile so với LoadFrom

Hãy cẩn thận - đây không phải là điều tương tự.

LoadFrom () đi qua Fusion và có thể được chuyển hướng đến một tổ hợp khác ở một đường dẫn khác nhưng với cùng một danh tính nếu một đã được tải trong bối cảnh LoadFrom.

LoadFile () hoàn toàn không liên kết thông qua Fusion - trình tải chỉ đi trước và tải chính xác * những gì người gọi yêu cầu. Nó không sử dụng bối cảnh Load hoặc LoadFrom.

Vì vậy, LoadFrom () thường cung cấp cho bạn những gì bạn yêu cầu, nhưng không nhất thiết phải như vậy. LoadFile () dành cho những người thực sự, thực sự muốn chính xác những gì được yêu cầu. (* Tuy nhiên, bắt đầu từ v2, chính sách sẽ được áp dụng cho cả LoadFrom () và LoadFile (), vì vậy LoadFile () sẽ không nhất thiết phải chính xác những gì được yêu cầu. Ngoài ra, bắt đầu từ v2, nếu một hội đồng có nhận dạng của nó GAC, bản sao GAC sẽ được sử dụng thay thế. Sử dụng ReflectionOnlyLoadFrom () để tải chính xác những gì bạn muốn - nhưng, lưu ý rằng các hội đồng được tải theo cách đó không thể được thực thi.)

LoadFile () có một lưu ý. Vì nó không sử dụng bối cảnh ràng buộc, nên các phụ thuộc của nó không tự động được tìm thấy trong thư mục của nó. Nếu chúng không có sẵn trong ngữ cảnh Tải, bạn sẽ phải đăng ký sự kiện AssociationResolve để liên kết với chúng.

Xem ở đây .

Đồng thời xem phần Chọn bài viết Binding Context trên cùng một blog.


Cảm ơn, tôi sẽ kiểm tra blog, tôi đã cập nhật bài viết của mình với một số câu hỏi liên quan đến tài liệu msDN.
Xaisoft

@Xaisoft - Blog của Suzanne Cook đến giải cứu một lần nữa với câu trả lời của Danh tính hội đồng. Xem blog.msdn.com/suzcook/archive/2003/07/21/57232.aspx . Nó thực chất là một "tên hiển thị lắp ráp" và đây là một cái gì đó như: "Hệ thống, Phiên bản = 1.0.3300.0, Văn hóa = trung tính, PublicKeyToken = b77a5c561934e089" bao gồm cả tên thực của hội đồng, đó là số phiên bản cùng với thông tin nhận dạng khác (như PublicKeyToken, v.v.).
CraigTP

1
Cô ấy đang đề cập đến điều gì khi nói về Fusion?
Xaisoft

1
Thật vậy, Jeff là tại chỗ. Xem liên kết này: grimes.demon.co.uk/workairs/fusionWS.htm để biết hướng dẫn hay về hệ thống con Fusion và đó là công nghệ để tải các cụm trong .NET
CraigTP

1
Chỉ cần cập nhật nhanh, lưu ý rằng URL ở trên (grimes.demon.co.uk/workairs/fusionWS.htm) không còn hợp lệ và hiện đã được chuyển đến: richardgrimes.com/workairs/fusionWS.htm
CraigTP

45

Sau nhiều lần vò đầu bứt tai, tôi đã phát hiện ra một sự khác biệt vào chiều nay.

Tôi muốn tải một DLL khi chạy và DLL sống trong một thư mục khác. DLL đó có các phụ thuộc riêng (DLL) cũng sống trong cùng thư mục đó.

LoadFile (): Đã tải DLL cụ thể, nhưng không phụ thuộc. Vì vậy, khi cuộc gọi đầu tiên được thực hiện từ bên trong DLL đến một trong những DLL khác, nó đã ném FileNotFoundException.

LoadFrom (): Đã tải DLL mà tôi đã chỉ định và tất cả các phụ thuộc sống trong thư mục đó.


4
Đó chính xác là vấn đề của tôi! Tôi đã nhận được FileNotFoundExceptionkhi tạo một phiên bản mới của một đối tượng được xác định trong một hội đồng được tham chiếu bởi hội đồng mà tôi vừa tải .LoadFile. Thay đổi điều này để .LoadFromxuất hiện để khắc phục sự cố, nhưng tôi không biết tại sao! Cảm ơn
Connell

1
Cảm ơn bạn, tôi đã có cùng một vấn đề.
Ivandro IG Jao

4

Lưu ý: Nếu một tập hợp được tải bằng cách sử dụng một đường dẫn 8.3, và sau đó từ một đường dẫn không phải 8.3, chúng sẽ được xem như là các tập hợp khác nhau, mặc dù chúng là cùng một DLL vật lý.



0

Một sự khác biệt mà tôi nhận thấy là:

Hội.LoadFile - tải lắp ráp trong AppDomain khác nhau với quyền sử dụng hạn chế (diffrence principel). các hoạt động như serilization / deserilization không thể được thực hiện.

Assembly.LoadFrom - tải lắp ráp trong cùng một AppDomain với quyền sử dụng giống nhau (cùng principel).


3
Điều này LAF không đúng. Điều gì khiến bạn tin rằng Association.LoadFile tải một hội đồng vào một AppDomain khác?
fr34kyn01535

0

Trong trường hợp của tôi, tôi chỉ cần xóa bộ đệm ứng dụng ASP nằm ở @ C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files. Nó được xây dựng lại khi trang web được chạy lần đầu tiên. Hãy chắc chắn dừng IIS trước.

Hy vọng điều này sẽ giúp ai đó như nó đã làm cho tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.