2011-02-22 1 views
3

У нас есть система обработки правил, где каждое правило представлено классом, а все правила реализуют общий интерфейс. Иногда мы добавляем правило (класс) в сборку, но когда это правило появляется для обработки, система не может найти этот класс. Код, который мы используем для запуска правил, выглядит следующим образом.Новые классы, добавленные в сборку, не найдены через отражение

private void runClass(string dllName, string className, string methodName, string ruleNamespace) 
{ 
    Assembly _Assemblies = Assembly.LoadFrom(dllName); 

    Type _Type = null; 
    string nameSpace = _Assemblies.ManifestModule.Name.Substring(0, _Assemblies.ManifestModule.Name.ToLower().IndexOf(".dll")); 
    if (ruleNamespace.Trim() != "") 
     nameSpace = nameSpace + "." + ruleNamespace; 
    _Type = _Assemblies.GetType(nameSpace + "." + className); 
    if (_Type == null) 
     throw new Exception("Cannot find class " + className + " in " +  nameSpace + "."); 

    IRule rule = (IRule)Activator.CreateInstance(_Type); 
    rule.Process(); 
} 

Я попытался очистки сборки, восстановление с нуля, перезагрузки, вытирая DLL файлы вручную и воссоздании и несколько других вещей, которые я не могу вспомнить сейчас. Причудливая часть состоит в том, что в сборке может быть 50 правил, и 48 из них найдены, но два не являются, а два, которые не найдены, - это те, которые были только что добавлены. Может ли кто-нибудь подумать о том, что может вызвать это?

Обновление: я нашел фактический ответ и принял самый близкий к фактическому ответу, потому что он привел меня в правильном направлении. У нас есть две ветви кода: одна для dev и одна для QA на наших машинах dev. приложение является веб-службой и для его отладки, мы должны начать модульные тесты, подключиться к процессу aspnet_wp.exe, а затем установить точки останова. Причина, по которой он не мог найти классы, состоял в том, что машина указала на экземпляр QA веб-службы, поэтому любые новые классы не будут найдены; все старые были там, потому что они были развернуты в филиале ОК. Спасибо за все комментарии и, в конце концов, приведу меня в нужные места, в конечном итоге все это касается развернутого места, но не так, как вы думаете. :)

+2

Возможно, вы используете старый код. – Gabe

+3

Извините, что вы не относитесь к делу, но я думаю, что ваш код трудно читать, потому что вы используете очень странную '_Convention' для локальных переменных. Почему бы не назвать их 'thisWay', как это обычно делается на C#? –

+0

Что именно вы имеете в виду, говоря: «Иногда мы добавим правило (класс) в сборку»? Я полагаю, вы не имеете в виду добавить его во время выполнения и переписать сборку? Это не ясно. –

ответ

2

Если эта проблема сохраняется после перезагрузки, у вас есть 1 из 3 возможных проблем.

  1. Фактически вы его не размещаете.

  2. Ваше приложение использует некоторый тип механизма кэширования пользовательских сборок и не обновляется на основе отсутствия новой сборки в папке с загрузкой.

  3. Вы развертываете его, но не в нужном месте/сервере.


Если бы я должен был сделать ставку, я хотел бы видеть, что было за дверью # 3.


UPDATE
На основе комментариев: Я не понимаю, вы работаете в этом локально против развертывания на сервере.

Это говорит о том, что вы ссылаетесь на сборку по имени сборки, а не по ссылке на уровне проекта. VS кэширует сборки во время разработки и, вероятно, не обновляет локальный кеш.

Кроме того, в зависимости от типа проекта иногда возникает недоумение относительно места сборки. Например, в проектах веб-сайта VS будет счастливо (и обычно неправильно) перенастроить ваши ссылки на сборку, если он найдет копию сборки в GAC или по другому пути. Проекты веб-приложений обычно не проявляют такого поведения.

В главном проекте щелкните правой кнопкой мыши ссылку на сборку и посмотрите, где она думает, откуда загружается dll.

+0

1. он не развертывается. Это в моей собственной среде разработки, и все проекты (веб-службы и библиотеки DLL) являются частью одного и того же решения. также, похоже, это не происходит, когда оно развертывается, это только происходит в локальном развитии, и это происходит с более чем одним разработчиком. –

+0

2. Мне нужно будет изучить это. Я не знаком. –

+0

3. См. Номер 1. –

1

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

Вместо этого используйте вместо этого LoadFile. См. Пояснения по выбору контекста привязки here.

Однако сначала вы должны убедиться, что сборка действительно изменилась. Положите точку останова на этот метод, и когда он ударит, откройте файл, расположенный по адресу dllPath в Reflector (пока он еще свободен :-) и убедитесь, что вы на самом деле пытаетесь загрузить новую сборку.

Я бы начал с удаления сборки в ожидаемом месте, а затем проверить, не сработал ли код.

+0

Звучит неплохо, за исключением той части, где OP говорит, что перезагрузка не решает проблему. – NotMe

Смежные вопросы