Да, это вполне возможно. Вы просто выставляете компоненты, написанные в 4.0, как COM-объекты. Хостинговое приложение 2.0 просто использует их как COM-объекты и не знает, являются ли они родными, 2.0, 4.0 или чем-то еще. COM - это общий интерфейс, который обе версии времени выполнения должны реализовывать одинаково.
Новая внутрипроцессная поддержка SxS в 4.0 означает, что при загрузке COM-объекта на основе 4.0 он загружает требуемое время выполнения вместо попытки запуска на 2.0, поэтому обе среды выполнения присутствуют в процессе, управляющем своими собственными объекты. Хотя вы не можете напрямую передавать объекты CLR между ними, вы можете передавать интерфейсы COM, и CLR прозрачно оборачивает ваши объекты в интерфейсы COM для вас.
Я не знаю, можно ли сделать одну сборку взаимодействия для обеих версий. Но ясно, что вы можете написать сборку взаимодействия в C # в 2.0, экспортировать ее в .tlb, а затем импортировать в сборку в 4.0. Это дает вам две совпадающие сборки взаимодействия, описывающие идентичные интерфейсы COM. (Или просто создайте один и тот же источник C # в проекте сборки каждой версии).
Обновление бонуса: Будет ли полученное приложение основано на COM (с какими бы то ни было проблемами)?
Зависит от того, как вы на это смотрите. Авторы компонентов будут делать их как компоненты COM. Поэтому хост-приложение должно найти и загрузить их как компоненты COM. Это означает дурачиться с GAC, реестром или манифестами SxS, что гораздо менее чисто, чем просто указывать авторам компонентов отбрасывать их сборки в определенном каталоге, чтобы вы могли загрузить их с отражением.
И это оказывает влияние во время выполнения: когда хост имеет ссылку на компонент, будет задействован не один, а три объекта. Хост имеет ссылку на RCW, который имеет указатель на интерфейс COM, реализованный CCW, который, в свою очередь, содержит ссылку на фактический компонент. CCW в середине - это COM-объект с подсчетом ссылок, а RCW хоста имеет финализатор, который вызывает Release
на CCW, и когда он уничтожается, он освобождает GCRoot
, который поддерживает действительный компонент.
Это означает, что - при достаточно сложном расположении указателей обратного вызова и т. Д. - система может столкнуться с проблемами подсчета циклических ссылок, когда все отключенные «островки» объектов содержат ссылки друг на друга, и поэтому они никогда не получат перераспределена.