Как правильно объяснили другие ответы, вашей основной программе требуется ссылка на библиотеку B, поскольку библиотека A открыла тип библиотеки B через собственный публичный API. То есть Node
публично реализует INode<T>
, что делает этот тип видимым для основной программы.
Обычно правильное решение - просто добавить ссылку на библиотеку B в основную программу. В конце концов, основной программе, безусловно, понадобится библиотека B во время выполнения, даже если она сама не имеет прямого доступа ни к одному из типов, объявленных в этой библиотеке.
Но есть альтернатива, если по какой-то причине добавление этой ссылки проблематично, при условии, что вы, по крайней мере, можете изменить Библиотеку А. То есть инкапсулировать использование типов из Библиотеки B, чтобы они не были видимый для кода, использующего библиотеку А. Как правило, эта инкапсуляция будет включать в себя некоторый вид прокси или оболочки, чтобы скрыть использование третьей библиотеки и (в некоторых случаях) раскрыть возможности третьей библиотеки для сборки, ссылающейся на вторую библиотека.
Например, вы можете изменить библиотеку A, чтобы она выглядела следующим образом:
namespace TopologyDAL
{
public partial class Node
{
// Auto generated from EF
}
public partial class Node
{
public int Key { ... }
private class NodeProxy : INode<int>
{
private readonly Node _node;
public NodeProxy(Node node)
{
_node = node;
}
public int Key { get { return _node.Key; } }
}
private readonly NodeProxy _nodeProxy;
public Node()
{
_nodeProxy = new NodeProxy(this);
}
}
}
Тогда везде, где вы хотите использовать метод расширения из библиотеки B, вы просто используете член _nodeProxy
вместо this
.
Конечно, вышеизложенное предполагает, что основная программа фактически не использует ничего непосредственно из Библиотеки B, и что все типы использования из Библиотеки B находятся только в Библиотеке A, и даже не возвращаются из Библиотеки A в возвращаемых значениях , типы собственности и т. д. Но что, если это не так? Что если, например, вы хотите, чтобы основная программа имела доступ к методу расширения из библиотеки B без ссылки на эту библиотеку?
Ну, мой первый ответ был бы "просто иди и уже ссылайся на сборку!" :) Но ради аргумента, скажем, вы не можете сделать это по какой-то причине, или, по крайней мере, это очень неудобно. Затем вы можете расширить прокси-подход, добавив прокси-методы в ваш тип библиотеки A, которые в свою очередь делегируют реализацию в библиотеке B.
Расширяя приведенное выше, например, можно добавить к объявлению класса Node
другой метод:
public void FromNodeMixin()
{
_nodeProxy.FromNodeMixin();
}
Обратите внимание, что сам метод не добавляет общедоступных случаев использования библиотеки B. Вместо этого он использует (ранее объясненный) экземпляр прокси-сервера для делегирования вызова методу расширения, объявленному в библиотеке B. Таким образом, фактически только библиотека A должна иметь ссылку на библиотеку B; основная программа может ссылаться на библиотеку A, не подвергаясь воздействию каких-либо типов в библиотеке B, и поэтому не нуждается в явной ссылке.
Теперь, все сказанное, я повторю, что - это на самом деле значение в , а не , работающее вокруг этой проблемы. Во-первых, добавление прокси может занять много времени. Это хорошо только для одного или двух типов, возможно, с несколькими методами. Но это станет очень быстро, если вы попытаетесь скрыть каждое косвенное использование библиотек DLL, от которых в противном случае вы использовали бы большое количество функций.
Также, как я уже упоминал ранее, отсутствие добавления ссылки на библиотеку B, конечно, не означает, что библиотека B не обязательно должна быть присутствующей для запуска программы. Вам по-прежнему необходимо иметь библиотеку, чтобы, если и когда библиотека A вызывала ее, ее можно было использовать. И наличие основной справочной программы Library B - один из самых простых способов, которые я знаю, чтобы убедиться, что Library B скопирована в выходной каталог сборки, чтобы убедиться, что DLL там.