AppDomain.CurrentDomain.AssemblyРешить возможные проблемы с доверием или другими проблемами, о которых я должен знать - PullRequest
2 голосов
/ 03 января 2011

В настоящее время я использую следующий код:

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
    var name = args.Name + ".dll";
    using (var input = Assembly.GetExecutingAssembly()
                               .GetManifestResourceStream(name)) {
        Assembly dll = input != null
            ? Assembly.Load(input.ToArray())
            : null;

        return dll;
    }
};

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

Есть ли какие-либо проблемы с доверием или ошибки, о которых мне следует знать при использовании этого типа динамической загрузки DLL?

Проблемы среднего доверия не кажутся проблемой, однако нашиВ конечном итоге DLL требует полного доверия.Я предполагаю, что это может быть связано с разрешениями безопасности или чем-то в этом роде.

Обновление

После просмотра документов я снова заметил одну строку, которую пропустил раньше, и я думаю, что она связана с моейпроблема.

"Начиная с .NET Framework 4, событие ResolveEventHandler вызывается для всех сборок , включая сборки ресурсов. В более ранних версиях событие не вызывалось для сборок ресурсов. Еслиоперационная система локализована, обработчик может вызываться несколько раз: по одному разу для каждой культуры в резервной цепочке. "

Тогда как в 3.5 это не было.Я опубликую обновленную информацию после подтверждения.

1 Ответ

8 голосов
/ 04 января 2011

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

  1. args.Name на самом деле является полным именем сборки, а не просто именем, но может содержать версии и т. Д. Передача этого значения в конструктор AssemblyName анализирует только простое имя. Я сомневаюсь, что это проблема, с которой вы столкнулись.

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

  3. Не используйте исполняемую сборку, получите доступ к правильной сборке, содержащей ресурс, через явную ссылку на тип, содержащийся в этой сборке. Просто замените THIS_CLASS в приведенном ниже примере. Это мое лучшее предположение относительно основной причины проблемы, с которой вы столкнулись.

  4. Вы должны пойти дальше и кешировать результаты этого метода в глобальный словарь. Зачем? Вас могут вызвать несколько раз для загрузки одной и той же сборки, и при каждом вызове вы должны возвращать один и тот же экземпляр сборки. Ваш пример загружает сборку снова и снова.

  5. Добавить подробное ведение журнала, записать, какую сборку вы ищете, имя ресурса, с которого вы пытаетесь загрузить, сборку, с которой вы его загружаете, если поток равен нулю, результат метода Load () и т. Д. 1021 *

    static Dictionary<String, Assembly> _assemblies = new Dictionary<String, Assembly>(StringComparer.OrdinalIgnoreCase);
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
        {
            Assembly dll;
            var name = new AssemblyName(args.Name).Name + ".dll";
            if(!_assemblies.TryGetValue(name, out dll))
            {
                Assembly res = typeof(THIS_CLASS).Assembly;
                using (var input = res.GetManifestResourceStream(name))
                {
                    if (input == null)
                    {
                        LogWrite("Assembly {0} does not contain {1}", res, name);
                        return null;
                    }
                    if (null == (dll = Assembly.Load(input.ToArray(), AppDomain.CurrentDomain.Evidence)))
                    {
                        LogWrite("Assembly {0} failed to load.", name);
                        return null;
                    }
                    LogWrite("Loaded assembly {0}.", name);
                    _assemblies[name] = dll;
                    return dll;
                }
            }
            return dll;
        };
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...