NuGet – это замечательный инструмент, позволяющий разработчику легко управлять библиотеками в проектах любого типа. Рассмотрим подробнее как его использовать. |
А зачем NuGet нужен?
Как уже было отмечено, основной задачей NuGet является упрощение процесса установки сторонних библиотек. Он берет на себя все шаги этого процесса, в том числе:
- поиск библиотеки;
- загрузка необходимого для установки пакета;
- проверка его хэш-значения на соответствие с заданным сервером (проверка целостности);
- распаковка файлов библиотеки в нужное место;
- добавление ссылок (reference) на её сборки в проект;
- модификацию файлов конфигурации (web.config, app.config) при необходимости.
Все это осуществляется с NuGet в несколько нажатий кнопки мыши или вводом одной консольной команды. Причем учитываются все зависимости загружаемой библиотеки от других компонентов. Последние, при необходимости, также будут загружены и добавлены в проект.
Установка NuGet
Если на рабочей станции еще не был установлен NuGet, то его необходимо загрузить его с помощью менеджера дополнений Visual Studio. Для этого достаточно выбрать раздел Online Gallery и в строке поиска указать название "nuget". При этом поддерживаются все версии среды разработки – от Express до Ultimate.
Официальный сайт проекта: https://www.nuget.org/
Использование NuGet
Графический интерфейс "Add Library Package Reference"
Для наглядности давайте создадим новый проект. Пусть это будет обычное консольное приложение. Попробуем добавить в него библиотеку Castle.DynamicProxy, предназначенную для создания во время выполнения динамических Прокси. Кстати, использование этой библиотеки уже рассматривалось при создании динамического Декоратора.
Откроем контекстное меню проекта Solution Explorer или Solution Navigator и выберем пункт "Add Library Package Reference". В открывшемся диалоговом окне перейдем раздел "Online". Обратите внимание, что в данный момент два типа источника библиотек – все (All) и официальные (NuGet official package source). В строке поиска укажем "Castle", немного подождем и посмотрим на появившиеся результаты:

При выборе библиотеки из списка, справа отображается краткая информация о ней и о её зависимостях от других компонентов. При этом последние также могут иметь свои зависимости от библиотек. При установке вся эта цепочка бу��ет проанализирована и загружены все необходимые файлы.
Выберем библиотеку Castle.DynamicProxy и нажмем кнопку "Install". Произойдет установка выбранного компонента. Давайте посмотрим, что добавилось в созданный проект.
В первую очередь это сама библиотека Castle.DynamicProxy. Её легко можно заметить в списке References проекта. Кроме того, её инсталляционный пакет указал зависимости от другой библиотеки: Castle.Core. А она, в свою очередь, потребовала наличия log4net и NLog. В результате все эти компоненты были найдены и установлены.
Обратите внимание, что могут быть указаны зависимости различных видов. Здесь их два:
- В первом случае требуется определенная версия библиотеки. В частности при установке была затребована именно Castle.Core 1.2.0. И не смотря на то, что на данный момент уже доступна 2 версия, она установлена не будет. Причем, даже если потом попытаться установить новую версию самостоятельно, то будет выведено сообщение об ошибке.
- Во втором случае указывается минимальная версия, которая будет загружена. Но в дальнейшем возможно обновление до последней версии. Например, таким образом в данном примере были зависимости Castle.Core от log4net и NLog.
Где разместились загруженные файлы? NuGet создал в папке решения (solution) свою папку packages. По сути, это небольшой репозиторий проекта. Внутри него расположились DLL и остальные файлы загруженных библиотек. Причем структура размещения внутри каждой папки частично определятся требованиями NuGet, а частично самим установленным компонентом.
Кроме того, в проект добавился один файл "packages.config", который в данный момент выглядит так:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="1.2.10" />
<package id="NLog" version="1.0.0.505" />
<package id="Castle.Core" version="1.2.0" />
<package id="Castle.DynamicProxy" version="2.2.0" />
</packages>
Как легко можно понять, он описывает добавленные в текущий проект библиотеки.
Давайте вновь откроем диалоговое окно "Add Library Package Reference" и перейдем в раздел "Updates". NuGet при этом проверит доступные обновления для установленных библиотек. В результате будет выведен список, какие из них обновились.

