플러그인을 사용하여 응용 프로그램을 만들려고합니다.FileNotFound 다른 도메인에 대한 종속성을로드 할 때 어셈블리
나는 MainLib.dll을 가지고 있는데, 여기에는 1 개의 방법으로 commnon 인터페이스 (ICommon
)를 만들었습니다. 그런 다음 MainLib.dll에 대한 참조가있는 2 개의 .dll (플러그인)을 만들고 일부 클래스에서는 ICommon
을 구현합니다. 또한이 .dlls exept System
의 모든 참조를 제거했습니다.
그럼, .DLL의 유형 (그래서이 응용 프로그램은 또한 MainLib.dll에 참조) ICommon
를 구현하는 경우 확인 newDomain
폴더에 ".\\Plugins"
로드 모든 .dll을을 모니터링하는 응용 프로그램을 만들었습니다. 예이면 일부 목록에 .dll 이름을 추가하십시오.
그리고 지금 여기에 문제 : 내가 플러그인을로드하려고하기 전에 - 모든 플러그인이 .dll을의 의존성을 가지고 있기 때문에 내가 NEWDOMAIN에 MailLib.dll 및 시스템을로드합니다. 그들은 정확하게 올린다. 그럼,이 플러그인을로드하기 시작하고, 여기에 내가있다 :
FileNotFoundException이, 파일이나 어셈블리를로드 할 수 없습니다 ', 버전 = 1.0.0.0을 PluginWithException을, PublicKeyToken = null의 문화 = 중립'또는 해당 종속성 중 하나. 시스템이 지정된 파일을 찾을 수 없습니다.) string assembly LoadAssembly = domain.Load (Assembly.LoadFrom (asm) .FullName);
PluginWithException 어셈블리에는 System 및 MainLib의 종속성 만 2 개 있습니다. PluginWithException을로드하기 위해 tryied하기 전에 새 도메인에서 어셈블리를 검사 한 결과 시스템 및 MainLib이이 도메인에로드되었습니다. 그래서 나는 의존성이있는 어떤 경계선을 볼 수 없다. 나는 this 주제를 읽고 ProxyDomain
와 함께 솔루션을 시도했지만 예외는 동일합니다.
내가 뭘 잘못하고있어? 여기
코드 : 당신이 어셈블리를로드하는 이유
그러나 AppDomain domain = AppDomain.CreateDomain("tmpDomain", null, new AppDomainSetup { ApplicationBase = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins") });
, 내가 볼 수 없습니다 :
public static List<string> SearchPlugins(string[] names)
{
AppDomain domain = AppDomain.CreateDomain("tmpDomain");
domain.Load(Assembly.LoadFrom(@".\MainLib.dll").FullName);
domain.Load(@"System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
MessageBox.Show(GetAssembies(domain)); // here I can see that System and MailLib exist in new domain
List<string> plugins = new List<string>();
foreach (string asm in names)
{
Assembly loadedAssembly = domain.Load(Assembly.LoadFrom(asm).FullName); // here I have exception
var theClassTypes = from t in loadedAssembly.GetTypes()
where t.IsClass &&
(t.GetInterface("ICommonInterface") != null)
select t;
if (theClassTypes.Count() > 0)
{
plugins.Add(asm);
}
}
AppDomain.Unload(domain);
return plugins;
}
감사합니다. 당신의 대답은 매우 유용합니다! app.config가 포함 된 솔루션이 작동하지만 가장 좋은 방법은 아닙니다. 나는 로더와 함께 해결책을 시도했다. 'var plugins = loader.LoadPlugins ( Assembly.LoadFrom (Environment.CurrentDirectory + @ "\ Plugins \ PluginWithOutException.dll"). FullName);'그러나 도움이되지 않았다. (예외는 동일합니다 : ( –
자식 AppDomain을 생성 할 때 PrivateBinPath를 설정하려고 했으므로 어셈블리의 Plugins 폴더를 볼 수 있습니까? 'var appDomainSetup = new AppDomainSetup {PrivateBinPath = "Plugins"}; var domain = AppDomain.CreateDomain ("tmpDomain", AppDomain.CurrentDomain.Evidence, appDomainSetup); –
감사합니다! 이전에'PrivateBinPath'를 사용하여 솔루션을 시도했지만 잘못 했으므로 이제는 제대로로드되고 작동합니다. 어셈블리를 새 도메인에로드하고, 인터페이스의 메소드를 호출하고, 도메인을 언로드하고, 현재 (기본) 도메인에서 어셈블리를 검사했습니다. 불행히도 현재 (d 오류) 도메인. 또한 Loader가없는 app.config를 사용하는 솔루션은 기본 도메인에 어셈블리를로드합니다. 기본 도메인에이 어셈블리를로드하지 않는 것이 실제로 가능합니까? –