C# фильтрует сборки, на которые ссылаются, при вызове сборки

У меня есть библиотека классов и решение, расположенное в разных каталогах.

из библиотеки классов я вызываю GetCallingAssembly, который возвращает исполняемый файл из решения, за которым следует вызовAssembly.GetReferencedAssemblies, который возвращает ссылки, теперь я хочу выполнить оптимизацию, чтобы отфильтровать ссылки и удалить все ссылки на пакеты, стремясь найти определенный тип.

Примечание. Я не хочу зависеть от свойства Name ссылок.

«теперь я хочу выполнить оптимизацию, чтобы отфильтровать ссылки и удалить все ссылки на пакеты» — что вы под этим подразумеваете?

Dai 27.08.2024 19:44

Что такое AggregateRoot в этом контексте?

Dai 27.08.2024 19:44

Не публикуйте изображения кода. Почтовый индекс.

Fildor 27.08.2024 21:01

@Dai Я имею в виду фильтрацию referencedAssemblies для удаления ссылок на пакеты. в настоящее время referencedAssemblies представляет собой список всех сборок, на которые ссылается вызывающая сборка, включая сборки Microsoft и AspNetCore, которые я хочу отфильтровать для оптимизации foreach.

Sarwan Surchi 27.08.2024 22:40

@Dai AggregateRoot — это базовый класс моего агрегатного типа, который я хочу найти.

Sarwan Surchi 27.08.2024 22:41

@Fildor Я думал, что это может помочь лучше понять мою цель, идея проста, поскольку я хочу посмотреть, сможем ли мы различать ссылки на пакет и проект при вызове GetReferencedAssemblies.

Sarwan Surchi 27.08.2024 22:43

@SarwanSurchi PackageReferences управляется вашей системой сборки (MSBuild), ссылки на сборки — единственное, о чем заботится csc.exe. PackageReferences обычно приводит к ссылке на сборку (но не всегда). Это не вариант «или-или».

Dai 27.08.2024 22:52

@Dai так нет возможности узнать какая сборка из полученных мною, проще говоря, созданная мной, а какая сторонняя?

Sarwan Surchi 27.08.2024 23:10

@SarwanSurchi Я не знаю, о чем вы говорите - в отношении CLR не существует такого понятия, как «сторонняя сборка».

Dai 27.08.2024 23:12

@Dai, как искать тип в ответ на вызов метода из вашей сборки? ну, чтобы помочь нам обоим понять контекст, первое, что вы делаете, это вызываете сборку, а затем получаете сборки, на которые ссылаются, против вызова, и в конечном итоге у вас есть куча сборок, в которых одна из них содержит мой тип, проблема здесь в загрузке типов каждого сборка не влияет на производительность, необходим фильтр для удаления таких сборок, как Microsoft.Extensions.DependencyInjection, Microsoft.Extensions.Logging, Microsoft.AspNetCore и т. д. Надеюсь, теперь вы поняли мою проблему :)

Sarwan Surchi 27.08.2024 23:58

«Ну, чтобы помочь нам обоим понять контекст, первое, что вы делаете, это вызываете сборку, а затем получаете сборки, на которые ссылаются, против вызова, и в конечном итоге вы получаете кучу сборок, в которых одна из них содержит мой тип», - Нет, это не так. способ сделать это. Вместо этого я предлагаю вам перечислить типы из всех загруженных сборок в текущем AppDomain — нет необходимости перемещаться по графу ссылок на сборки.

Dai 27.08.2024 23:59

AppDomain не поможет, поскольку текущая сборка не ссылается на вызывающую сборку.

Sarwan Surchi 28.08.2024 00:10

@SarwanSurchi ...Я думаю, ты неправильно понимаешь, что такое AppDomain.

Dai 28.08.2024 00:13

правда, моя ошибка, хотя для сборки в AppDomain требуется ссылка.

Sarwan Surchi 28.08.2024 01:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
14
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

... если вы просто хотите найти все типы во всех загруженных сборках, производных от вашего типа AggregateRoot, без поиска сборок, которые не могут содержать подкласс, тогда все, что вам нужно, это:

