c# — Получить список объектов типа из другой библиотеки DLL

#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));