2015-06-26 3 views
0

У меня есть библиотека DLL с алгоритмом сортировки, парсерами, валидаторами, преобразователями и т. Д. DLL составляет около 40 Мб (это не так много, я знаю, но все же). Теперь я хотел бы ссылаться только на парсеры этой DLL. Дело в том, чтобы вытащить эти парсеры без доставки 40 Мб клиенту.Частично ссылается на DLL

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

Я думаю, мне нужно было бы иметь дело с большим количеством отражений, чтобы добиться чего-то подобного, верно? Есть идеи?

+1

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

+1

Вы посмотрели на мультифильные сборки? https://msdn.microsoft.com/en-us/library/168k2ah5(v=vs.110).aspx – MadSkunk

+0

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

ответ

3

Позвольте мне начать с цитаты from MSDN:

«Сборки являются строительными блоками приложений .NET Framework, они формируют основную единицу развертывания [...].»

Обратите внимание, что цитата о сборках, а не о DLL. Есть разница!

Хотя большинство сборщиков .NET состоят только из одного DLL-файла, это не является строгим требованием: сборка может состоять из нескольких файлов; такой "multi-file assembly" может, например, состоять из нескольких DLL, которые, в свою очередь, называются «netmodules». (Сетевой модуль может иметь расширение файла .netmodule по соглашению, но это действительно DLL, содержащая метаданные .NET и байт-код.) Каждая сборка с несколькими файлами имеет ровно один «главный» модуль, который содержит метаданные, которые ссылаются на все другие файлы сборки и так далее объединяет их в логическое целое.

Хотя сборка должна быть развернута полностью (согласно приведенной выше цитате), среда выполнения .NET может загружать только те сетевые модули, которые действительно необходимы для компиляции и выполнения кода JIT.

Таким образом, вы можете разделить сборку на несколько частей и иметь рабочую нагрузку только то, что на самом деле необходимо; но вы не можете сделать то же самое с файлом netmodule/DLL. DLL-файл может быть развернут и полностью загружен.

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

Суть в том, что на практике , если вы или ваши клиенты заинтересованы только в части сборки («DLL»), тогда обычно проще разделить большую сборку (то есть один большой визуальный Studio) в несколько взаимозависимых сборок (несколько небольших проектов Visual Studio).

+1

Если вам нужна половина кирпича, вы разрезаете свой кирпич на две части. – StuperUser

+1

... или, как в этом случае, вместо слишком больших кирпичей вы производите меньшие размеры нужного размера. – stakx

0

В общем, нет, нет способа достичь этого. После того, как вы упакуете «все» в модуль и скомпилируете его, вы не сможете разделить этот модуль на более мелкие. (хорошо, хорошо, вы можете проанализировать байт-код и переписать сборку, см. конец этого сообщения).

Для меня ваша нулевая гипотеза кажется неправильной. Вам не нужно работать с «одной огромной библиотекой, которая хранит все ваши вспомогательные классы», и действительно, вы не хотите, или вам тоже этого не захочется. Если вы этого не чувствуете, я заверяю вас, что со временем, может быть, вы будете ненавидеть такой подход «один-к-все-все-все».

Это именно то, от чего вы хотите избавиться, и именно поэтому .Net и многие другие языки/среды поддерживают концепцию «библиотек» или «модулей» и позволяют использовать их несколько, и именно поэтому большинство из них проекты, которые вы видите повсюду, не создаются как «один огромный EXE». Гораздо проще повторно использовать, анализировать и даже охотиться на ошибки, когда у вас есть это в небольших кусках.

-

Однако, если вы настаиваете, есть способы (некрасивых) для того чтобы достигнуть кое-как вы думаете. Я предполагаю, что «огромная DLL» находится в C# и контролируется вами.

Во-первых, несколько неуловимый, но рабочий путь, заключается в использовании «ссылок на файлы». В VisualStudio у вас может быть проект, содержащий множество файлов и производящий BigDLL «all.dll», и только рядом с ним вы можете создать другой проект, который будет не содержать любых файлов вообще, но он будет содержать ссылки на файлы первых проектов. Используйте стандартный вариант «Добавить файл ..» в проект и обратите внимание, что рядом с последней кнопкой «Добавить» есть стрелка вниз, которая расширяется до «Добавить как ссылку ..».

Это приведет к тому, что файл останется в HugeProject, но SmallProject также увидит файл и когда SmallProject будет скомпилирован, он также вытащит код из этого файла.

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

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

-

антракт для побочных мыслей:

  • вы можете использовать #if условно отключить некоторые в настоящее время-неиспользуемый код, однако установке флагов, которые управляют этим МСФ будет громоздким
  • вы можете редактировать файлы .csproj и использовать условные предложения MSBuild для автоматического исключения неиспользуемых файлов кода из вашего HugeProject во время окончательной сборки, однако установка флагов, которые управляют этими IF, тоже будет громоздкой.

-

Второй способ держать все в HugeProject, и иметь приложения (а) ссылаться на него непосредственно, а затем, после построения и тестирования все, как раз перед упаковкой, что и отправка клиенту - используйте какую-то утилиту обрезки, которая проверяет, на какие части кода ссылаются, и которая удалит весь мертвый код из сборок. Я не могу назвать вам такую ​​полезность, но многие обфускаторы имеют такую ​​функцию.

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

пример: See a question related to that
пример: See an example of such utility также рассматривают ILMerge для достижения лучших результатов.

Против - утилита может оставить какой-то мусор, он не может решить, будет ли он использоваться или нет, поиск/тестирование/покупка может занять некоторое время и ресурсы, у вас могут возникнуть проблемы с подписью, поскольку сборная сборка будет новая сборка и т. д. Кроме того, такие утилиты имеют проблемы, если вы вызываете какой-то код только путем отражения, и может потребоваться предоставить дополнительные подсказки или убедиться, что код «кажется использован» (пример: полное пространство имен " плагины ", которые реализуют« IPlugin », а затем ваше приложение искало NS для типов и использует Activator.CreateInstance для их создания, без использования жестких связей, триммер может решить удалить все плагины как« неиспользуемые », вам нужно настроить триммер осторожно или быть удивленным).

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

Смежные вопросы