public static IEnumerable<Type> GetAllTypesDerivedFromAggregateRoot()
{
    Assembly[] asses = AppDomain.Current.GetAssemblies();

    Type typeofRoot = typeof(AggregateRoot);
    AssemblyName mustReferenceThisAssembly = typeofRoot.Assembly.GetName();

    List<Assembly> candidates = asses
        .Where( ass => ass
            .GetReferencedAssemblies()
            .Any( ra => AssemblyName.ReferenceMatches( reference: ra, definition: mustReferenceThisAssembly ) )
        )
        .ToList();

    foreach( Assembly candidate in candidates )
    {
        Type[] types = candidate.GetTypes();
        foreach( Type t in types )
        {
            if ( typeofRoot.IsAssignableFrom( t ) ) yield return t;
        }
    }
}

Ты справился, @Dai, спасибо. не знал, что AssemblyName.ReferenceMatchesDefinition() существует и это все, что мне нужно. однако не думаете ли вы (в моем случае) лучше использовать вызывающую программу вместо AppDomain, что приводит к меньшему количеству сборок, с которыми приходится иметь дело? и вот мой взлом кода, если вам интересно. var ideals = caller.GetReferencedAssemblies().Where(x => Assembly.Load(x).GetReferencedAssemblies() .Any(x => AssemblyName.ReferenceMatchesDefinition(x, mustReferenceAssembly)));

Sarwan Surchi 28.08.2024 01:32

@SarwanSurchi "не думаешь ли ты (в моем случае) использовать вызывающую программу вместо AppDomain, что приводит к меньшему количеству сборок, с которыми приходится иметь дело?" - Нет, потому что, используя ваш подход, вы не получаете полного представления о своей программе.

Dai 28.08.2024 01:33

ну, у меня есть сборка вызывающего объекта, которая запустила метод, первое, что я делаю, это проверяю, находится ли мой тип в самой сборке вызывающего объекта для оптимизации. если нет, то я использую вызывающую программу для получения ссылок, которые удовлетворяют условию, должны ссылаться на сборку агрегатного корня. более того, большое спасибо, это было здорово.

Sarwan Surchi 28.08.2024 01:38

@SarwanSurchi Другая причина: ваш подход просто не будет работать, если между реальным вызывающим объектом и вашей сборкой находится прокси-сборка или код, сгенерированный во время выполнения (например, такой, который мы получаем с Entity Framework, Linq и т. д.).

Dai 28.08.2024 01:40

что ж, будем надеяться, что со мной этого не произойдет (хотя я не уверен, насколько это распространено), не хочу иметь дело со сложностями на этом уровне и идти глубже.

Sarwan Surchi 28.08.2024 01:43

В конце концов, не уверен, что вам интересно, но если да, то вызывающим объектом является API с несколькими библиотеками классов, вызывающим расширение AddEventSourcing, которое запускает то, что мы обсуждали, а AddEventSourcing находится в отдельном решении, которое является моей структурой поиска событий. Теперь причина, по которой мое расширение не является универсальным, когда я просто отправляю свой агрегат, не заключается в том, что клиенты заставляют указывать агрегат. вместо этого я нахожу дополнительные агрегаты и преобразую свои общие репозитории в IoC.

Sarwan Surchi 28.08.2024 01:58

Универсальные репозитории @SarwanSurchi — это антишаблон. Не используйте их.

Dai 28.08.2024 02:04

Согласитесь, с ними сложно справиться, спасибо за урок, но какая практика способствует этому? наверное состав? @Дай

Sarwan Surchi 28.08.2024 02:09

@SarwanSurchi Композиция не имеет к этому никакого отношения. Речь идет о том, чтобы не тратить время на добавление абстракций, которые не приносят никакой пользы и только создают антиработу в долгосрочной перспективе.

Dai 28.08.2024 02:15

ну, в моей ситуации мне нужны дженерики для достижения моей цели, пока не могу придумать лучшего способа.

Sarwan Surchi 28.08.2024 02:34

@SarwanSurchi Похоже, вы в целом довольны моим ответом - даже если только в качестве вдохновения, можете ли вы хотя бы отметить его как принятый ответ?

Dai 29.08.2024 08:45

во что бы то ни стало, только что принял и еще раз спасибо.

Sarwan Surchi 29.08.2024 21:59

Другие вопросы по теме