2013-06-18 2 views
2

Я пишу код для реализации архитектуры подключаемого модуля. Я определил интерфейс, назовем его IThing в пространстве имен MyStuff, для плагина, и у меня также есть код для динамического создания экземпляра подключаемого модуля из DLL. Мой код делает это, просматривая обнажает классы, поля и методы, и в конечном итоге тестирования, что он находит с:Когда .Net-интерфейсы считаются эквивалентными?

if (typeof(IThing).IsAssignableFrom(instType)) 

Это все хорошо и хорошо работает, когда интерфейс реализуется что-то в моем собственном коде, то есть ссылки на сборка, которая обеспечивает определение MyStuff.IThing.

Другой разработчик, в другой компании, расположенной в другой стране, пишет подключаемый компонент.

Я отправил определение интерфейса, то есть источник C#, для MyStuff.IThing разработчику, и он включил его в свой код.

Проблема, которую мы увидели в первую очередь, заключается в том, что его компонент, хотя он реализовал MyStuff.IThing, не прошел бы вышеописанный тест IsAssignableFrom. Причина неудачи заключается в том, что он имеет определение интерфейса в другой сборке (естественно), хотя он имеет одно и то же пространство имен и определение интерфейса не изменилось. Решение здесь достаточно простое, что я посылаю ему сборку DLL, содержащую интерфейс.

Мой вопрос заключается в следующем: учитывая, что пространство имен совпадает и определение интерфейса идентично, почему важно, какая сборка находится в нем? Если сборка A содержит MyStuff.IThing с точно таким же определением интерфейса, как MyStuff.IThing в сборке B, почему эти сборки не взаимозаменяемы для приложений, которые хотят работать с экземпляром MyStuff.IThing?

+0

Это важно, потому что имя сборки является частью идентификатора типа. –

ответ

3

Учитывая, что пространство имен совпадает и определение интерфейса идентично, почему это важно, какая сборка находится в нем?

Выбор лечения этих интерфейсов как эквивалент затруднит сравнивать интерфейсы: вместо сравнения фиксированного набора элементов (то есть полное имя и сборки) CLR потребуется сравнить квалифицированное имя, и список всех свойств и всех методов, а также их типы аргументов, которые будут рекурсивными. Это будет непомерно медленным, особенно если вы хотите сделать это последовательно и включить классы и struct s в аналогичную схему сравнения.

Примечание: при совместном использовании DLL с разработчиком в другой стране убедитесь, что ваша сборка имеет strong name. Это обеспечит, чтобы вы оба ссылались на одну и ту же сборку и обнаруживали несоответствия на ранней стадии. Например, если вы измените свой интерфейс, но другой разработчик отправит вам плагин, скомпилированный со старой DLL, плагин не сможет загрузить.

+0

Хорошие моменты, спасибо. Я предположил, что сравниваются методы, свойства и т. Д. –

0

.NET не проверяет свойства и их типы и делает вывод об эквивалентности.

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