Сперва дам два определения. Они не точные, не претендуют на истину, просто для пояснения, что же я имею в виду.
Библиотека - это когда пользовательский код управляет порядком вызовов. Например, OpenGL.
Фреймворк - это когда пользовательский код вызывается по наступлению некоторых условий. Например, GLUT.
Ещё раз повторюсь, что это не правильные определения, это просто определения для разграничения двух предельных понятий.
Библиотеки довольно легко совмещать. Например, я могу распаковывать с помощью zlib скрипт последовательности вызовов OpenGL и тут же их выполнять. Но они редко выполняют много стандартных действий сразу, поэтому и существуют фреймворки.
Фреймворки совмещать тяжело. Требуется завести машину состояний, чтобы правильно совместить фреймворки (приём XML по сети с вызовом обработчиков элементов надо совместить с GLUT).
(Что интересно, многие ОО библиотеки сделаны в стиле фреймворков.
"Наследуем и нас вызовут." Кстати, пользовательский интерфейс для ФЯ тоже недалеко ушёл)
Я подумал, что параллелизм позволяет легко совмещать фреймворки.
У нас, например, есть пользовательский интерфейс и моделирование. Они работают параллельно. Моделирование работает с хранилищем сигналов, периодически сообщая пользовательскому интерфейсу об изменениях, а пользовательский интерфейс может (синхронно) спросить у моделирования (по каналу) о нужном ему участке сигналов.
Здесь моя мысль заканчивается.
Осталось только посетовать на отсутствие в C# каналов а-ля Chan/TChan Хаскеля или хотя бы безопасной посылки сообщений а-ля Эрланг, и моя миссия выполнена. ;)