2012-01-25 277 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(); 
    } 
} 

正如我所说的,我可能是完全的轨道,但机会也有人寻找替代发现它有用:-)