Динамическая перезагрузка классов в C # (цикл всех экземпляров) - PullRequest
0 голосов
/ 28 марта 2011

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

По сути, я хотел бы получить список всех ссылок на определенный объект. Я знаю, что это может быть совершенно невозможно в C #, поскольку это сильно зависит от языка, хранящего список всех объектов, ссылающихся на определенный объект. Не имеет значения, является ли реализация невероятно медленной, если она работает правильно.

Я вставил здесь псевдокод для того, что я хочу сделать: http://nopaste.dk/p3059

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

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

Ответы [ 3 ]

1 голос
/ 28 марта 2011

Если вы еще не проверили его, вам стоит взглянуть на Managed Extensibility Framework . Это сэкономит вам много времени, а не изобретет колесо.

0 голосов
/ 28 марта 2011

Если вы пойдете по пути самостоятельного управления этим, имейте в виду, что все ссылки через AppDomain будут проходить через ссылки прокси, а не указывать на экземпляр.Все ваши маршаллированные экземпляры также должны быть производными от MarshalByRefObject для генерации прокси.

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

  • Сериализировать состояние игры, используя что-то вроде DataContractSerializer, который может поддерживать ссылки.
  • Выгрузить весь игровой домен приложения
  • Загрузите новый игровой домен приложения
  • Десериализуйте игровое состояние, которое теперь будет преобразовываться во вновь загруженные типы при восстановлении.
0 голосов
/ 28 марта 2011

Слабая ссылка уже существует.Это достойная идея.

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

Кроме того, для загрузки .dll в стиле "плагина", проверьте MEF.Он абстрагирует много работы для вас.

http://mef.codeplex.com/

...