Подтвердить что ты не робот

Как ссылаться на сборку в mvc во время выполнения

В моем приложении ASP.NET MVC у меня есть файл вида (.cshtml), который ссылается на внешнюю библиотеку, которую он будет загружать во время выполнения. поэтому после запуска приложения я загружаю сборку Assembly.Load и регистрирую контроллеры по своему собственному ControllerFactory, и все в порядке.

Но в некоторых представлениях, которые имеют ссылки на динамически загруженную сборку, выдает:

Сообщение об ошибке компилятора: CS0234: Тип или имя пространства имен "MyDynamicNamespace" не существует в пространстве имен "MyApp" (вам не хватает ссылки на сборку?)

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

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

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

4b9b3361

Ответ 1

1) Я бы не рекомендовал, чтобы ваши представления напрямую использовали внешние ссылки или динамически загруженные внешние ссылки. Прочтите это, если ваше представление взаимодействует с контроллером. Сделайте ваш контроллер подает объект данных в ваше представление, которое известно во время сборки вашим приложением (другими словами, объект, известный вашему веб-приложению во время сборки). Это полностью изолировать (абстрактный) плагин определенного бизнеса от вашего представления. Затем сделайте ваш контроллер взаимодействующим с "плагином".

2) Я не знаю, как работает ваш "пользовательский factory", но в настоящее время мы больше не создаем никаких "настраиваемых фабрик". Вместо этого мы используем контейнеры для инъекций зависимостей, такие как Microsoft Unity (или Ninject, или Castle Windsor или т.д.). Создание "настраиваемых фабрик" очень старомодно, и вы в основном изобретаете колесо, которое было разрешено с помощью инъекции зависимостей.

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

Динамически загружать тип из внешней сборки

4) Как правило, конструкция плагина предоставляет интерфейсы, которые известны вашему основному веб-приложению во время сборки. То, что скрывает дизайн плагина, - это реализация, которая может изменяться с одного плагина на другой. Важно то, что каждый плагин реализует те же общедоступные интерфейсы, которые ожидаются вашим основным веб-приложением. Обычно у вас будут эти интерфейсы в отдельном "общем" проекте, на который ссылаются как ваше основное веб-приложение, так и ваш плагин, который реализует эти интерфейсы. Поэтому из вашего основного веб-приложения вы узнаете, что такое публичные интерфейсы ваших плагинов, вы можете динамически загружать внешнюю сборку и использовать отражение С# для поиска классов, которые реализуют эти интерфейсы, и загружать их в контейнер для инъекций зависимостей. Кроме того, любой, кто захочет разработать плагин для вашего веб-приложения, должен будет реализовать интерфейсы, определенные в вашем "общем" проекте.

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

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

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

Надеюсь, что это поможет!

Ответ 2

Как администратор Sys, я бы рекомендовал период обслуживания, особенно если файл, который вы заменяете, вызывает что-то еще. Даже если ваш период обслуживания составляет всего полчаса, это хорошая практика.

Что касается DLL и перекомпилировать... как правило, рабочий процесс IIS (служба, запускающая пул приложений) будет перерабатываться с регулярными интервалами на основе конфигурации IIS и использования памяти. Когда это произойдет, приложение будет перекомпилировано, если что-то потребует JIT. Он также завершает все открытые сеансы пользователя, когда он физически останавливается, а затем снова запускается. Рабочий процесс также контролирует корневой каталог (как вы упомянули) для любых изменений файла. Если какой-либо из них найден, перекомпиляция принудительно. Просто потому, что зависимость изменена, не заставляет перекомпилировать. Если вы предварительно компилируете свою DLL, остается только компилировать любой код внутри вашего фактического файла ASPX, и это использует JIT, который компилируется каждый раз. Из того, что вы описали IIS, не нужно перекомпилировать или перезапустить, звучит как другая проблема, когда IIS висит при замене файла. Может потребоваться, чтобы администратор sys рассматривал журналы IIS.

Удачи!

http://msdn.microsoft.com/en-us/library/ms366723.aspx

http://msdn.microsoft.com/en-us/library/bb398860.aspx

Ответ 3

Вот заметка, которая может помочь: если вы не загружаете свои сборки из каталога /bin, вам необходимо убедиться, что путь к сборкам можно обнаружить:

AppDomain.CurrentDomain.AppendPrivatePath(path_to_your-dyna_assembly);