С#: пользовательский каталог сборки

Скажем, у нас есть приложение, состоящее из одной исполняемой и 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() и, возможно, отражение.