Не все сборки загружаются в AppDomain из папки bin

У меня есть следующий метод, который должен получить список загруженных локальных (в папке bin) сборок:

static IEnumerable<Assembly> GetLocalAssemblies()
    {
        Assembly callingAssembly = Assembly.GetCallingAssembly();
        string path = new Uri(Path.GetDirectoryName(callingAssembly.CodeBase)).AbsolutePath;

        var assemblies = AppDomain.CurrentDomain.GetAssemblies();
        return assemblies.Where(x => !x.IsDynamic && new Uri(x.CodeBase).AbsolutePath.Contains(path)).ToList();
    }  

Но в списке сборок отсутствует пара сборок, которые мне нужны. Сборки, которые мне нужны, являются управляемыми (C# .net 4), упоминаются в проекте и присутствуют в папке bin.

Почему двоичные файлы, присутствующие в папке bin, НЕ проникают в домен приложений при запуске приложения?

4 ответа

Решение

У Адиля это есть, но более подробно:

.NET CLR использует компиляцию Just-In-Time. Помимо прочего, это означает, что он загружает сборки при первом использовании. Таким образом, несмотря на то, что сборки ссылаются на используемую сборку, если CLR еще не использовала ссылки для выполнения программы, они не загружены и поэтому не будут отображаться в списке сборок в текущем домене приложений.

Еще одна вещь, которая может или не может применяться, это то, что если у вас есть та же версия сборки в GAC, CLR использует GAC преимущественно над локальными сборками, ЕСЛИ УКАЗАНО путь к этим сборкам указан в переменной среды DEVPATH. Если это так, и CLR использует копию GAC любой из "отсутствующих" сборок, они будут иметь разные значения CodeBase и не будут отображаться в результатах вашего запроса Linq.

Еще одна вещь: вы можете рассмотреть возможность использования свойства Location вместо свойства CodeBase. Свойство Location содержит абсолютный путь к сборке, которая была загружена во время выполнения. Свойство CodeBase немного отличается и может не совпадать для всех сборок в полной сборке проекта.

CurrentDomain.GetAssemblies() возвращает только загруженные сборки, а не все сборки, доступные в папке выполнения.

Вот что говорит по этому поводу Microsoft: "Метод GetAssemblies для получения списка всех сборок, которые были загружены в домен приложения". кликните сюда

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

Если у вас есть контроль над кодом в сборке, на которую ссылаются, я бы рекомендовал создать фиктивный метод, который вы выполняете в начале своей программы, что заставит сборку загружаться в CLR.

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