.NET 어셈블리를 사용하는 LoadFile과 LoadFrom의 차이점은 무엇입니까?


126

내가 MSDN 설명서를보고 있었고, 난 아직 정확히 사용의 차이점이 무엇인지에 혼란 조금 생각 LoadFile하고 LoadFrom어셈블리를로드 할 때. 누군가가 그것을 더 잘 설명하기 위해 예 또는 비유를 제공 할 수 있습니까? MSDN 문서가 더 혼란 스러웠습니다. 또한 반사 모드에서만 어셈블리를로드한다는 점 ReflectionOnlyLoadFromLoadFrom제외 하면 동일 합니다.

내 .NET 경험이 최고가 아니기 때문에 다음은 LoadFile을 사용하는 MSDN 설명서와 관련된 몇 가지 질문입니다.

1) LoadFile동일한 ID를 가지고 있지만 다른 경로에있는 어셈블리를 검사 한다는 것은 무엇을 의미 합니까? 정체성 (예)은 무엇입니까?

2) LoadFile'LoadFrom Context'에 파일을로드하지 않는다고 명시 하고로드 경로를 사용하여 종속성을 해결하지 않습니다. 이것은 무엇을 의미합니까, 누군가가 모범을 보일 수 있습니까?

3) 마지막으로 LoadFileLoadFrom은 ID가 같지만 경로가 다른 어셈블리를로드 할 수 없기 때문에이 제한된 시나리오에서 유용하다고 말합니다 . 그런 첫 번째 어셈블리 만로드됩니다. 그러면 다시 동일한 질문이 나타납니다. 어셈블리 ID는 무엇입니까?


10
진심으로 나는 또한 문장이 ... 항상 이해하지 않기 때문에 MS가 더 나은 작가 또는 뭔가를 고용해야한다는 가끔 생각
타릭


1
@ColonelPanic MS는 모든 것이 문서화되었다고 말할 수 있지만 도움 요인은 zeroooo입니다.
Legends

답변:


96

이게 해결 되나요?

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

편집 : 수정 된 질문에서 제기 한 질문에 답하려면 Assembly Identity에 대한 Suzanne Cook 을 읽고 싶습니다 .

어셈블리가로드되는 방법을 제어하는 ​​많은 규칙이 있으며, 그중 일부는 종속성을 해결하는 방법과 관련이 있습니다. AssemblyA가 AssemblyB에 종속 된 경우 .NET에서 AssemblyB를 찾아야하는 위치는 어디입니까? 전역 어셈블리 캐시에서 AssemblyA를 찾은 것과 동일한 디렉터리입니까, 아니면 완전히 다른 곳입니까? 또한 해당 어셈블리의 여러 복사본을 찾은 경우 사용할 복사본을 어떻게 선택해야합니까?

LoadFrom한 세트의 규칙 LoadFile이 있고 다른 세트의 규칙이 있습니다. 를 사용해야하는 여러 이유를 상상하기는 어렵지만 LoadFile동일한 어셈블리의 서로 다른 복사본에 리플렉션을 사용해야하는 경우 사용할 수 있습니다.


2
CodeBase는 ID와 동일합니까?
Xaisoft

아니요, 여기에서는 CodeBase를 어셈블리의 임의 속성으로 사용하여 두 번째 Assembly 인스턴스가 '잘못된'파일 (첫 번째 예제에서)을 가리키고 있음을 보여줍니다. 자세한 내용으로 답변을 업데이트하고 있습니다.
Jeff Sternal

1
약간 지워지지 만 LoadFrom을 사용할 때와 LoadFile을 사용할 때 path1 및 path2가 다른 어셈블리를 가리키는 경우 path1 및 path2가 디스크에서 동일한 어셈블리의 다른 복사본을 어떻게 가리 킵니다. path1과 path2의 예는 무엇입니까? 양해 해 주셔서 감사합니다.
Xaisoft

값이 같은지 두 개의 문자열 참조를 확인하는 이유는 무엇 string.Compare(x, y) == 0입니까? 나는 당신이 x == y거기 를 원한다고 생각 합니까? 모호한 이유로 문화 의존적 평등 검사를 원하는 string.Equals(x, y, StringComparison.CurrentCulture)경우 예를 들어 를 작성하는 것이 더 명확합니다 .
Jeppe Stig Nielsen

@JeffSternal "Suzanne Cook on Assembly Identity"링크가 여기서 끊어진 것 같습니다 ...
Martin Verjans

61

에서 수잔 쿡의 블로그 :

LoadFile 대 LoadFrom

조심하세요-이것들은 같은 것이 아닙니다.

LoadFrom ()은 Fusion을 통과하고 다른 경로에있는 다른 어셈블리로 리디렉션 될 수 있지만 LoadFrom 컨텍스트에 이미로드 된 경우 동일한 ID를 사용합니다.

LoadFile ()은 Fusion을 통해 바인딩되지 않습니다. 로더는 계속 진행하여 호출자가 요청한 내용을 정확히로드 *합니다. Load 또는 LoadFrom 컨텍스트를 사용하지 않습니다.

