2013-09-22 6 views
6

사기스러운 질문에 사과드립니다. 누군가가 더 좋은 제안을하면 큰 소리로 말하십시오.다른 어셈블리를 찾는 어셈블리를 어떻게 동적으로 참조 할 수 있습니까?

다른 응용 프로그램에 속한 어셈블리를 동적으로 호출하여 개체를 만들려고합니다.

다음 PowerShell을 코드 ​​

나를 위해 잘 작동하고 : 나는 C#에서 같은 일을하기 위해 사투를 벌인거야

[Reflection.Assembly]::LoadFrom("C:\Program Files\Vendor\Product\ProductAPI.dll") 
$bobject = new-object ProductAPI.BasicObject  
$bobject.AddName("Some Name") 

. StackOverflow에 대한 다른 게시물을 기반으로 현재이 있습니다 :

System.Reflection.Assembly myDllAssembly = 
System.Reflection.Assembly.LoadFile("C:\\Program Files\\Vendor\\Product\\ProductAPI.dll"); 

System.Type BasicObjectType = myDllAssembly.GetType("ProductAPI.BasicObject"); 

var basicObjectInstance = Activator.CreateInstance(BasicObjectType); 

최종 행 결과 TargetInvocationException.

{파일 또는 어셈블리 'AnotherObject, Version = 1.2.345.0, Culture = neutral, PublicKeyToken = null'또는 종속성 중 하나를로드 할 수 없습니다. 시스템에서 지정된 파일을 찾을 수 없습니다. "

BasicObject 생성자가 AnotherObject (같은 폴더의 AnotherObject.dll에서)를 호출하려고하지만 찾지 못하는 것처럼 보입니다.

이 문제를 해결하는 방법에 대한 유용한 정보가 있습니까?

+0

DLL이 작동하려면 다른 DLL이 필요합니다. 이 도구를 사용하여 DLL의 종속성을 탐색 할 수 있습니다. http://www.dependencywalker.com/ – cgTag

+0

누락 된 DLL을 찾을 때. 릴리스 폴더에 복사하거나 창 PATH를 수정하여 포함하십시오. – cgTag

+0

['FUSLOGVW.exe'] (http://msdn.microsoft.com/en-us/library/e74a18c4.aspx) (* Assembly Binding Log Viewer *)로로드에 실패한 것을 확인해보십시오. 로드되지 못했습니다 (그리고 .NET 로더가 찾고있는 곳). – Richard

답변

7

the usual places에서 종속 어셈블리를 찾을 수없는 경우 해당 어셈블리를 찾는 방법을 수동으로 지정해야합니다.

두 쉬운 방법 나는이 작업을 수행하는 알고 있어요 :

  1. 수동 Assembly.Load와 사전에 종속 어셈블리를로드합니다.

  2. 추가 어셈블리 종속성을 사용하여 어셈블리를로드하는 도메인의 AssemblyResolve 이벤트를 처리하십시오.

두 가지 모두 당신이 미리로드하려는 어셈블리의 종속성을 알아야하지만, 그렇게 큰 질문은 아니라고 생각합니다.

첫 번째 옵션을 사용하면 전체로드와 reflection-only Load의 차이를 살펴 보는 것도 도움이됩니다.

2 (권장)과 같이 사용하면 중첩 된 종속성 체인 (예 : MyLib.dll은 LocalStorage.dll이 Raven.Client를 참조로 참조 함)을 사용하여 추가 혜택을 얻을 수 있습니다. dll은 NewtonSoft.Json.dll을 참조합니다.) 또한 찾을 수없는 종속성에 대한 정보를 제공합니다 :

AppDomain.CurrentDomain.AssemblyResolve += (sender,args) => { 

    // Change this to wherever the additional dependencies are located  
    var dllPath = @"C:\Program Files\Vendor\Product\lib"; 

    var assemblyPath = Path.Combine(dllPath,args.Name.Split(',').First() + ".dll"); 

    if(!File.Exists(assemblyPath)) 
     throw new ReflectionTypeLoadException(new[] {args.GetType()}, 
      new[] {new FileNotFoundException(assemblyPath) }); 

    return Assembly.LoadFrom(assemblyPath); 
}; 
+1

굉장! 마지막으로 '경로'에 대한 두 개의 참조가 'assemblyPath'여야한다고 생각합니다. – gf131072

+0

예, 고맙습니다. – nathanchere

관련 문제