C#: каталог пользовательских сборок
Скажем, у нас есть приложение, которое состоит из одного исполняемого файла и 5 библиотек. Регулярно все они будут храниться в одном каталоге, и библиотеки будут загружаться оттуда.
Можно ли сделать так, чтобы я мог иметь, например, некоторые из библиотек в одном каталоге с именем Lib, а остальные - в одном под названием Lib2? Так что каталог приложения будет содержать только сам исполняемый файл, а другие сборки будут содержаться в различных логических каталогах.
Как я могу это сделать? И я хотел бы знать, как выполнять загрузку сборок, а также как сделать так, чтобы сборка приложения помещала сборки в правильный каталог.
4 ответа
Вы можете добавить дополнительные пути поиска в ваш app.config, в который он смотрит, чтобы загрузить сборки. Например
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib;thirdParty" />
</assemblyBinding>
</runtime>
Вы можете увидеть более подробную информацию здесь.
Если вы хотите вручную определить, откуда брать сборки, у вас есть две возможности:
Обработайте событие 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.
Чтобы автоматически копировать сборки в папку, в которую вы хотите их поместить, вы можете установить Copy Local
true для всех ссылок и сделайте шаг после сборки, чтобы переместить их в подкаталоги.
В качестве альтернативы, вы можете установить Copy Local
в false и добавьте указанные DLL-файлы как файлы в проект в соответствующие подкаталоги, и установите Build Action
Копировать в выходной каталог (это сохранит подкаталоги)
Самый гибкий способ найти их во время выполнения - это обработать событие AppDomain.AssemblyResolve и вручную загрузить сборку, используя Assembly.LoadFile. Вам нужно, чтобы ваш код знал, какие сборки находятся в каких каталогах.
В вашем комментарии вы упоминаете добавление путей и местоположений во время выполнения. Да, вы можете, но вы должны использовать Assembly.Load() и, возможно, отражение.