Используя тип, не зная о dll - PullRequest
2 голосов
/ 29 января 2012

возможно ли использовать тип интерфейса, который определен в огромной внешней dll, без ссылки на эту dll?другими словами, будет одно ядро ​​или глобальная dll, которая ссылается на внешнюю dll, и все проекты ссылаются на эту глобальную, поэтому внешние dll скрыты от других проектов.введите мой код, зная только о глобальном проекте AllInterfaces.это может работать?и если да, что нужно сделать для такого сценария?

Ответы [ 5 ]

9 голосов
/ 29 января 2012

Можно ли использовать тип интерфейса, который определен в огромной внешней DLL, без ссылки на эту DLL в время компиляции ?

Не совсем, нет. Компилятор имеет разумное ожидание, что необходимые ему типы доступны.

Можно ли использовать тип интерфейса, определенный в огромной внешней dll, без ссылки на эту dll в runtime ?

Да . Мы добавили эту функцию в C # 4. «Правильное» имя функции - это что-то вроде «Внедрение типов с эквивалентностью типов», но все просто называют его «Без PIA».

Мотивация для этой функции наиболее очевидна для разработчиков Visual Studio Tools for Office. Разработчики VSTO пишут код C #, который настраивает, скажем, электронную таблицу Excel с некоторым управляемым кодом. Они взаимодействуют с Excel через управляемый интерфейс, но, конечно, Excel фактически предоставляет набор интерфейсов COM. Чтобы преодолеть этот пробел, команда Office предоставляет Первичную сборку взаимодействия или PIA. PIA - это огромная внешняя библиотека , которая содержит только метаданные, описывающие, как управляемые интерфейсы соответствуют неуправляемым интерфейсам объектов COM.

Проблема в том, что команда Office по умолчанию не устанавливает PIA, когда ваш клиент покупает Office! Поэтому вы должны отправить PIA с вашими настройками. А PIA настолько велика, что часто во много раз превышает размер настройки, что увеличивает продолжительность загрузки. И так далее; это ни в коем случае не идеальная ситуация.

Функция No-PIA позволяет компилятору связывать только те части PIA, которые вы фактически используете , с вашей библиотекой, так что вам не нужно поставлять PIA вместе с ней.

Теперь вы можете спросить: " что если у меня есть две настройки, которые взаимодействуют друг с другом, и обе используют интерфейс IFoo из PIA, который я не отправляю? " Среда выполнения определяет типы по сборка, из которой они произошли , поэтому два интерфейса IFoo будут считаться разными типами и поэтому не будут совместимы.

Функция "Без PIA" также учитывает это. Он проделывает тот же трюк, который вы используете в COM для решения этой проблемы: сборка указывает среде выполнения объединить все интерфейсы с одинаковым GUID в один и тот же логический тип , даже если они происходят из разных сборок. Тем самым объясняется требование о том, что каждый интерфейс, который вы используете с «без PIA», должен быть помечен, как если бы это был интерфейс взаимодействия COM с GUID.

В командной строке используйте / L вместо / R для ссылки на сборку как на сборку «без PIA».

Выполните поиск по сети «no PIA», и вы найдете больше информации об этой функции.

2 голосов
/ 29 января 2012

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

Вы можете написать интерфейс адаптера в вашей глобальной dll для исходного интерфейса и использовать его везде.

1 голос
/ 29 января 2012

Это не может быть сделано статически, но вы можете сделать это с помощью отражения.

0 голосов
/ 29 января 2012

Вы пытаетесь обмануть тип личности .CLR определяет тип по следующим свойствам:

  • Отображаемое имя сборки
  • [AssemblyVersion]
  • [AssemblyCulture]
  • Значение PublicKeyToken сборки
  • Архитектура процессора сборки (неявная)
  • Имя пространства имен типа
  • Имя типа.

Подделка имени и имени пространства имен типа isn 'Сложно, но сложно подделать свойства сборки.Вы мертвы в воде, если сборка со строгим именем (ненулевое PublicKeyToken) или если она хранится в GAC, вы не можете загрузить замену.Фальсифицировать культуру и архитектуру несложно, вам нужно будет правильно указать отображаемое имя и версию.

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

0 голосов
/ 29 января 2012

С C # 4 вы можете использовать ключевое слово dynamic.

Однако я не понимаю, как незнание интерфейса заранее поможет вам - как вы узнаете, какие методы вызывать?

...