Пользовательский AppDomain и PrivateBinPath - PullRequest
9 голосов
/ 08 июля 2011

Я использую 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);

Я получаю исключение Файл не найден при использовании Загрузка на моем созданном домене приложений.

Спасибо.

Ответы [ 3 ]

9 голосов
/ 09 июля 2011

Сначала убедитесь, что плагины - это подкаталог вашего AppDomain базового пути.PrivateBinPath будет работать только с подкаталогами, как описано здесь

Если это не проблема, взгляните на свои журналы привязки Fusion.Используйте Fusion Log Viewer Есть также хороший Блог .Журналы Fusion скажут вам, где он искал сборку.Это должно сказать вам, включен ли ваш путь в поиск.

Одной из других возможностей является то, что он находит вашу сборку, но не одну из ее зависимостей.Снова программа просмотра журнала Fusion скажет вам.

7 голосов
/ 22 мая 2013

Я сталкивался с этой темой при попытке динамически загрузить файл dll из каталога вне каталога bin.Короче говоря, я смог сделать это с помощью события 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("...").Этот пользовательский обработчик событий выполняет поиск сборки, используя вашу собственную пользовательскую логику (что означает, что вы можете указать, чтобы она смотрела где угодно, даже за пределами пути корзины и т. Д.).Надеюсь, это сэкономит кому-то еще несколько часов ...

5 голосов
/ 12 июля 2011

Я думаю, я понял, почему это происходит, потому что текущий домен должен загружать сборку тоже, даже если вы загружаете сборку в другой домен приложения, текущий домен должен знать об этом и загружать его, вот и всепотому что .NET был разработан.

проверьте здесь для получения подробной информации.

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

и когда я проверил журналы Fusion, я обнаружил, что недавно созданный домен приложения успешно смог загрузить сборку изпуть к частной корзине и причина, по которой вы по-прежнему получаете исключение «Файл не найден», потому что это исключение изначально принадлежит текущему домену приложения.

, что означает, что вы скопировали сборку в текущий путь приложения илипо пути, по которому проверяется текущий домен, вы обнаружите, что можете загрузить сборку в свой пользовательский домен.

Надеюсь, это поможет.

...