따라서 LoadFrom ()은 일반적으로 요청한 것을 제공하지만 반드시 그런 것은 아닙니다. LoadFile ()은 요청 된 것을 정말로 정말로 원하는 사람들을위한 것입니다. (* 그러나 v2부터는 LoadFrom ()과 LoadFile () 모두에 정책이 적용되므로 LoadFile ()이 반드시 요청 된 것과 정확히 일치하지는 않을 것입니다. 또한 v2부터는 해당 ID가있는 어셈블리가 GAC에서 GAC 복사본이 대신 사용됩니다. ReflectionOnlyLoadFrom ()을 사용하여 원하는대로 정확히로드합니다. 그러나 그런 방식으로로드 된 어셈블리는 실행할 수 없습니다.)

LoadFile ()에는 캐치가 있습니다. 바인딩 컨텍스트를 사용하지 않기 때문에 해당 디렉터리에서 종속성이 자동으로 발견되지 않습니다. 로드 컨텍스트에서 사용할 수없는 경우 바인딩하기 위해 AssemblyResolve 이벤트를 구독해야합니다.

여기를 참조 하십시오 .

또한 동일한 블로그에서 바인딩 컨텍스트 선택 문서를 참조하십시오 .


감사합니다. 블로그를 확인하고 msdn 문서에 대한 몇 가지 질문으로 게시물을 업데이트했습니다.
Xaisoft

@Xaisoft-Suzanne Cook의 블로그가 Assemblies Identity의 답변으로 다시 구출되었습니다. blogs.msdn.com/suzcook/archive/2003/07/21/57232.aspx를 참조하십시오 . 기본적으로 "어셈블리 표시 이름"이며 "System, Version = 1.0.3300.0, Culture = neutral, PublicKeyToken = b77a5c561934e089"와 같으므로 어셈블리의 실제 이름과 다른 식별 정보 (예 : PublicKeyToken 등).
CraigTP

1
퓨전에 대해 말할 때 그녀는 무엇을 언급합니까?
Xaisoft

1
실제로 Jeff가 자리를 잡았습니다. 이 링크를 참조하십시오 : grimes.demon.co.uk/workshops/fusionWS.htm Fusion 하위 시스템에 대한 멋진 자습서와 .NET에서 어셈블리를로드하는 기술
CraigTP

1
그냥 빨리 업데이트 (grimes.demon.co.uk/workshops/fusionWS.htm) 위의 URL은 더 이상 유효하지 지금으로 이동 한 것을 참고 : richardgrimes.com/workshops/fusionWS.htm
CraigTP

45

많은 머리를 긁적 거리고 난 후에 오늘 오후 나 자신의 차이를 발견했습니다.

런타임에 DLL을로드하고 싶었고 DLL은 다른 디렉토리에있었습니다. 이 DLL은 동일한 디렉토리에있는 자체 종속성 (DLL)을 가지고 있습니다.

LoadFile () : 특정 DLL을로드했지만 종속성은로드하지 않았습니다. 따라서 DLL 내에서 다른 DLL 중 하나에 대한 첫 번째 호출이 이루어지면 FileNotFoundException이 발생했습니다.

LoadFrom () : 내가 지정한 DLL과 해당 디렉터리에있는 모든 종속성을로드했습니다.


4
그것은 정확히 내 문제였습니다! FileNotFoundException방금로드 한 어셈블리에서 참조하는 어셈블리에 정의 된 개체의 새 인스턴스를 만들 때를 얻었습니다 .LoadFile. 이것을 변경 .LoadFrom하여 문제를 해결하는 것처럼 보였지만 이유를 몰랐습니다! 감사합니다
Connell

1
감사합니다. 저도 같은 문제를 겪고있었습니다.
Ivandro IG Jao 2016

4

참고 : 8.3 경로를 사용하여 한 어셈블리를로드 한 다음 8.3이 아닌 경로에서로드하는 경우 동일한 실제 DLL이더라도 다른 어셈블리로 표시됩니다.



0

내가 알아 차린 한 가지 차이점은 다음과 같습니다.

Assembly.LoadFile- 제한된 사용자 권한 (차이 원칙)을 사용하여 다른 AppDomain에서 어셈블리를로드합니다. serilization / deserilization과 같은 작업을 수행 할 수 없습니다.

Assembly.LoadFrom- 동일한 사용자 권한 (동일한 사용자)을 사용하여 동일한 AppDomain에서 어셈블리를로드합니다.


3
이것은 올바르지 않습니다. Assembly.LoadFile이 어셈블리를 다른 AppDomain으로로드한다고 생각하는 이유는 무엇입니까?
fr34kyn01535

0

필자의 경우 @에있는 ASP 응용 프로그램 캐시를 삭제하기 만하면 C:\Windows\Microsoft.NET\Framework\[asp version]\Temporary ASP.NET Files됩니다. 사이트가 처음 실행될 때 다시 작성됩니다. 먼저 IIS를 중지해야합니다.

이것이 나를 위해했던 것과 같은 사람이 도움이되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.