Custom AppDomain and PrivateBinPath

2019-03-19 00:07发布

I'm using c# 4.0 and a console application just for testing, the following code does gives an exception.

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);

I keep getting File not found exception when using Load on my created AppDomain.

Thanks.

3条回答
Evening l夕情丶
2楼-- · 2019-03-19 00:35

I think i'v figured out why this happens, thats because the current domain needs to load the assembly too even if your loading the assembly in a diffrent app domain, the current domain needs to know about it and load it, thats because how the .NET was designed.

check here for details.

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

and when i checked the fusion logs, i found that the newly created app domain was successfully able to load the assembly from the private bin path, and the reason why you still get the exception of "File not found", because this exception belongs originally to the current app domain.

that means if you copied the assembly in current application path or to the path where the current domain is probing, you will find that you can load the assembly into your custom domain.

Hope that helps.

查看更多
迷人小祖宗
3楼-- · 2019-03-19 00:40

First make sure Plugins is a subdirectory of your AppDomain base path. PrivateBinPath will only work on subdirectories as described here

If that isn't the problem then take a look at your fusion binding logs. Use the fusion log viewer There is also a good Blog Post on that. The fusion logs will tell you where it searched for the assembly. That should tell you if your path is included in the search.

One of the other possibilities is that it is finding your assembly but not one of its dependencies. Again the fusion log viewer will tell you.

查看更多
Lonely孤独者°
4楼-- · 2019-03-19 00:47

I came across this thread when attempting to dynamically load a dll file from a directory outside of the bin directory. Long story short, I was able to accomplish this by using the AppDomain.CurrentDomain.AssemblyResolve event. Here is the code:

//--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

The method CurrentDomain_AssemblyResolve is called each time the AppDomain.CurrentDomain.Load("...") method is called. This custom event handler does the job of locating the assembly using your own custom logic (which means you can tell it to look anywhere, even outside of the bin path, etc). I hope this saves someone else a few hours...

查看更多
登录 后发表回答