Попытка обновить Castle.Core приведет к неудаче. Как уже было отмечено, Castle.DynamicProxy требует определенную её версию. А вот NLog можно обновить, нажав кнопку "Update".
После обновления перейдем обратно в раздел Installed Packeges. В нем приведен список всех установленных компонентов. Кроме того, здесь можно убедиться что NLog был обновлен и его описание содержит номер последней версии (на момент создания данной статьи это 2.0.0.0):

При выборе любой из приведенных в списке библиотек, рядом появляется кнопка "Uninstall". Однако, удалить возможно только те, от которых не зависят другие компоненты. Для остальных будет показано сообщение об ошибке. Таким образом NuGet следит за соблюдением зависимостей.
Давайте сейчас удалим добавленные компоненты. Порядок при этом будет такой: вначале Castle.DynamicProxy, затем Castle.Core и последними будут удалены log4net и NLog. Обратите внимание, что были удалены не только ссылки на сборки (References), но и загруженные установочные пакеты.
Консоль "Package Manager Console"
Посмотрим на еще один способ работы с NuGet. Он подойдет тем, кому больше нравится работать с командной строкой, чем с диалоговыми окнами. Сразу необходимо отметить, что поддерживается подсказка для завершения набора команд. Для её активации необходимо ввести несколько первых букв и нажать кнопку "Tab".
Откроем Package Manager Console с помощью меню View > Other Windows (другой вариант – Tools > Library Package Manager). После загрузки и инициализации PowerShell, который она использует, оно выглядит следующим образом:

Давайте сначала посмотрим как найти нужную библиотеку в этом случае. Для этого необходимо дать команду "Get-Package -ListAvailable". Однако в этом случае будет выведен огромный список всех доступных установочных пакетов. Поэтому уточним команду, добавив строку для поиска. В итоге поучится следующий вариант: "Get-Package -ListAvailable castle.dynamic". Результатом его работы будет список доступных библиотек, в имени или описании которых есть указанная строка.

