Совместное использование класса C# из библиотеки классов, на которую ссылаются, через другую библиотеку

Я создаю библиотеку классов (MyLib), которая содержит общедоступный класс A. Этот класс указывает общедоступные методы M, возвращающие экземпляр класса B из внешней библиотеки классов (ExtLib).

Чтобы использовать MyLib.A.M(), пользователь, который будет использовать мою библиотеку классов, должен будет ссылаться как на MyLib, так и на ExtLib.

Мой вопрос в том, можно ли каким-то образом сделать класс ExtLib.B доступным напрямую через MyLib (например, MyLib.B), чтобы пользователю не приходилось ссылаться на обе библиотеки, а только на MyLib?


person STremblay    schedule 13.04.2016    source источник
comment
Как пользователь мог бы получить доступ к внешним типам, если бы он не ссылался на них?   -  person Wjdavis5    schedule 13.04.2016
comment
Нет. Это невозможно.   -  person Jcl    schedule 13.04.2016
comment
Вы можете загрузить сборку ExtLib с помощью Reflection.   -  person Gosha_Fighten    schedule 13.04.2016
comment
@Gosha_Fighten, или вы могли бы сгенерировать тип во время выполнения, но я не думаю, что это то, о чем просит ОП: если он не использует B (например, безопасным способом), то он на самом деле не нуждается в ссылке ExtLib   -  person Jcl    schedule 13.04.2016
comment
Вы можете попробовать это: stackoverflow.com/questions/1829531/   -  person Mike Cheel    schedule 13.04.2016
comment
Используйте для этого ILMerge.   -  person Greg Ferreri    schedule 13.04.2016
comment
@MikeCheel на самом деле, ILMerge может быть лучшим обходным путем, учитывая этот сценарий. Другая возможность — сделать полную оболочку вокруг объекта B, но это неразумно, если цель состоит в том, чтобы избежать ссылки (ссылки, которые в любом случае есть в основной библиотеке).   -  person Jcl    schedule 13.04.2016
comment
Кроме того, в зависимости от того, насколько вы лягушатны, и типа сборки, вы можете взломать стороннюю сборку в чем-то вроде JustCompile, декомпилировать и просто поднять нужный код. Я делал это раньше в редких случаях =)   -  person Mike Cheel    schedule 13.04.2016
comment
@MikeCheel ILMerge создаст другую сборку. Таким образом, если в ExtLib будут внесены изменения, потребуется повторно объединить существующую сборку. Излучение, я думаю, является лучшим выбором. Вы можете просмотреть все свойства B во время JIT и скомпилировать новые, если они будут добавлены. Но, с другой стороны, в сборке MyLib должен быть реализован интерфейс, предоставляющий новые свойства. Итак, MyLib тоже следует изменить.   -  person Gosha_Fighten    schedule 13.04.2016


Ответы (1)


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

Да, вы, вероятно, можете заставить работать ilmerge, чтобы поддерживающая сборка целиком включалась в вашу собственную сборку. Но это полностью связывает график выпуска вашей сборки с графиком поддержки сборки. Не было бы никакой возможности обновить поддерживающую сборку для использования с вашей сборкой без повторного выпуска вашей собственной сборки.

Существует также вопрос об авторском праве и лицензировании. Если вы также написали вспомогательную сборку, я думаю, у вас не должно возникнуть никаких проблем. Но в противном случае слияние поддерживающей сборки с вашей собственной может, по крайней мере, не одобряться автором этой сборки, если не прямо запрещено.

Другим неприятным вариантом может быть возврат dynamic объектов из API вашей сборки вместо типов, объявленных в поддерживающей сборке. Это, конечно, может повлиять на производительность, а также свести на нет любую возможную безопасность типов во время компиляции, которая в противном случае была бы обычным преимуществом использования такого языка, как C#. Но это можно было сделать.

Если вы действительно не можете смириться с мыслью, что пользователь добавляет ссылку на вспомогательную библиотеку, разумным вариантом с точки зрения разработки программного обеспечения будет изменение API вашей сборки, чтобы он не возвращал типы из вспомогательной библиотеки. Им все равно понадобится эта сборка во время выполнения, если вы ее используете, но, по крайней мере, пользовательскому коду не потребуется явная ссылка. Вместо этого ваш API будет возвращать типы, которые объявляет ваша собственная сборка и которые обертывают типы поддерживающей сборки, возможно, изменяя интерфейсы этих типов (удаляя ненужные элементы, добавляя новые расширения и т. д.), чтобы лучше удовлетворить потребности ваших собственных пользователей. Таким образом, поддерживающие типы сборки скрыты от просмотра и поэтому не требуют явной ссылки со стороны ваших пользовательских сборок.


ИМХО, стоит принять к сведению, что ваш пользователь уже ссылается на множество других сборок, от которых зависит ваша сборка, то есть, если ничего другого, то, по крайней мере, различные сборки .NET. Конечно, многие из них необходимы для работы любого кода .NET, поэтому в пользовательских проектах уже есть эти ссылки, но они по-прежнему представляют собой дополнительные ссылки на сборки. Другие сборки .NET не по умолчанию могут потребоваться или не потребоваться, в зависимости от того, что еще ваша собственная сборка использует и возвращает в код пользователя. Тем не менее, такого рода вещи довольно распространены, и на самом деле не следует тратить значительное количество времени, пытаясь их избежать.

Опять же, дело в том, что поддерживающая сборка в любом случае потребуется во время выполнения. Таким образом, не кажется большой трудностью требовать, чтобы на эту сборку ссылались собственные проекты пользователя. Ссылки на сборки, которые объявляют типы, от которых зависит собственный код, — это как раз то, как работает .NET. Зачем с этим бороться? Что это за насущная проблема, которая могла бы побудить приложить какие-либо реальные усилия, чтобы избежать этой дополнительной ссылки в проектах пользователей?

person Peter Duniho    schedule 14.04.2016
comment
Я отвечу на ваш вопрос Что... проблема, которая может... мотивировать прилагать... усилия, чтобы избежать этой ссылки Ответ прост, школьное задание с наложенным ограничением (после), где сборка A должна использовать только интерфейс сборки B , а сборка B использует только интерфейс сборки C. Однако я уже спроектировал сборку C так, чтобы несколько классов были полезны как для сборок A, так и для B, до того как я был проинформирован об этом ограничении. Поэтому я искал способ каким-то образом переименовать эти классы из C и сделать их похожими на принадлежащие B. - person STremblay; 15.04.2016
comment
Ах. Назначение школы? Тогда ответ прост: оберните тип поддерживающей сборки в свой тип сборки (т.е. третий вариант, который я предложил выше). Ограничение уже произвольное, наложенное по академическим причинам; нет причин тратить время на поиски более умного решения, чем это. (Кроме того, спорно, будет ли использование ilmerge соответствовать наложенным ограничениям, поскольку это будет равносильно либо полному исключению поддерживающего узла из уравнения, либо неизменению экспозиции шрифта и его сборки, в зависимости от того, как смотреть на Это.) - person Peter Duniho; 15.04.2016
comment
Спасибо, я продолжу с оболочкой, это была моя первая идея, но мне было интересно, есть ли какой-то встроенный механизм импорта, который может автоматически включать одну часть сборки в другую. Ответ, кажется, нет, так что я пойду с оберткой! - person STremblay; 15.04.2016