어셈블리를 사용하여 어셈블리의 로딩을 혼합 할 때 이상한 동작.
-
03-07-2019 - |
문제
어셈블리를 사용하여 어셈블리의 로딩을 혼합 할 때 이상한 동작.
Assembly.Load와 함께 어셈블리를로드 할 때 이상한 동작을 만났습니다.
어셈블리가 실행 폴더가 아닌 폴더에있는 Assembly.LoadFrom을 사용하여 어셈블리를로드하고 있습니다.
나중에 어셈블리가 이미로드된다는 사실에도 불구하고 System.io.filenotfoundException (“파일 또는 어셈블리를로드 할 수 없음…”)을 사용 하여이 어셈블리를 다시로드하려고 할 때 테스트 코드에서 나중에로드를 시도합니다. . 부하는 강한 이름과 강력한 이름으로 실패합니다 (이 어셈블리가 다시 한 번로드하는 원래 이유는 Binaryformatter의 사용입니다).
그러나 어셈블리가 실행 폴더에있는 경우 나중에로드는 두 경우 모두에 성공하며 강력한 이름과 비 강력한 이름으로 성공합니다. 이 경우 두 개의 동일한 어셈블리가 두 개의 다른 위치에서로드되어 있음을 알 수 있습니다.
이 문제를 재현하는 간단한 코드 샘플 -
어셈블리 어셈블리 1 = Assembly.Loadfrom (@"C : A.Dll");
// 강한 이름으로로드하는 조립 실패 어셈블리 2 = Assembly.Load ( "a, 버전 = 1.0.0.0, Culture = Neutral, PublicKeyToken = 14986c3f172d1c2c");
// 비 강력한 실패 실패 어셈블리 조립 3 = Assembly.Load (@"a");
- CLR이 이미로드 된 어셈블리를 무시하는 이유는 무엇입니까?
- 이 문제를 어떻게 완화 할 수 있습니까?
감사.
해결책
이상하지 않습니다. 문서에 따라로드 및로드로로드하면 어셈블리가 다른 상황에 놓입니다. 이것 도움이 될 수 있습니다.
- CLR이 이미로드 된 어셈블리를 무시하는 이유는 무엇입니까?
그들은 다른 맥락에 있기 때문에.
- 이 문제를 어떻게 완화 할 수 있습니까?
동일한 컨텍스트에서로드하거나 CLR이 어셈블리를 찾도록 핸들러를 부착하여 AppDomain.AssemblyResolve
.
대안
어셈블리를로드하는 위치가 AppDomain의 하위 폴더 인 경우 Basedirectory는 간단히 app.config에 항목을 추가 할 수 있습니다.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;bin2\subbin;bin3"/>
</assemblyBinding>
</runtime>
</configuration>
다른 팁
@kent boogart : 그것은 올바른 설명 인 것 같습니다. 전체 설명을 위해, Suzanne Cook 은이 블로그 게시물을 가지고있는이 블로그 게시물을 가지고 있습니다.http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx
다음은 AppDomain.assemblyresolve를 활용하는 코드입니다.
// register to listen to all assembly resolving attempts:
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
// Check whether the desired assembly is already loaded
private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) {
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies) {
AssemblyName assemblyName = assembly.GetName();
string desiredAssmebly = args.Name;
if (assemblyName.FullName == desiredAssmebly) {
return assembly;
}
}
// Failed to find the desired assembly
return null;
}