Добавим найденную библиотеку в проект. Для этого укажем следующую команду: "Install-Package Castle.DynamicProxy". Результат её выполнения будет аналогичным использованию диалога "Add Library Package Reference".
Как и в примере с графическим интерфейсом, теперь попробуем обновить библиотеки. Чтобы узнать какие новые версии доступны необходимо ввести команду "Get-Package -updates". Посмотрим на полученный список и решим, также как и в прошлый раз, обновить NLog. Укажем следующую команду: "Update-Package NLog", которая приведет к загрузке и установке последней версии этого компонента.
Остается рассмотреть как удалить установленную библиотеку. Для этого используется команда "Uninstall-Package". Давайте введем "Uninstall-Package Castle.DynamicProxy" в командной строке консоли. После чего при помощи команды "Get-Package" без параметров вызовем список установленных пакетов и убедимся что Castle.DynamicProxy был действительно удален. Аналогично, с помощью команды Uninstall-Package удалим оставшиеся пакеты.
Использования консоли для операций над группой проектов (конвейер команд)
Необходимо отметить еще одну возможность, которая предоставляет "Package Manager Console". Это возможность объединения команд в "конвейер" (pipeline). В частности это позволяет выбрать проект, к которому будет применена следующая команда. Для этого в начале строки необходимо указать:
- Get-Project –All – чтобы выбрать все проекты текущего решения (solution).
- Get-Project –Name projectName - чтобы выбрать проект с именем projectName.
После чего через разделитель "|" добавить необходимую команду. При этом нужно учесть, что не все поддерживают такой режим. Наиболее интересными представляются следующие варианты для установки, обновления и удаления библиотеки, присутствующей во всех проектах решения:
- Установка: Get-Project -All | Install-Package [params]
- Обновление: Get-Project -All | Update-Package [params]
- Удаление: Get-Project -All | Uninstall-Package [params]
Если необходимо выборочно обновлять несколько проектов, можно написать скрипт для PowerShell. Для этого необходимо создать файл с расширением .ps1. Например, пусть это будет update.ps1 в папке, являющейся корнем решения. В нем будут заданы команды для обновления библиотек c указанием проектов:
Update-Package Castle.Core -ProjectName projectName1
Update-Package Castle.Core -ProjectName projectName3
Update-Package Castle.Core -ProjectName projectName4
В дальнейшем, запустить данный скрипт на выполнение можно указав путь до него и его имя. При этом сам путь задается относительно корневой папки проекта и начинается c ".\". Например, ".\update.ps1". Аналогично можно задать любую последовательность действий для NuGet.
Настройки NuGet
Начиная с версии 2.1 NuGet позволяет управлять несколькими полезными настройками с помощью файлов NuGet.config.
Иерархия NuGet.config
Для определения настроек, специфичных для конкретной папки и вложенных в неё папок, необходимо разместить в ней файл NuGet.config с новыми параметрами.
Это может использоваться для задания источников, специфичных для определенных проектов. Например, разместим в папке C:\MyProjectGroup1 файл NuGet.config, который добавляет новый источник:
<configuration>
<packageSources>
<add key="My source" value="http://myserver/api/v2/" />
</packageSources>
<disabledPackageSources />
<activePackageSource>
<add key="My source" value="http://myserver/api/v2/" />
</activePackageSource>
</configuration>
Теперь My source доступен всем проектам внутри C:\MyProjectGroup1, но не доступен остальным.
Указание места размещения установочных пакетов
При большом числе решений, на диске скапливается множество копий одних и тех же установочных пактов. Это можно исправить, указав в файле NuGet.config единое место для размещения:
<configuration>
<config>
<add key="repositoryPath" value="C:\MyProjectGroup1\TeamPackages" />
</config>
...
</configuration>
Если указанную строку добавить в файл из примера выше, то все проектам внутри C:\MyProjectGroup1 будут хранить свои установочные пакеты в папке C:\MyProjectGroup1\TeamPackages. Стоит отметить, что можно указывать относительные пути.
Список доступных консольных команд NuGet
Стоит еще раз отметить, что в консоли NuGet поддерживается подсказка по нажатию кнопки "Tab". Это очень сильно ускоряет процесс работы с ней и делает её в чем-то даже удобнее и быстрее варианта с графическим интерфейсом. Причем, подсказка есть не только для имен самих команд, но и параметров и их значений. При этом если существует только один вариант, то он будет сразу вставлен в текст команды.
Например, при установке можно ввести часть имени библиотеки и нажать кнопку "Tab". Через небольшой промежуток времени (запрос к серверу) будет отображена подсказка, содержащая имена первых в списке библиотек, названия которых начинаются с указанного текста.
Другой пример – указание имени проекта. Это необходимо в случае, если в решении (solution) их содержится несколько. В этом случае, после параметра команды также можно нажать кнопку "Tab". В окне подсказки будут перечислены все доступные проекты.
Давайте теперь перейдем к списку команд, доступных в консоли NuGet.
Get-Package – вывод списка установочных |
[Без параметров] |
Выводит список установленных пакетов. |
‑ProjectName projectName |
Отображает список пакетов, установленных в указанном в качестве параметра проекте projectName. |
‑Source sourceUrlOrPath |
Определяет источник для получения информации о пакетах. Это может быть RSS поток, папка на диске или сервис, поддерживающий OData. |
-ListAvailable [filterSpecification] |
Выводит список библиотек, доступных в выбранном источнике. Возможна установка фильтра, который применяется для названий и описаний библиотек. |
‑Updates |
Отображает список библиотек, для которых доступны обновления. |
‑Recent |
Выводит список последних установленных библиотек. |
‑First N |
Отображает первые N установочных пакетов в списке. |
‑Skip N |
Пропускает N установочных пакетов при выводе списка. Вместе с параметром –First позволят выводить список частями. Например, чтобы вывести названия библиотек с 15 по 45 необходимо указать "–Skip 15 –First 30" |
‑Filter filterSpecification |
Устанавливает фильтр для вывода списка библиотек как установленных, так и на доступных в источнике. Применяется к названию и описанию библиотеки. |
Install‑Package – установка библиотек |
‑Id packageName
|
Обязательный первый параметр (при этом можно опустить "–Id"). Задает имя установочно пакета. При этом если не ввести имя показывается 30 самых библиотек с самым большим рейтингом. Если указать часть имени, то осуществляется поиск по вхождению указанного текста в имена библиотек. |
‑IgnoreDependencies |
Указывает необходимость установки только указанной библиотеки, игнорируя её зависимости от других. |
‑Project projectName |
Определяет в какой из проектов необходимо установить библиотеку. По умолчанию используется проект текущий проект, указанный в окне консоли. |
‑Source sourceURL |
Указывает источник получения установочного пакета. |
‑Version versionNumber |
Запрашивает установку указанной версии библиотеки (по умолчанию используется самая последняя). |
‑FileConflictAction action |
Определяет действие, если устанавливаемый файл уже существует в проекте. Параметр action может принимать одно из значений: Overwrite (перезаписать) или Ignore (пропустить). |
Uninstall‑Package – деинсталляция библиотек |
‑Id packageName
|
Обязательный первый параметр (при этом можно опустить "–Id"). Определяет имя библиотеки для удаления. |
‑RemoveDependencies |
Указывать не необходимость так же удалить пакеты, от которых зависит библиотека и которые не используются другими. |
‑Force |
Удаляет библиотеку, даже если есть зависимые от неё компоненты. |
‑Version versionNumber |
Указывает версию удаляемой библиотеки. По умолчанию выбирается самая последняя версия. |
‑Project projectName |
Определяет из какого проекта удаляется библиотека. По умолчанию используется проект текущий проект, указанный в окне консоли. |
Update-Package – обновление установленных библиотек |
‑Id packageName
|
Первый параметр (при этом можно опустить "–Id"). Определяет имя библиотеки, для которой производится поиск и установка обновления. Если он не указан, то производится обновление всех библиотек. |
‑Reinstall |
Указывает на необходимость переустановки библиотеки. Установочный пакет удаляется, загружается повторно и устанавливается в заданный проект. |
‑UpdateDependencies |
При установке этого флага производится обновление всех зависимых библиотек. |
‑ProjectName projectName |
Определяет в каком проекте будет обновлены библиотеки. Если ключ не указан, то выбранный пакет или все пакеты обновляются во всех проектах решения. |
‑Source sourceURL |
Переопределяет источник получения установочного пакета для данной команды. |
‑Version versionNumber |
Указывает версию до которой происходит обновление. По умолчанию выбирается самая последняя версия. |
‑Safe |
Задействует безопасное обновление, т.е. загружаются только минорные обновления. Например: установлена версия 1.0.0 и доступны 1.0.1, 1.0.2 и 1.1. При использовании ключа –safe будет загружена версия 1.0.2, а без него – 1.1. |
Open-PackagePage – переход на страницу проекта |
‑Id packageName
|
Обязательный первый параметр (при этом можно опустить "–Id"). Определяет имя библиотеки, страница которой будет открыта в браузере. |
‑Version versionNumber |
Указывает номер версии. |
‑Source sourceURL |
Переопределяет источник получения установочного пакета для данной команды. |
‑License |
Открывает в браузере страницу с лицензионным соглашением. |
‑ReportAbuse |
Открывает в браузере страницу для подачи жалобы. |
‑PassThru |
Изменяет поведение команды. Вместо открытия браузера возвращается строка с адресом выбранной страницы. Например, следующий код присваивает переменной $url ссылку на страницу с текстом лицензии: $url = Open-PackagePage Ninject -License -WhatIf -PassThru
|
Get–Projects - выбор проекта(ов) (для конвейера команд) |
[Без параметров] |
Возвращает текущий проект. |
-All
|
Возвращает все проекты загруженного решения (solution). |
‑Name projectName |
Возвращает заданный проект для команды. |
В завершении несколько примеров:
- Get-Package -ListAvailable Razor – выводит список всех доступных установочных пакетов, у которых в имени или описании есть текст "Razor".
- Get-Package –ListAvailable -Skip 5 -First 10 Castle – отображает перечень с 5 по 15 библиотеку, в названии которых содержится слово "Castle".
- Get-Package -Update -Filter Castle – отображает список обновлений, доступных для установленных проектов в названии которых содержится слово "Castle".
- Update-Package – обновляет все установочные пакеты во всех проектах текущего решения.
- Update-Package EntityFramework – обновляет пакет EntityFramework во всех проектах решения.
- Update-Package –ProjectName MVCDemo – обновляет все пакеты в проекте MVCDemo.
- Install-Package Raz[нажатие кнопки "Tab"] – откроет окно подсказки с списком библиотек, имена которых начинаются с текста "Raz". Обратите внимание на возможность пропускать указание "–Id".
Как можно убедиться, использовать NuGet достаточно просто. Как из консоли, так и c помощью графического интерфейса. Какой из них выбрать? Каждый решает сам.
А в следующей части рассмотрим возможности оп настройке NuGet, а также какие новые возможности это может дать разработчику.