2012-01-09 2 views
2

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

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

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

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

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

С наилучшими пожеланиями, Карлос

ответ

0

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

  AppDomain.Unload(yourAppDomain); 

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

0

Возможно, DynamicMethod - это то, что вы ищете.

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

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

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

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

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

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

Панос

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