Net cli что это
Создадим первую программу на языке C#. Что для этого нужно? Прежде всего для написания кода программы нам понадобится текстовый редактор. В принципе можно выбрать любой понравившийся текстовый редактор, например, встроенный в Windows по умолчанию блокнот. Но я в данном случае буду ориентироваться на более изощренный текстовый редактор Visual Studio Code . Данный текстовый редактор доступен для всех основных операционных систем: Windows, MacOS, Linux. Он доступен по ссылке загрузить Visual Studio Code
Второй необходимый компонент для создания программ — компилятор. Для компиляции, построения, запуска и ряда других задач Microsoft предоставляет набор инструментов, который называется .NET SDK . Загрузим его со страницы https://dotnet.microsoft.com/en-us/download.
На странице https://dotnet.microsoft.com/en-us/download/dotnet/7.0 при необходимости можно найти все возможные варианты SDK под различные архитектуры и системы.
После загрузки запустим установщик .NET SDK:
И после установки .NET SDK мы можем начать свою славную поступь в прекрасный мир программирования на C#.
Создадим первый проект. Для этого определим какую-нибудь новую папку для проекта. Например, пусть мы создали для проекта папку C:\dotnet\helloapp . Откроем терминал/командную строку и с помощью команды cd перейдем к этой папке.
cd C:\dotnet\helloapp
Для создания проекта в .NET CLI применяется команда dotnet new , которой передается тип проекта. Мы будем создавать консольное приложение, поэтому будем использовать тип console . Итак, в введем в терминале следующую команду:
dotnet new console
В данном случае мы указываем, что создаваемый проект будет представлять консольное приложение.
После выполнения этой команды в папке helloapp будет создан проект с минимальным набором стандартных файлов и папок.
В частности, мы можем найти в папке проекта файл helloapp.csproj . Это главный файл проекта, который определяет его конфигурацию. Мы можем открыть его в любом текстовом редакторе, просмотреть и при необходимости изменить.
И, кроме того, по умолчанию создается главный файл программы Program.cs со следующим содержимым:
// See https://aka.ms/new-console-template for more information Console.WriteLine("Hello, World!");
Соответственно, если нам надо внести изменения в исходный код программы, то мы будем изменять содержимое именно этого файла.
В принципе этот минимальный проект уже можно запускать. Для запуска проекта введем в командной строке следующую команду:
dotnet run
После выполнения команды в проекте в папке bin\Debug\net7.0 появятся файлы программы helloapp.dll и helloapp.exe, которые можно вручную запустить на компьютере, где установлен .NET 7.
Теперь изменим весь код программы. Для этого откроем файл Program.cs в каком-нибудь текстовом редакторе и изменим его код на следующий:
Console.Write("Введите свое имя: "); var name = Console.ReadLine(); // вводим имя Console.WriteLine($"Привет "); // выводим имя на консоль
По сравнению с автоматически сгенерированным кодом я внес несколько изменений. Теперь первой строкой выводится приглашение к вводу.
Console.Write("Введите свое имя: ");
Метод Console.Write() выводит на консоль некоторую строка. В данном случае это строка «Введите свое имя: «.
На второй строке определяется строковая переменная name, в которую пользователь вводит информацию с консоли:
var name = Console.ReadLine();
Ключевое слово var указывает на определение переменной. В данном случае переменная называется name . И ей присваивается результат метода Console.ReadLine() , который позволяет считать с консоли введенную строку. То есть мы введем в консоли строку (точнее имя), и эта строка окажется в переменой name .
Затем введенное имя выводится на консоль:
Console.WriteLine($"Привет ");
Чтобы ввести значение переменной name внутрь выводимой на консоль строки, применяются фигурные скобки <>. То есть при выводе строки на консоль выражение будет заменяться на значение переменной name — введенное имя.
Однако чтобы можно было вводить таким образом значения переменных внутрь строки, перед строкой указывается знак доллара $.
Теперь протестируем проект, запустив его на выполнение с помощью команды
Создание CLI-приложений при помощи System.CommandLine в .NET
В .NET уже несколько лет существует библиотека System.CommandLine, позволяющая быстро создавать CLI-приложения. Несмотря на то, что библиотека ещё в стадии beta, её активно используют и сами разработчики Microsoft, например, в утилите dotnet из пакета .NET SDK.
Преимущества этой библиотеки в том, что она позволяет сосредоточиться на разработке полезного функционала приложения и не тратить время на создание парсера команд, опций и аргументов, а также имеет широкие возможности для кастомизации.
Реализация простого CLI-приложения
Библиотека поддерживает следующие виды токенов:
Опции и аргументы определяются совместно через обобщённый тип Option :
var left = new Option( aliases: new[] < "-l", "--left" >, description: "Left operand") < IsRequired = true, Arity = ArgumentArity.ExactlyOne >; var right = new Option( aliases: new[] < "-r", "--right" >, description: "Right operand") < IsRequired = true, Arity = ArgumentArity.ExactlyOne >;
Полностью исходный код можно найти в нашем GitLab-репозитории.
Subcommand и command отличаются тем, что subcommand определяет группу команд, а command определяет непосредственно действие, выполняемое командой.
Определим для начала команду sum:
var sum = new Command("sum", "Sum of the two numbers"); sum.Add(left); sum.Add(right); sum.SetHandler((l, r) => Console.WriteLine(l + r), left, right);
Разделение на команды и группы команд очень условное, т.к. с точки зрения C# оба вида определяются через класс Command . Также нам ничто не мешает определить действие и для группы команд:
var math = new Command("math", "Mathematical operations"); math.Add(sum); math.SetHandler(() => Console.Write("Math command handler"));
Помимо примитивных типов, библиотека также поддерживает массивы, списки, FileInfo , DirectoryInfo и другие. Полный список можно узнать, заглянув в документацию. Если есть необходимость привязать опции к кастомному типу, то можно воспользоваться встроенным механизмом привязки через тип BinderBase . Определим операцию вычитания, используя этот способ:
public record Subtract(double Left, double Right) < public double Calc() < var result = Left - Right; File.WriteAllText("result.txt", $""); return result; > > public class SubtractBinder : BinderBase < private readonly Option_left; private readonly Option _right; public SubtractBinder(Option left, Option right) => (_left, _right) = (left, right); protected override Subtract GetBoundValue(BindingContext bindingContext) => new Subtract( bindingContext.ParseResult.GetValueForOption(_left), bindingContext.ParseResult.GetValueForOption(_right)); >
Тогда определение хендлера для команды вычитания будет выглядеть следующим образом:
subtract.SetHandler( (sub) => Console.WriteLine(sub.Calc()), new SubtractBinder(left, right));
Осталось определить Root command через одноимённый класс RootCommand :
var root = new RootCommand("CLI app example"); root.Add(math); await root.InvokeAsync(args);
Теперь можно собрать приложение и проверить работу:
dotnet run -– math // вывод: Math command handler dotnet run -— math sum -l 4 -r 7 // вывод: 13 dotnet run -— math subtract -l 10 -r 3 // вывод: 7
Внедрение зависимостей
Жизненный цикл CLI-приложения выглядит следующим образом:
- Вызывается некоторая команда.
- Запускается процесс.
- Происходит обработка данных, возвращается результат.
- Процесс завершается.
Классические контейнеры зависимостей не рекомендуется использовать, поскольку зависимости одной команды могут быть совершенно не нужны для другой команды, а инициализация всех зависимостей может увеличить время запуска CLI-приложения. Вместо этого можно воспользоваться механизмом внедрения зависимостей для конкретного обработчика. Для этого снова понадобится класс BinderBase . Определим новый класс ResultWriter , который будет записывать результат математической операции в файл:
public class ResultWriter < public void Write(double result) =>File.WriteAllText("result.txt", $""); >
Теперь создадим класс ResultWriterBinder . Этот класс инкапсулирует экземпляр ResultWriter :
public class ResultWriterBinder : BinderBase < private readonly ResultWriter _resultWriter = new ResultWriter(); protected override ResultWriter GetBoundValue(BindingContext bindingContext) =>_resultWriter; >
Теперь определим операцию умножения и внедрим туда экземпляр ResultWriter :
var multiply = new Command("multiply", "Multiply one number by another"); multiply.Add(left); multiply.Add(right); multiply.SetHandler((left, right, resultWriter) => < var result = left * right; resultWriter.Write(result); Console.WriteLine(result); >, left, right, new ResultWriterBinder());
Такой подход позволяет внедрять зависимости в обработчики команд независимо друг от друга.
Кастомизация вывода
Справка генерируется автоматически из описаний, которые использовались при инициализации опций и команд. Например, команда cli-app math sum -h отобразит следующее:
Description: Sum of the two numbers Usage: cli-app math sum [options] Options: -l, --left (REQUIRED) Left operand -r, --right (REQUIRED) Right operand -?, -h, --help Show help and usage information
При желании можно заменить любой раздел справки, например, Description или создать новый. Добавим новую строку с текстом «This is a new section» в начало справки:
using System.CommandLine.Builder; using System.CommandLine.Help; using System.CommandLine.Parsing; // остальной код var parser = new CommandLineBuilder(root) .UseDefaults() .UseHelp(ctx => ctx.HelpBuilder.CustomizeLayout(x => HelpBuilder.Default .GetLayout() .Prepend(d => Console.WriteLine("This is a new section")))) .Build();
Тогда вывод станет следующим:
This is a new section Description: Sum of the two numbers // остальной текст
Если требуется улучшить внешний вид вывода данных в целом, то сделать это можно, например, написав кастомный способ отображения при помощи методов и свойств класса Console, таких как SetCursorPosition, ForegroundColor, BackgroundColor и т.д. Либо воспользоваться 3rd-party библиотеками:
1. ShellProgressBar. Простая библиотека для отображения прогресса в командном окне.
2. Spectre.Console. Мощная библиотека для создания красивых консольных приложений, которая имеет множество компонентов, упрощающих создание интерфейса. Кстати, обложка для статьи была сделана с помощью этой библиотеки.
3. ConsoleGUI. Позволяет создавать полноценный GUI на основе консоли. Судя по всему, автор вдохновлялся WPF, так как в ней содержатся привычные для этого фреймворка компоненты: TextBox, CheckBox, DataGrid, DockPanel и другие.
Заключение
Библиотека System.CommandLine является полезным инструментом для создания CLI-приложений. Она даёт разработчикам гибкий инструментарий для работы командами и опциями, что позволяет сократить время разработки и создать удобный и функциональный пользовательский интерфейс.
Shared Source CLI – открытая версия .Net от Microsoft
В конце марта на сайте Microsoft появился архив под длинным названием Shared Source Common Language Infrastructure (CLI) Implementation Beta (кодовое название Rotor). В его описании (что не характерно для сайта Microsoft) часто мелькает название FreeBSD, а также навевающий ассоциации со свободно распространяемым ПО термин Shared Source. Этот архив – ни что иное, как усеченный вариант .Net CLR, который был изменен Microsoft в целях переносимости. Что же все это значит?
Shared Source – это новый подход Microsoft к распространению программного обеспечения. Очевидно, что эта программа появилась под натиском все усиливающихся сообществ разработчиков ПО с открытым кодом. В рамках Shared Source Microsoft позволяет скачать и использовать исходные коды некоторых своих разработок. К сожалению, документ The Microsoft Shared Source Philosophy, который должен объяснить суть программы, никаких конкретных слов не содержит. Он просто говорит, что Open Source – это плохо, а Shared Source – хорошо.
Но политика распространения кода – это одно, а сам код – другое. Код доступен кому угодно в виде 11-мегабайтного tgz-файла. Сейчас CLI работает под Windows XP и FreeBSD, но в будущем возможно появление версий и для других платформ. Главное достоинство CLI – он содержит большую часть исходных кодов библиотек .Net. В интернете уже появились сообщения, что CLI можно собрать под W2k и другими ОС Microsoft. Впрочем, было бы странно, если бы код, предназначеный для портирования на другие платформы, нельзя было перенести на родные платформы.
Shared Source Common Language Infrastructure (CLI) Implementation – это исходный код работающей реализации стандартов ECMA-334 (C#) и ECMA-335, описывающего инфраструктуру Common Language Infrastructure, аналогичную CLR, используемой в .NET Framework (www.ecma.org).
Архив CLI в форме исходного кода содержит:
- Реализацию runtime CLI (ECMA-335).
- Компиляторы C# (ECMA-334) и JScript, работающие с CLI.
- Средства разработки для CLI – ассемблер/дизассемблер языка MSIL (ilasm, ildasm), отладчик (cordbg), утилиту для просмотра метаданных (metainfo) и другие утилиты.
- Слой адаптации к платформе (Platform Adaptation Layer, PAL), обеспечивающий работоспособность CLI на FreeBSD.
- Средства для сборки проектов (nmake, build и др.).
- Документацию.
- Тестовые средства.
Сам Microsoft заявляет, что Rotor не является переносом .Net на другую платформу, и что в реализациях CLI и CLR существуют значительные различия. Ключевым словом здесь является «различия». Кроме того, пока что CLI существует только в бета-версии. Сроки выхода следующих бета-версий и окончательной версии не называются. Несмотря на заверения разработчиков в стабильности работы кода, на данном этапе применение его в реальных проектах сомнительно. Но это и не важно. Главное, при затруднениях в .Net-разработке можно посмотреть, как что устроено и обойти подводные камни.
Чтобы перенести Windows-приложение на другую платформу, нужно перенести Win32 API, чтобы перенести COM – нужно перенести Win32 API и COM API, ну, а чтобы перенести .Net – нужно перенести Win32 API, COM API и .Net. Нам трудно судить, получилась ли эта шутка смешной, но MS, хотя и частично, воплотила ее в жизнь. Для переносимости был создан PAL (Platform Adaptation Layer), набор динамически подключаемых библиотек, реализующий основные функции Win32 и COM API (242 функции), используемые в CLI. PAL аналогичен Apache Portable Runtime (APR). Теоретически, перенос Rotor на другую ОС должен сводиться исключительно к переносу PAL. PAL позволяет реализовать:
- Создание и уничтожение контекстов приложений.
- Отладку и поддержку средств разработки.
- Работу с потоками и управление памятью.
- Исключения.
- Локали.
- Операции синхронного файлового ввода/вывода.
- Операции асинхронного сетевого ввода/вывода.
- Критические секции, мьютексы, семафоры и события в стиле Win32.
- Работу с локальным COM.
Первая версия Rotor компилируется под Windows XP и FreeBSD 4.5. Кроме огромного количества памяти, для ее работы потребуется Perl. FreeBSD, как правило, содержит Perl, а под Windows дело обстоит хуже. Большинству желающих придется скачать Perl с сайта ActiveState. Пользователям Windows понадобится и Visual Studio .NET (или другой компилятор C/C++, а так же время на адаптацию кода под него), так как наличия .NET Framework SDK недостаточно для Rotor.
В развернутом виде Rotor занимает около 70 МБ. Однако после компиляции это добро займет полгигабайта под Windows, и около гигабайта – под FreeBSD. 24 МБ из них – это исходные коды библиотек, входящих в .Net, написанных на С#. Остальное – это в основном исходники на С++ и make-файлы. Это позволяет сказать, что основная часть .Net написана на С++.
Подробные инструкции по установке и начальным шагам использования Rotor можно найти в статьях Dave Stutz и Brian Jepson на www.oreillynet.com.
Практическая ценность CLI, то есть применимость в реальных приложениях, пока не очень понятна. Однако в Shared Source CLI много интересного для разработчика. Например, разработчики, которым интересно, что у .Net внутри, могут посмотреть на реализации сборки мусора, JIT-компиляции, протоколов безопасности, организацию среды и систем виртуальных объектов.
Но, если рассматривать CLI с точки зрения противостояния .Net-Java, это очень сильный ход Microsoft. Он если и не выбьет из рук оппонентов доводы о «непереносимости» и закрытости продуктов Microsoft, то значительно ослабит их.
MS заявляет, что Shared Source CLI может представить значительный интерес для академических и образовательных учреждений, так как на его основе легко организовать учебный курс по современным компиляторам или JIT-оптимизации. Но это лукавство. Дело в том, что многие университеты уже выбрали Яву для своих учебных программ. Главным их доводом было отсутствие исходного кода в .Net, не позволяющее студентам и преподавателям углубиться в изучаемую проблему на только ими определяемую глубину.
Еще одна категория разработчиков, которой может пригодиться CLI – энтузиасты переноса .Net на другие платформы. Лично я знаю только одного такого, но догадываюсь, что их может быть несколько. Для них CLI – это подарок судьбы, руководство к действию и эталонная реализация в одном флаконе.
Впервые статья была опубликована в журнале <Технология Клиент-Сервер>.
Эту и множество других статей по программированию, разработке БД, многоуровневым технологиям (COM, CORBA, .Net, J2EE) и CASE-средствам вы можете найти на сайте www.optim.su и на страницах журнала.Технология>
Общеязыковая инфраструктура CLI
К удивлению большинства разработчиков, сборки .NET могут разрабатываться и выполняться в средах операционных систем производства не Microsoft, в частности — в Mac OS X, различных дистрибутивах Linux, Solaris, а также на устройствах типа iPhone производства Apple (через API-интерфейс MonoTouch). Чтобы понять, что делает подобное возможным, необходимо рассмотреть еще одну используемую в мире .NET аббревиатуру — CLI, которая расшифровывается как .
Вместе с языком программирования C# и платформой .NET в Microsoft был также разработан набор официальных документов с описанием синтаксиса и семантики языков C# и CIL, формата сборок .NET, ключевых пространств имен и технических деталей работы гипотетического механизма исполняющей среды .NET (названного виртуальной системой выполнения — Virtual Execution System (VES)).
Все эти документы были поданы в организацию Ecma International и утверждены в качестве официальных международных стандартов. Среди них наибольший интерес представляют:
- документ ECMA-334, в котором содержится спецификация языка C#
- документ ECMA-335, в котором содержится спецификация общеязыковой инфраструктуры (CLI)
Важность этих документов становится очевидной с пониманием того факта, что они предоставляют третьим сторонам возможность создавать дистрибутивы платформы .NET для любого количества операционных систем и/или процессоров. Среди этих двух спецификаций документ ECMA-335 является более «объемным», причем настолько, что был разбит на шесть разделов, которые перечислены в следующей таблице:
Разделы документа ECMA-335 | Предназначение |
---|---|
Раздел I. Концепции и архитектура | В этом разделе описана общая архитектура CLI, в том числе правила CTS и CLS и технические детали функционирования механизма среды выполнения .NET |
Раздел II. Определение метаданных и семантика | В этом разделе описаны детали метаданных и формат сборок в .NET |
Раздел III. Набор инструкций CIL | В этом разделе описан синтаксис и семантика кода CIL |
Раздел IV. Профили и библиотеки | В этом разделе дается общий обзор тех минимальных и полных библиотек классов, которые должны поддерживаться в дистрибутиве .NET |
Раздел V | В этом разделе описан формат обмена деталями отладки |
Раздел VI. Дополнения | В этом разделе представлена коллекция дополнительных и более конкретных деталей, таких как указания по проектированию библиотек классов и детали по реализации компилятора CIL |
Следует иметь в виду, что в разделе IV (Профили и библиотеки) описан лишь минимальный набор пространств имен, в которых содержатся ожидаемые от дистрибутива CLI службы (наподобие коллекций, консольного ввода-вывода, файлового ввода-вывода, многопоточной обработки, рефлексии, сетевого доступа, ключевых средств защиты и возможностей для манипулирования XML-данными). Пространства имен, которые упрощают разработку веб-приложений (ASP.NET), доступ к базам данных (ADO.NET) и создание настольных приложений с графическим пользовательским интерфейсом (Windows Forms/Windows Presentation Foundation) в CLI не описаны.
Хорошая новость состоит в том, что в главных дистрибутивах .NET библиотеки CLI дополняются совместимыми с Microsoft эквивалентами ASP.NET, ADO.NET и Windows Forms, чтобы предоставлять полнофункциональные платформы для разработки приложений производственного уровня. На сегодняшний день популярностью пользуются две основных реализации CLI (помимо самого предлагаемого Microsoft и рассчитанного на Windows решения).