Разница между LoadFile и LoadFrom с сборками .NET?

Я смотрел документацию msdn, и я все еще немного запутался в чем разница между использованием LoadFile и LoadFrom при загрузке сборки. Может ли кто-нибудь представить пример или аналогию, чтобы лучше описать его. Документация MSDN смутила меня больше. Кроме того, Is ReflectionOnlyLoadFrom совпадает с LoadFrom, за исключением того, что он загружает сборку только в режиме отражения.

Поскольку мой опыт .NET не самый большой, вот несколько вопросов, касающихся документации MSDN с помощью LoadFile:

1) Что означает LoadFile анализирует сборки, которые имеют одинаковый идентификатор, но находятся в разных путях? Что такое идентификатор (пример)?

2) Указывает, что LoadFile не загружает файлы в "Контекст LoadFrom" и не разрешает зависимости с использованием пути загрузки. Что это значит, может ли кто-нибудь привести пример?

3) Наконец, он утверждает, что LoadFile полезен в этом ограниченном сценарии, потому что LoadFrom не может загружать сборки, которые имеют одинаковые идентификаторы, но разные пути; он будет загружать только первую такую ​​сборку, что снова приводит меня к одному и тому же вопросу, какова идентичность сборок?

Ответ 1

Проясняет ли это?

// 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);

Изменить. Чтобы ответить на вопросы, поднятые вами в вашем пересмотренном вопросе, вы определенно хотите прочитать Suzanne Cook on Assembly Identity.

Существует множество правил, которые регулируют загрузку сборок, а некоторые из них связаны с тем, как они разрешают зависимости - если ваша AssemblyA зависит от AssemblyB, где .NET должен искать AssemblyB? В глобальном кэше сборок в том же каталоге он нашел AssemblyA или где-то еще полностью? Кроме того, если он находит несколько копий этой сборки, как выбрать, какой из них использовать?

LoadFrom имеет один набор правил, а LoadFile - другой набор правил. Трудно представить много причин использовать LoadFile, но если вам нужно было использовать отражение на разных копиях одной и той же сборки, это там для вас.

Ответ 2

Из Блог Suzanne Cook:

LoadFile vs. LoadFrom

Будьте осторожны - это не то же самое вещь.

LoadFrom() проходит через Fusion и может быть перенаправлен на другой сборку по другому пути, но с это тождество, если оно уже загружен в контекст LoadFrom.

LoadFile() не связывается через Fusion вообще - загрузчик просто идет впереди и точно загружается *, что запрашиваемый абонент. Он не использует либо Load, либо LoadFrom контекст.

Итак, LoadFrom() обычно дает вам то, что вы просили, но не обязательно. LoadFile() предназначен для тех, кто действительно, действительно хотят точно, что запрашивается. (* Однако, начиная с версии 2, политика будет применяется как для LoadFrom(), так и для LoadFile(), поэтому LoadFile() не будет обязательно будет именно то, что было просил. Кроме того, начиная с v2, если сборка с ее личностью находится в GAC, копия GAC будет использована вместо. Использовать ReflectionOnlyLoadFrom() загрузить именно то, что вы хотите - но, обратите внимание, что сборки загружены таким образом не может быть выполнена.)

LoadFile() имеет catch. С тех пор не использует контекст привязки, его зависимости не автоматически найденный в его каталоге. Если они не доступный в контексте загрузки, вы должны были бы подписаться на Событие AssemblyResolve для привязки к ним.

Смотрите здесь.

Также см. "Выбор контекста привязки" в том же блоге.

Ответ 3

После большого поглаживания головы я обнаружил разницу сегодня днем.

Я хотел загрузить DLL во время выполнения, а DLL - в другой каталог. Эта DLL имела свои собственные зависимости (DLL), которые также жили в том же каталоге.

LoadFile(): Загрузите определенную DLL, но не зависимости. Поэтому, когда первый вызов был сделан из DLL в одну из этих других DLL, он выбрал исключение FileNotFoundException.

LoadFrom(): Загрузите указанную мной DLL, а также все зависимости, которые были в этом каталоге.

Ответ 4

одно отличие, которое я заметил:

Assembly.LoadFile. Загружает сборку в другой AppDomain с ограниченными правами пользователя (diffrence principel). операции, такие как сериализация/десерилизация, не могут быть выполнены.

Assembly.LoadFrom - загружает сборку в тот же AppDomain с теми же правами пользователя (тот же принцип).

Ответ 5

Примечание. Если одна сборка загружается с использованием пути 8.3, а затем из пути не-8.3, они будут рассматриваться как разные сборки, хотя они представляют собой одну и ту же физическую DLL.

Ответ 6

У .NET есть другой контекст нагрузки. Сюзанна Кук написала о них здесь: http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx

Это способ .Net помещает в карантин, что ссылки не перепутаны.

Ответ 7

В моем случае мне просто нужно просто удалить кеш-приложение ASP, расположенное @ C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files. Он восстанавливается при первом запуске сайта. Обязательно сначала остановите IIS.

Надеюсь, это поможет кому-то, как это было для меня.

Ответ 8

Согласно документации:

LoadFile (String): загружает содержимое файла сборки с указанием пути к файлу.

LoadFrom (String): загружает сборку с указанием ее имени или пути к файлу.