В прошлой части было рассмотрено как подключить к NuGet локальный репозиторий. Это удобное решение для установки библиотек собственной разработки. Осталось разобраться как создать свой пакет. |
Для его создания потребуется утилита "NuGet.exe Command Line", которую можно загрузить с официальной страницы проекта на CodePlex.Скопируем её в папку, доступную из командной строки. В качестве подходящего места может выступить "(Program files)\Microsoft Visual Studio 10.0\Common7\Tools\".
Создаем проект библиотеки
Прежде чем создать установочный пакет, необходимо подготовить библиотеку, которая будет в него включена. В неё включим атрибуты проверки данных, созданные в цикле статей "ASP.NET MVC 3 в деталях". Обратите внимание, что для подключения этой библиотеки к проекту необходимо не только добавить её сборку, но и скопировать дополнительные JavaScript-файлы.
Имя решения (solution) возьмем произвольное. А вот название проекта будет совпадать с используемым в библиотеке пространством имен MVCDemo.Attributes.Validation. Включем в него следующие исходные файлы атрибутов проверки данных:
- BlockHtmlAttribute.cs
- EqualAttribute.cs
- StringLengthRangeAttribute.cs
Кроме того, в папке Scripts\Validation разместим JavaScript-файлы для поддержки проверки данных на стороне клиента:
- BlockHtmlAttribute.js
- EqualAttribute.js
Чтобы не акцентировать внимание на создании библиотеки (class library), можно сразу загрузить готовый проект. Соберем его в режиме Release. Все готово для создания установочного пакета NuGet.
Создаем установочный пакет
Чтобы лучше понять принципы работы NuGet, соберем установочный пакет вручную. Для этого в корневой папке решения создадим папку nuget-package (имя произвольное) для размещения его файлов.
Структура папок
По умолчанию, все папки и файлы, включая вложенные, в указанном для создания сборки месте будут включены в установочный пакет. Однако, NuGet определяет три специальных имени для папок, содержимое которых будет обработано особым образом:
- tools – папка для утилит, которые должны быть доступны из командной строки. После установки её путь добавляется в список, расположенный в переменной среды Path.
- lib – хранилище сборок проекта. Именно сюда необходимо скопировать их DLL файлы.
- content – место хранения дополнительных файлов. Его внутренняя структура может быть любой. При этом она один в один будет перенесена в корневую папку проекта при установке пакета.
Кроме того, папка lib имеет дополнительное соглашение. Сборки, размещенные непосредственно в ней, будут подключены к проекту для любой версии .NET Framework. Но при необходимости DLL файлы можно разделить в зависимости от версии .NET или Silverlight для которых они предназначены. Для этого файлы необходимо разместить в подпапке с названием и номером версии платформы. Для интерпретации этого имени NuGet использует класс FrameworkName. Поэтому возможно использовать как полные имена, так и сокращения. Кроме того, при отсутствии имени считается что подразумевается .NET Framework. Таким образом, "4.0" эквивалентно ".NetFramework 4.0".
Может возникнуть вопрос: а что будет если расположить файлы и самой lib и в подпапках для различных версий .NET? В этом случае, файлы из основной папки всегда будут добавляться в проект, а из подпапок – только в проект, ориентированный на указанную платформу и её версию.
Таким образом структура может выглядеть следующим образом:
- content
- lib
- .NetFramework 1.1
- .NetFramework 2.0
- .NetFramework 4.0
- Silverlight 3.0
- Silverlight 4.0
- tools
Разумеется, необходимо создавать только те папки, в которых будут размещены файлы.
В случае с создаваемым для примера установочным пактом необходимо:
- в content скопировать папку Scripts;
- сборку MVCDemo.Attributes.Validation.dll из папки Release проекта перенести в lib;
- папки tools в данном примере не будет.
Описываем спецификацию библиотеки
Теперь необходимо создать описание установочного пакета. Это будет файл в формате XML с именем библиотеки и расширением ".nuspec". Создадим CustomValidationAttributesLib.nuspec в папке install-package. Его структура достаточно понятная, поэтому давайте сразу посмотрим на пример:
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata>
<id>MVCDemo.Attributes.Validation</id>
<version>1.0.0</version>
<authors>Andrey Veselov</authors>
<description>Custom validation attributes for ASP.NET and ASP.NET MVC.</description>
<language>en-US</language>
<licenseUrl>http://andrey.moveax.ru/terms-of-use.aspx</licenseUrl>
<projectUrl>http://andrey.moveax.ru/</projectUrl>
<tags>ASP.NET MVC</tags>
</metadata>
</package>
Отдельно можно отметить только тег id. Это уникальный идентификатор библиотеки, который должен быть равен имени используемого ей пространства имен. Кроме того, id и номер версии будут использованы для создания имени установочного пакета.
Позже будут рассмотрены дополнительные возможности, предоставляемые файлом спецификации, и приведено полное описание поддерживаемых тегов. А пока создадим первый установочный пакет.
Создаем установочный пакет
Запустим "Visual Studio Command Prompt" и перейдем в папку nuget-package. В ней выполним следующую команду (nuget.exe должен быть доступен из командной строки):
nuget pack AdditionalValidationAttributes.nuspec
В результате будет создан установочный пакет "MVCDemo.Attributes.Validation.1.0.0.nupkg". По формату это zip-файл который можно открыть в любом архиваторе. Кроме того, для их просмотра можно воспользоваться утилитой "NuGet Package Explorer".
Скопируем полученный файл в репозиторий, созданный в предыдущей части. Теперь посмотрим на созданный пакет в работе, а затем немного автоматизируем процесс его создания.
Проверка
Для проверки создадим простой ASP.NET MVC 3 проект NuGetMvсDemo. Модель TestModel будет содержать два свойства, для проверки атрибутов из AdditionalValidationAttributes:
namespace NuGetMvсDemo.Models
{
using System.ComponentModel.DataAnnotations;
public class TestModel
{
[Required]
[DataType(DataType.MultilineText)]
public string TextBlock { get; set; }
public bool BooleanValue { get; set; }
}
}
Добавим Контроллер HomeController с единственным Действием Create:
namespace NuGetMvсDemo.Controllers
{
using System.Web.Mvc;
public class HomeController : Controller
{
// GET: /Home/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Home/Create
[HttpPost]
public ActionResult Create(FormCollection collection)
{
return View();
}
}
}
Теперь необходимо создать строго-типизированное Представление для Действия, используя для этого Модель TestModel и шаблон Create.
Остается только в методе RegisterRoutes() изменить Действие по умолчанию:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {
controller = "Home",
action = "Create",
id = UrlParameter.Optional
} // Parameter defaults
);
}
Можно запустить проект и убедиться что форма выводится без ошибок.
Теперь откроем консоль "Package Manager Console" и установим в качестве текущего источника локальный репозиторий "Local NuGet repository". Ведем команду "Get-Package -ListAvailable" и получим следующий список:
PM> Get-Package -ListAvailable
Id Version Description
-- ------- -----------
Castle.Core 1.2.0 Core of the castle project
Castle.DynamicProxy 2.2.0 Castle DynamicProxy is a library for...
log4net 1.2.10 log4net is a tool to help the progra...
MVCDemo.Attributes.Validation 1.0.0 Custom validation attributes for ASP...
NLog 1.0.0.505 NLog is a logging platform for .NET ...
NLog 2.0.0.0 NLog is a logging platform for .NET ...
RazorEngine 2.1 A templating engine built upon Micro...
Установим пакет "MVCDemo.Attributes.Validation":
PM> Install-Package MVCDemo.Attributes.Validation
Successfully installed 'MVCDemo.Attributes.Validation 1.0.0'.
Successfully added 'MVCDemo.Attributes.Validation 1.0.0' to NuGetMvDemo.
Обратите внимание, что в папку Scripts добавилась папка Validation c JavaScript-файлами для проверки данных на стороне клиента. Кроме того, подключена сборка "MVCDemo.Attributes.Validation.dll". В случае удаления библиотеки все эти изменения будут отменены, а соответствующие файлы стерты.
Изменим Модель и задействуем в ней новые атрибуты проверки данных:
namespace NuGetMvDemo.Models
{
using System.ComponentModel.DataAnnotations;
using MVCDemo.Attributes.Validation;
public class TestModel
{
[Required]
[DataType(DataType.MultilineText)]
[BlockHtml (ErrorMessage="Html is not allowed.")]
[StringLengthRange(2,20)]
public string TextBlock { get; set; }
[Equal(true, ErrorMessage="Please check this checkbox.")]
public bool BooleanValue { get; set; }
}
}
Так же в Представление необходимо добавить ссылки на JavaScript-файлы:
@model NuGetMvDemo.Models.TestModel
@{
ViewBag.Title = "Create";
}
<h2>
Create</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/Validation/BlockHtmlAttribute.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/Validation/EqualAttribute.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
.........
Запустим проект и убедимся, что новые атрибуты работоспособны.
Автоматизируем создание установочного пакета
Копировать файлы каждый раз вручную не очень удобно. Конечно можно написать cmd-файл, но есть решение удобнее: спецификация NuGet позволяет указать файлы для включения в пакет. Таким образом, нет необходимости копировать их в папку.
Удалим все, за исключением "CustomValidationAttributesLib.nuspec", из папки nuget-package. Теперь откроем файл спецификаций и добавим в него список файлов:
<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata>
<id>MVCDemo.Attributes.Validation</id>
<version>1.0.0</version>
<authors>Andrey Veselov</authors>
<description>Custom validation attributes for ASP.NET and ASP.NET MVC.</description>
<language>en-US</language>
<licenseUrl>http://andrey.moveax.ru/terms-of-use.aspx</licenseUrl>
<projectUrl>http://andrey.moveax.ru/</projectUrl>
<tags>ASP.NET MVC</tags>
</metadata>
<files>
<file src="..\MVCDemo.Attributes.Validation\bin\Release\*.dll" target="lib" />
<file src="..\MVCDemo.Attributes.Validation\Scripts\Validation\*.js" target="content\Scripts\Validation" />
</files>
</package>
Файл или их группа (по маске) задается тегом <file>. Атрибут src определяет откуда их необходимо взять. При этом относительные пути считаются указанными относительно папки, где расположен файл со спецификацией. Второй атрибут target показывает место размещения в установочном пакете.
Важный момент – в этом случае будут использоваться только указанные в спецификации файлы.
В действия после сборки проекта (post-build step) добавим вызов "NuGet Command Line". При помощи условия поставим ограничение, что установочный пакет будет собираться только вместе с Release версией:
if $(ConfigurationName) == Release "$(DevEnvDir)..\Tools\nuget" pack "$(SolutionDir)nuget-package\CustomValidationAttributesLib.nuspec" /OutputDirectory "$(SolutionDir)nuget-package"
В данной команде используется опциональный параметр OutputDirectory. Он указывает куда сохранить файл созданного установочного пакета. Кроме того, подразумевается что nupack.exe скопирован в папку "Microsoft Visual Studio 10.0\Common7\Tools\".
Соберем проект и убедимся, что при сборке Release-версии в папку nuget-package добавляется "MVCDemo.Attributes.Validation.1.0.0.nupkg". При необходимости можно настроить публикацию пакета сервер или копирование его в локальный репозиторий.
И в завершении серии, предлагаю ознакомиться с справкой по использованию NuGet. В ней, кроме краткого изложения описанных в серии возможностей, рассмотрен вопрос модификации конфигурационных и исходных файлов проекта. Кроме того, есть инструкция по подключению поддержки nuspec-файлов в Visual Studio IntelliSense.
Исходный код различных вариантов проекта проекта (C#, Visual Studio 2010):
Проект исходной демонстрационной библиотеки (10 Kb)
Проект с созданием установочного пакета вручную (17 Kb)
Проект с автоматическим созданием установочного пакета (11 Kb)
Проект тестового ASP.NET MVC проекта (464 Kb)