2012-01-25 255 views
4

我主要通過谷歌閱讀了很多東西(不在這裏),沒有找到答案,所以我在這裏問它。AppDomain.AppendPrivatePath替代方案?

我想添加到「東西」(我認爲對AppDomain),以便我的代碼可以解決在AT RUNTIME如何Assembly.CreateInstance特定的DLL是在我的應用程序的編譯文件夾之外。

我真的覺得AppDomain是類使用和AppendPrivatePath聽起來像使用的方法,但它現在是「過時」 ...... MSDN建議使用PrivateBinPath但據我瞭解我要創建一個新的AppDomain中,並與我的測試,我覺得Assembly.CreateInstance不查找引用我的新的AppDomain

像一些代碼:

AppDomainSetup domaininfo = new AppDomainSetup(); 
domaininfo.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; 
domaininfo.PrivateBinPath = "D:\\.....\\bin\\Debug\\"; 

Evidence adevidence = AppDomain.CurrentDomain.Evidence; 

AppDomain newDomain = AppDomain.CreateDomain("FrameworkDomain", adevidence, domaininfo); 

作品,但後來,當我嘗試CreateInstance,我得到了TargetInvocation例外

我也試過:

Thread.GetDomain().SetupInformation.PrivateBinPath = "D:\\.....\\bin\\Debug\\"; 

聽起來「特殊」,但對我好,但它不工作...

我真的覺得我必須給D:\\.....\\bin\\Debug\\路徑到目前的AppDomain,但它不再可能,因爲AppendPrivatePath已過時...

任何幫助嗎?

回答

3

您可以在程序集觸發的事件中自行解析附加的DLL,以使您知道它無法找到類型。

AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += MyResolve; 
AppDomain.CurrentDomain.AssemblyResolve += MyResolve; 

private Assembly MyResolve(Object sender, ResolveEventArgs e) { 
    Console.Error.WriteLine("Resolving assembly {0}", e.Name); 
    // Load the assembly from your private path, and return the result 
} 
0

如何使用

Assembly.LoadFrom("..path) 
0

你可以在事件處理程序添加到應用程序域AssemblyResolve事件,然後加載組件形成的特殊的私人路徑。

2

我可能是完全跟蹤你實際上是試圖建立,但假設你想建立要組織插件在子文件夾這樣的插件基礎設施:

\plugins\foo\foo.dll 
\plugins\foo\dependency_that_foo_needs.dll 
\plugins\bar\bar.dll 
\plugins\bar\dependency_that_bar_needs.dll 

的您遇到的問題是,foo.dll無法加載其依賴項,因爲該框架不會查找要加載的程序集的子目錄。

使用Managed Extensibility Framework(MEF 2 Preview)的最新預覽版,人們可以輕鬆構建這樣的事情。我認爲你甚至可以在早期版本中做到這一點,但是早期的版本迫使你在插件上使用最新版本不再依賴的特殊屬性。

因此,假設是你的插件合同:

public interface IPlugin 
{ 
    string Run(); 
} 

加載和運行的所有插件\插件\富\,\插件\欄\(...)只需使用此代碼:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var registration = new RegistrationBuilder(); 
     registration.ForTypesDerivedFrom<IPlugin>().Export().Export<IPlugin>(); 

     var directoryInfo = new DirectoryInfo("./plugins"); 

     var directoryCatalogs = directoryInfo 
      .GetDirectories("*", SearchOption.AllDirectories) 
      .Select(dir => new DirectoryCatalog(dir.FullName, registration)); 

     var aggregateCatalog = new AggregateCatalog(directoryCatalogs); 

     var container = new CompositionContainer(aggregateCatalog); 
     container 
      .GetExportedValues<IPlugin>() 
      .ForEach(plugin => Console.WriteLine(plugin.Run())); 

     Console.ReadLine(); 
    } 
} 

正如我所說的,我可能是完全的軌道,但機會也有人尋找替代發現它有用:-)