自定义AppDomain和PrivateBinPath

时间:2011-07-08 15:21:57

标签: c# appdomain appdomainsetup

我正在使用c#4.0和一个仅用于测试的控制台应用程序,以下代码确实提供了异常。

AppDomainSetup appSetup = new AppDomainSetup()
{
    ApplicationName = "PluginsDomain",
    ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
    PrivateBinPath = @"Plugins",
    ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
};

AppDomain appDomain = AppDomain.CreateDomain("PluginsDomain", null, appSetup);

AssemblyName assemblyName = AssemblyName.GetAssemblyName(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins", "sample.dll"));

Assembly assembly = appDomain.Load(assemblyName); //This gives an exception of File not found

AppDomain.Unload(appDomain);

在我创建的AppDomain上使用加载时,我一直收到文件未找到异常。

感谢。

3 个答案:

答案 0 :(得分:9)

首先确保插件是AppDomain基本路径的子目录。 PrivateBinPath仅适用于here

所述的子目录

如果这不是问题,那么请查看您的融合绑定日志。使用fusion log viewer还有一个很好的Blog Post。融合日志将告诉您搜索程序集的位置。这应该告诉您路径是否包含在搜索中。

其他一种可能性是找到你的程序集而不是其中一个依赖项。同样,融合日志查看器会告诉你。

答案 1 :(得分:7)

当我尝试从bin目录之外的目录动态加载dll文件时,我遇到了这个线程。长话短说,我能够通过使用AppDomain.CurrentDomain.AssemblyResolve事件来实现这一目标。这是代码:

//--begin example:

public MyClass(){
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}

private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    foreach (var moduleDir in _moduleDirectories)
    {
        var di = new DirectoryInfo(moduleDir);
        var module = di.GetFiles().FirstOrDefault(i => i.Name == args.Name+".dll");
        if (module != null)
        {
            return Assembly.LoadFrom(module.FullName);
        }
    }
    return null;
}

//---end example

每次调用CurrentDomain_AssemblyResolve方法时都会调用方法AppDomain.CurrentDomain.Load("...")。此自定义事件处理程序使用您自己的自定义逻辑来执行定位程序集的任务(这意味着您可以将其指向任何位置,甚至在bin路径之外等)。我希望这可以节省其他人几个小时......

答案 2 :(得分:5)

我想我会弄清楚为什么会发生这种情况,那是因为当前域也需要加载程序集,即使你在不同的app域中加载程序集,当前域需要知道它并加载它,那就是因为.NET是如何设计的。

点击此处了解详情。

http://msdn.microsoft.com/en-us/library/36az8x58.aspx

当我检查融合日志时,我发现新创建的应用程序域成功地能够从专用bin路径加载程序集,以及为什么你仍然得到“File not found”的例外,因为这异常最初属于当前的应用域。

这意味着如果您将程序集复制到当前应用程序路径或当前域正在探测的路径中,您会发现可以将程序集加载到自定义域中。

希望有所帮助。