Comments 14
Вот уже раза три сталкивался с этим велосипедом…
Коллеги всегда настаивали мол давай напишем «правильно» — то есть через AppDomain.
И тут начинают вылезать подводные камни пачками:
1. Код выполняемый в созданном домене имеет урезанные права (Code Access Security, что там в .Net 4.0 поменяли — не вкурсе).
Как правило при создании домена приходится настраивать ему права в Full trust.
2. У вас объект унаследован от MarshalByRefObject. А как GC созданного домена узнает, что объект еще нельзя собирать? Гуглим по InitialeLifeTimeService…
3. А значение GetExtensionName вернется по значению или по ссылке? Так как строка не MarshalByRef, то она будет сериализовываться при передаче между доменами со всеми вытекающими…
4. В 90% случаев время жизни плагина (extension) совпадает со временем жизни всего приложения — соответсвенно Unload нам никогда не потребуется.
Вобщем, если вы не пишете что-то типа IIS, то используйте MEF или что-то подобное для этих целей.
Коллеги всегда настаивали мол давай напишем «правильно» — то есть через AppDomain.
И тут начинают вылезать подводные камни пачками:
1. Код выполняемый в созданном домене имеет урезанные права (Code Access Security, что там в .Net 4.0 поменяли — не вкурсе).
Как правило при создании домена приходится настраивать ему права в Full trust.
2. У вас объект унаследован от MarshalByRefObject. А как GC созданного домена узнает, что объект еще нельзя собирать? Гуглим по InitialeLifeTimeService…
3. А значение GetExtensionName вернется по значению или по ссылке? Так как строка не MarshalByRef, то она будет сериализовываться при передаче между доменами со всеми вытекающими…
4. В 90% случаев время жизни плагина (extension) совпадает со временем жизни всего приложения — соответсвенно Unload нам никогда не потребуется.
Вобщем, если вы не пишете что-то типа IIS, то используйте MEF или что-то подобное для этих целей.
1. Ничто не даётся даром.
2 и 3. Данное решение не «гуглится», а bing`уется в msdn. Я так понимаю, что если проникнутся забытой технологией remouting, то можно получить ответы на Ваши вопросы. К тому же станут ясны многие «тонкие» моменты.
4. Сожалею, но таково ТЗ. Условия эксплуатации алгоритма неизвестны. Но возможность выгрузки сборок — основное условие.
Насчёт MEF — спасибо. Обогатился почитав статьи на хабре, возьму на заметку.
2 и 3. Данное решение не «гуглится», а bing`уется в msdn. Я так понимаю, что если проникнутся забытой технологией remouting, то можно получить ответы на Ваши вопросы. К тому же станут ясны многие «тонкие» моменты.
4. Сожалею, но таково ТЗ. Условия эксплуатации алгоритма неизвестны. Но возможность выгрузки сборок — основное условие.
Насчёт MEF — спасибо. Обогатился почитав статьи на хабре, возьму на заметку.
Забавно, свою первую (и пока крайнюю) статью я тоже посветил теме велосипеда с расширениями в .Net. Хоть и писалось все еще в эпоху 3.5, но все равно на Хабре законно дали понять что это таки велосипед. В общем, ждите еще много интересного и нового в комментариях. Полезные комментарии — это одно из главных достоинств Хабра.
Поздравляю, вы написали свой MEF
Хм неплохо :) Но я бы вынес код загрузки и работы с интерфейсом в тот же домен где реализация интерфейса живет. Так решается очень много проблем со временем жизни объектов и междоменным взаимодействием, да и разработчику плагина не надо парится с MarshalByRef.
Стоп, стоп. Сборка с плагином на самом деле загрузиться в ваш основной домен вот здесь Type[] types = asm.GetTypes(). Я тоже когда-то таким игрался, единственный путь которым мне удалось обойти, это грузить в новый домен свою сборку с классом хелпером, который уже подгружал сборки с плагинами и искал уже там типи и при необходимости их создавал.
Да это велосипед, но хотел сделать безопасную среду для исполнения плагинов. Моя статья на эту тему
Да это велосипед, но хотел сделать безопасную среду для исполнения плагинов. Моя статья на эту тему
Habrahabr — мы придумали 10001 способ реализации MEF.
Хотелось бы еще теста насколько просела производительность вызовов при использовании домена. Когда-то на rsdn.ru писали что 20х
Автор может справедливо счесть это брюзжанием, но мне почему-то в глаза бросилось
На самом деле эту проверку можно не выполнять, так как EnumerateFiles либо выбросит исключение, либо вернет таки набор с именами файлов (может даже пустой) в виде итератора
if (fileNames != null)
На самом деле эту проверку можно не выполнять, так как EnumerateFiles либо выбросит исключение, либо вернет таки набор с именами файлов (может даже пустой) в виде итератора
new FileSystemEnumerableIterator(path, originalUserPath, searchPattern, searchOption, new StringResultHandler(includeFiles, includeDirs));
(подсмотрено Reflector'ом)
Sign up to leave a comment.
Динамическая загрузка, эксплуатация и выгрузка сборок в .NET