Модульная система в.NET может быть изменена во время выполнения

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

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

Есть ли рамки или способ замены / выгрузки отдельных частей кода? Как это делается в реальных приложениях? Может ли быть обходной путь? Или я выбрал неправильный набор инструментов?

5 ответов

Решение

Вам нужна какая-то система плагинов с четко определенными интерфейсами. Затем вы загружаете исполняемые файлы (ваш плагин *.dll) и создаете из него объекты, а затем выполняете на нем методы. Когда вы создаете систему, в которой объекты из ваших плагинов должны создаваться через ваш IPluginManager, у вас не возникает проблем с заменой кода во время выполнения.:)

Или же

У вас есть что-то вроде папки с файлами *.cs, которая будет по требованию скомпилирована (в памяти) и создаст из них объекты, которые вы хотите использовать, и вызовите для них методы. Что в основном то же самое, что и выше, без компиляции во время выполнения.

Оттуда вы можете сделать дальнейшие улучшения.

РЕДАКТИРОВАТЬ: Как вы написали, единственная проблема без использования AppDomain заключается в том, что после загрузки не может быть выгружены сборки. Но это не проблема.

Я не думаю, что вам нужны отдельные домены приложений: вы можете динамически загружать сборки в текущем домене приложений. И каждая сборка, вероятно, должна реализовывать определенные интерфейсы (в зависимости от вашего использования). Вы можете использовать класс FileSystemWatcher, например, для загрузки / выгрузки сборок по мере необходимости.

См. http://msdn.microsoft.com/en-us/library/25y1ya39(v=vs.110).aspx

Вы можете взглянуть на MEF. Он расшифровывается как: Managed Extensibility Framework.
Вот еще одна статья об этом MEF на codeproject.

Используется для загрузки dllэто во время выполнения, составляя их. Это то, что обычно используется для plugins или что-то еще, вы как бы падаете в папку и ожидаете, что она запустится.

Вот ссылка на еще несколько учебных пособий: Где я могу узнать о MEF?

Да, вы правы, просто выгрузить сборку невозможно (только домены приложений). Но я думаю, что одной из особенностей ASP.Net vNext является возможность иметь только сборки в памяти, и когда вы просто изменяете исходный код на диске, он автоматически компилируется и загружается. Для этого должен существовать механизм выгрузки предыдущей версии.

Я думаю, что они делают это, просто создавая домен приложений, в который все сборки загружаются снова, чтобы избежать любого междоменного взаимодействия. Но я действительно не знаю, и, возможно, если бы вы больше изучили механизм их работы в ASP.NET, вы, возможно, найдете хорошее решение. Больше информации о горячих темах от vNext вы также можете найти в блоге Scotts.

Ну, я нашел 2 решения, которые работают для меня, которыми я хотел бы поделиться. Первый заключается в использовании CollectibleAssembly и определить типы. Это, конечно, немного сложно, и этот тип динамических сборок накладывает ряд ограничений. Другой вариант - использовать язык сценариев, такой как IronPython или же IronRuby, Также отличительной особенностью нового компилятора Roslyn является то, что он также предоставляет API-интерфейсы сценариев, ранее недоступные в.NET Framework. Более того, скриптовые языки Roslyn очень похожи на свои полноценные эквиваленты (C# или VB). И я также нашел крошечный пример его способности.

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