С#: пользовательский каталог сборки
Скажем, у нас есть приложение, состоящее из одной исполняемой и 5 библиотек. Регулярно все они будут содержаться в одном каталоге, и библиотеки будут загружены оттуда.
Можно ли сделать так, чтобы у меня могли быть, например, некоторые из библиотек в одном каталоге под названием Lib, а остальное в одном - Lib2? Чтобы каталог приложений содержал только сам исполняемый файл, а остальные сборки содержались в различных логических каталогах.
Как я могу это сделать? И я хотел бы знать, как выполнять загрузку сборок, но также, как заставить здание приложения поместить сборки в правильный каталог.
Ответы
Ответ 1
Вы можете добавить дополнительные пути поиска к вашему app.config, чтобы он загружал сборки. Например
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib;thirdParty" />
</assemblyBinding>
</runtime>
Вы можете увидеть более подробную информацию здесь.
Ответ 2
Если вы хотите вручную управлять местом получения сборок, у вас есть две возможности:
-
Обработайте событие AppDomain.AssemblyResolve (как описано SLaks). Вот фрагмент кода:
static void Main(string[] args)
{
...
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
...
}
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string assembliesDir = "your_directory";
Assembly asm = Assembly.LoadFrom(Path.Combine(assembliesDir, args.Name + ".dll"));
return asm;
}
-
Создайте домен с собственными настройками (установив ApplicationBase или PrivateBinPath свойства объекта AppDomainSetup).
Итак, если вы хотите продолжить работу в текущем домене, вам нужно использовать метод 1.
Ответ 3
Чтобы автоматически копировать сборки в папку, в которой вы хотите, вы можете установить Copy Local
в true для всех ссылок и сделать шаг после сборки, чтобы переместить их в подкаталоги.
В качестве альтернативы вы можете установить Copy Local
в значение false и добавить связанные DLL файлы в качестве файлов в проекте в соответствующие подкаталоги и установить Build Action
для копирования в выходной каталог (это сохранит подкаталоги)
Самый гибкий способ заставить runtime найти их - обработать событие AppDomain.AssemblyResolve и вручную загрузить сборку, используя Assembly.LoadFile. Вам потребуется какой-то способ для вашего кода узнать, какие сборки находятся в каталогах.
Ответ 4
В своем комментарии вы указываете добавление путей и местоположений во время выполнения. Да, вы можете, но вы должны использовать Assembly.Load() и, возможно, отражение.