#c# #dll #types #reflection #.net-assembly
Вопрос:
У меня есть веб-приложение, которое использует 2 пользовательских библиотеки DLL. Один из них-мини-ОРМ, который я сделал поверх Dapper, а другой-библиотека классов, содержащая все мои классы моделей. В моем ORM есть класс, который запускается при запуске, сканирует предоставленный пакет на наличие типов и создает реестр полей для использования ORM. Этот класс раньше находился в той же библиотеке классов, что и модели, и он отлично работал, так как мог находить классы в своей собственной библиотеке классов. С тех пор как я переместил его в библиотеку ORM, он (как и следовало ожидать) перестал работать из-за этой строки :
var types = Assembly.GetAssembly()
.GetTypes()
.Where(t => t.IsClass)
.Where(t => t.Namespace != null)
.Where(t => t.Namespace.StartsWith(packageName));
Я попытался заменить GetAssembly() на GetEntryAssembly (), думая, что вызывающее веб-приложение инкапсулирует все классы моделей, которые оно нашло в библиотеке моделей, но, похоже, я ошибся.
Мой вопрос в двух словах таков : есть ли способ получить доступ к типам, содержащимся в библиотеке DLL, из другой библиотеки DLL через родительское веб-приложение, которое ссылается на оба?
Ответ №1:
Да, это возможно, но способ зависит от вашего приложения.
Вы можете искать типы во всех загруженных сборках
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => t.IsClass)
.Where(t => t.Namespace != null)
.Where(t => t.Namespace.StartsWith(packageName));
Или вместо поиска всех типов во всех сборках вы можете выполнять поиск в одной сборке по имени
var types = AppDomain.CurrentDomain.GetAssemblies()
.Single(a => a.GetName().Name == packageName)
.GetTypes()
.Where(t => t.IsClass)
.Where(t => t.Namespace != null)
.Where(t => t.Namespace.StartsWith(packageName));
Приведенный выше код предполагает, что сборка уже загружена.
Если вы знаете какой — либо тип внутри сборки
var types = typeof(SomeKnownType)
.GetTypes()
.Where(t => t.IsClass)
.Where(t => t.Namespace != null)
.Where(t => t.Namespace.StartsWith(packageName));
Вышеизложенное обеспечит загрузку сборки с момента доступа к типу в сборке. Или вы можете вручную загрузить сборку, если она еще не загружена
var types = Assembly.Load(packageName)
.GetTypes()
.Where(t => t.IsClass)
.Where(t => t.Namespace != null)
.Where(t => t.Namespace.StartsWith(packageName));