Представьте ситуацию, когда наша сервисная система предоставляет ряд функциональных сервисов, и в будущем будут добавлены новые функциональные сервисы, и функциональные сервисы могут потребоваться изменения или удаление. Распространённым базовым требованием к такой сервисной системе является нельзя остановить работу сервисной системы при добавлении/удалении/обновлении функциональных сервисов. Обычно «плагины горячей замены» можно реализовать очень просто, инкапсулируя каждый сервис в DLL плагинов, но «горячая замена» («динамическая замена») плагинов становится проблемой. Причина в том, что когда мы удаляем плагин Dll из сервисной системы, сервисная система всё ещё сохраняет базовую ссылку на DLL, и если вы попытаетесь удалить или перезаписать DLL, Windows появляется сообщение вроде «используется DLL».
Так как же решить эту проблему? Думаю, есть как минимум два варианта:
(1) Используйте AppDomain. Загрузка плагинов в новый AppDomain и удаление AppDomain чисто удаляет DLL плагина из сервисной системы. Недостаток такого подхода в том, что нужно управлять множеством AppDomains (потому что у вас очень много функциональных сервисов), а коммуникация между AppDomains происходит удалённо, что добавляет множество ненужных головных болей в нашу систему. Если интересно, можете попробовать и этот вариант, а я предпочитаю второй.
(2) Скопировать плагин Dll в память, а затем загрузить его в память. Таким образом, DLL-файлы на жёстком диске могут быть перезаписаны или удалены по желанию. Ранее мы загружали плагин Dll прямо с жёсткого диска, вот так:
Теперь нам нужно повернуть за новый угол:
Это решает проблему «динамической замены» плагинов.
|