У меня есть вспомогательный проект, который я использую во всех приложениях, которые я создаю. Он содержит некоторые методы расширения и набор общих вспомогательных классов, элементов управления и т. Д. Я время от времени обновляю / расширяю вспомогательный проект. Обычно это небольшие и несвязанные проекты, и я единственный человек, работающий над всеми из них.
Я попробовал два подхода для его использования
- добавлять файлы .cs напрямую (Добавить как ссылку) в каждый проект, где я их использую
- скомпилируйте его как .dll и добавьте в качестве ссылки
Я вижу некоторые преимущества и недостатки этих подходов.
Первый:
- Проще, потому что вспомогательные классы скомпилированы в exe-файл, поэтому я часто очень легко могу предоставить только один .exe-файл, который будет работать очень хорошо. Поскольку я добавляю как ссылку, я могу быть уверен, что всякий раз, когда я создаю какой-либо проект, который использует помощник, файлы помощника будут последней версией.
- еще проще, потому что я могу отделить файлы, так что на мои методы расширения, которые отлично работают в .NET 4.0, можно ссылаться отдельно от тех, которые требуют .NET 4.5, что означает, что приложение в целом может работать в .NET 4.0
- Позволяет отлаживать код, со всеми преимуществами точек останова и т. Д. И т. Д.
- не похоже на «лучшую практику»
Второй:
- кажется правильным подходом, но:
- требует, чтобы я доставил отдельный файл .dll, который по некоторым причинам гораздо сложнее для пользователей (они, как правило, делятся моими программами без .dll, которая затем вылетает при запуске)
- поскольку он скомпилирован в один .dll, ему потребуется самая высокая версия .NET - у многих из моих пользователей нет .NET 4.5, и это требуется только некоторым элементам моего вспомогательного класса, что означает, что я могу заставить некоторых людей обновить свои системы без причины
- Мне также нужно убедиться, что всякий раз, когда я обновляю любую из моих программ, я также доставляю файл .dll - хотя я не знаю, изменился ли он с последней версии или нет (это могло быть, но может также быть той же версией). Я не вижу простого способа определить это, не отслеживая версию сборки, что является дополнительной работой. На данный момент, когда я обновляю свои программы, я поставляю только обновленный exe, и мне нравится держать его маленьким и скромным.
Итак, какова реальная выгода от использования файла .dll здесь? Обратите внимание, что я единственный человек, который редактирует код всех приложений и вспомогательных файлов.
Кроме того, чтобы уточнить - приложений обычно очень мало, тогда как код, содержащийся во вспомогательных классах, является полностью общим для всех из них (некоторые простые сравнения строк, пути или операции XML и т. Д.)
На самом деле, кто-то заставил меня понять, что есть третий вариант. Поскольку у меня есть вспомогательный код в отдельном проекте, я могу добавить этот проект к решениям каждого из моих отдельных приложений - что работает как «Добавить как ссылку» для отдельных файлов, за исключением того, что я добавляю только один проект ... Но Как заметил Док Браун, это, по сути, означает, что .dll все равно нужно будет добавить в проект ...
Еще одна вещь, которая как бы не способствует использованию dll-файлов, это возможность активной отладки через вспомогательный класс ...
Ответы:
Вы уже заметили большинство плюсов и минусов. Использование CS-файлов в качестве ссылок действительно легче и зачастую проще в управлении. Однако я рекомендую использовать этот подход исключительно тогда, когда ваши
cs
файлы полностью автономны и не имеют каких-либо особых требований к сборке.Использование отдельных DLL
сделает зависимости от других утилит или библиотек явными (если у вас нет таких зависимостей, все будет работать нормально)
позволит вам определить конкретные конфигурации сборки (например, если класс работает только в конфигурации x86 или требует как минимум .NET 4.0, конфигурация сборки сборки делает это требование явным).
Поэтому, особенно если у вас есть много отдельных классов, автономных компонентов, использование ссылок на файлы - это нормально, но если у вас есть компоненты, ссылающиеся на другие компоненты или конкретные требования к сборке, я бы рекомендовал использовать библиотеки DLL.
Чтобы устранить проблемы с управлением многими отдельными DLL, вы можете создать пакет установщика или использовать ILMerge , который может встроить набор сборок в один исполняемый файл. В нашей среде мы решаем проблему по-разному, используя сценарий развертывания для каждого приложения. Этот сценарий гарантирует, что все необходимые библиотеки DLL всегда доставляются в производство при публикации нового выпуска приложения.
источник
Библиотеки DLL удобны, когда приложение большое и есть части, которые требуют обновлений, но не всего приложения. Итак, если вы пишете MS Word, удобно иметь код проверки орфографии в DLL, который можно обновлять без необходимости обновления всего MS Word. Если то, что вы пишете, является небольшим служебным приложением (или рядом автономных приложений, которые, как оказалось, все используют один и тот же код), не имеет большого значения, встроен ли код в приложение (я) или нет.
источник
Вы подытожили это в своем вопросе, у меня есть только пара моментов, чтобы добавить.
Mono Options - отличный пример пакета NuGet, который очень хорошо использует первый подход.
В качестве альтернативы, если вы решили использовать dll, вы можете использовать такие инструменты, как Costura, чтобы встроить эту ссылку в свой исполняемый файл как встроенный ресурс. Чтобы использовать это просто добавьте
Costura.Fody
пакет:источник
Является ли dll более выгодным или нет, зависит от нескольких факторов:
Цель разделяемой библиотеки - взять код, общий для нескольких исполняемых файлов, и централизовать его так, чтобы все исполняемые файлы имели общую копию. Это предназначено для экономии места и облегчения обновления кода.
Если количество кода в вашем вспомогательном классе очень мало, возможно, не стоит переносить его в dll, поскольку накладные расходы на код, находящийся в dll, могут противодействовать преимуществу экономии места, связанного с его централизацией.
Кроме того, если вы создаете только несколько исполняемых файлов, размер кода в каждом исполняемом файле может быть достаточно маленьким, чтобы не представлять проблемы. Тем не менее, чем больше исполняемых файлов вы используете, один и тот же код, тем выгоднее было бы переместить код в dll.
В качестве упрощенного примера, скажем, ваш вспомогательный класс компилируется в 128 байт в исполняемом файле, но при перемещении в dll dll составляет 512 байт. Если у вас есть только 3 исполняемых файла, вы сэкономите место, включив код в исполняемые файлы. Однако если бы у вас было 5 исполняемых файлов, вы бы оказались в той точке, где вам было бы лучше иметь dll, потому что объединенное пространство, занимаемое 5 копиями кода (5 * 128 = 640 байт), больше, чем занимаемое пространство имея код в dll (512 байт).
Теперь скажем, например, что вы нашли ошибку в своем коде помощника. Если вы скомпилировали все свои исполняемые файлы с помощью встроенного кода, вам придется перекомпилировать каждый исполняемый файл, а затем распространять перекомпилированные версии. Если вы скомпилировали код в dll, вам нужно будет только перекомпилировать и перераспределить одну dll, и ошибка будет автоматически исправлена для всех исполняемых файлов, использующих ее.
Наконец, для программы, чтобы найти DLL, она должна знать, где искать DLL. Если вы храните все свои исполняемые файлы вместе, вы можете просто поместить dll в один и тот же каталог, и они все сразу его найдут. Если вы намеренно держите их отдельно, становится сложнее координировать их, чтобы использовать одну и ту же DLL.
источник
Ваш третий вариант является наиболее подходящим (добавьте его как отдельный проект "библиотеки классов" к решению). Это сочетает в себе преимущества всех подходов:
Мы делаем это все время, и я ничего не могу сделать, но рекомендую этот подход.
Еще одна четвертая альтернатива, о которой вы не упомянули, - это поместить ее в закрытое хранилище NuGet, которое позволит вам правильно ее версия и ссылаться на нее без дополнительного проекта в каждом решении.
источник
Как разработчик, я всегда хотел бы включить ссылку на решение утилиты для моего приложения, поскольку это позволяет мне отлаживать код (и выявлять возможные ошибки в Utility!), А также любые изменения, вносимые в утилиту, автоматически включаются в приложение.
Итак, на самом деле решение зависит от того, насколько зрелой является Утилита ! Если вы не уверены в ошибках Utility, вы должны всегда включать файл .cs этой утилиты, чтобы выяснить ошибки ... Но если вы уверены, что Utility достаточно развита, и она не будет возвращать результат с какими-либо ошибками, и там В Utility нет возможностей для улучшения, вы можете пойти дальше и включить файл DLL.
источник