Использование System.Addin со сборкой, сгенерированной в памяти - PullRequest
2 голосов
/ 09 января 2012

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

Пользователь вводит допустимое выражение в текстовое поле, и я должен предоставить результаты.В настоящее время я внедряю выражение в статический метод сборки, сгенерированной в памяти, следуя инструкциям в http://blogs.msdn.com/b/abhinaba/archive/2006/02/09/528416.aspx.. Затем я использую отражение, чтобы вызвать конкретный метод и вернуть результат.

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

При поиске какчтобы выгрузить сборку, я обнаружил пространство имен System.Addin.Это именно то, что я хочу: загрузка сборки на другой домен приложений, который я могу отменить последним.Он даже инкапсулирует все отражения.

Единственная проблема, с которой я столкнулся сейчас, заключается в том, что AddInStore ожидает путь к файлу, но все мои сборки генерируются в памяти, устанавливая для свойства GenerateInMemory CompileParameters, используемого в true.Обязательно ли записывать мои сборки на диск?Или можно использовать сборку, скомпилированную во время выполнения, непосредственно в качестве надстройки?

С уважением, Карлос

Ответы [ 2 ]

0 голосов
/ 30 марта 2012

Может быть DynamicMethod - это то, что вы ищете.

Если нет, то вы можете взглянуть на IronPython .Это очень легко добавить в ваше приложение и достаточно мощный.Конечно, это будет медленнее, чем скомпилированный код C #, но я не уверен, будет ли это медленнее, чем компиляция + отражение.

Конечно, вы можете делать то, что упоминает MZN.Вы можете:

  1. Изменить свой класс компилятора, чтобы он был производным от MarshalByRefObj.Это необходимо для CLR для создания прокси-объекта.Вам придется немного проверить .Net Remoting.Не слишком много.
  2. Создайте свой собственный домен приложений,
  3. Наконец, вызовите одну из перегрузок CreateInstanceFromAndUnwrap, чтобы загрузить ассемблер с вашим классом компилятора на новый домен приложений и создать экземпляр вашего компилятора наЭто.Он вернет вам объект прокси.Затем выполните компиляцию с помощью прокси-объекта.Скомпилированная сборка будет загружена на новый домен приложений.Когда вы решаете, что эта сборка вам больше не нужна, или когда вы достигли максимального количества скомпилированных сборок, вы можете сделать вызов, упомянутый MZN, и выгрузить AppDomain и все загруженные сборки.Затем повторите все заново со свежего домена приложений.

Я думаю, что самый простой способ - использовать IronPython.

В данный момент я работаю над приложением на основе MAF, которое включает компиляциюкода C # на месте (с использованием System.CodeDom).Он похож на ваш, но в моем случае компиляция происходит только после обновления.Так что у меня нет проблем со многими загруженными сборками "скриптов".Также я строю сборки в файловой системе.

С уважением и удачи,

Panos

0 голосов
/ 18 января 2012

Я не понимаю, для чего вы используете AddInStore (выгрузка сборок?), Но вы можете просто выгрузить домен приложения (в котором, как вы сказали, вы смогли создать свою динамически загруженную сборку):

            AppDomain.Unload(yourAppDomain);

Или, может быть, вы столкнулись с гораздо более серьезной проблемой!

...