<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: DotMakeBuild</title>
    <description>The latest articles on DEV Community by DotMakeBuild (@dotmake).</description>
    <link>https://dev.to/dotmake</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1268593%2F228700a7-f911-4072-9f39-3d3fdd20d6c4.png</url>
      <title>DEV Community: DotMakeBuild</title>
      <link>https://dev.to/dotmake</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dotmake"/>
    <language>en</language>
    <item>
      <title>Docfx-Plus: A template and a tool to enhance DocFx and migrate from SHFB (Sandcastle)</title>
      <dc:creator>DotMakeBuild</dc:creator>
      <pubDate>Sat, 13 Dec 2025 11:07:17 +0000</pubDate>
      <link>https://dev.to/dotmake/docfx-plus-a-template-and-a-tool-to-enhance-docfx-and-migrate-from-shfb-sandcastle-1kp0</link>
      <guid>https://dev.to/dotmake/docfx-plus-a-template-and-a-tool-to-enhance-docfx-and-migrate-from-shfb-sandcastle-1kp0</guid>
      <description>&lt;p&gt;We used SHFB for many years mainly because of its excellent &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; block and &lt;code&gt;NamespaceDoc&lt;/code&gt; support and it had been very stable but imho its theme and architecture is a bit outdated. DocFx is great in many ways but it misses some important features that we got used to with SHFB. So I created a new project &lt;a href="https://github.com/dotmake-build/docfx-plus" rel="noopener noreferrer"&gt;docfx-plus&lt;/a&gt; to enhance DocFx. My aim was to update existing project docs that depend on some SHFB features, without changes to xml comments, to DocFx. Check it out and let me know what you think.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dotmake.build/command-line/api/" rel="noopener noreferrer"&gt;&lt;strong&gt;Live Demo&lt;/strong&gt;&lt;/a&gt; - Sample API docs result for our other project &lt;a href="https://github.com/dotmake-build/command-line" rel="noopener noreferrer"&gt;DotMake Command-Line&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Just released DocFx-Plus v2.0.0 which now adds new &lt;code&gt;convert&lt;/code&gt; command to convert/migrate your existing &lt;code&gt;SHFB (Sandcastle Help File Builder)&lt;/code&gt; projects completely to &lt;code&gt;docfx&lt;/code&gt; projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project file (&lt;code&gt;.shfbproj&lt;/code&gt;) will be converted to &lt;code&gt;docfx.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Content Layout files (&lt;code&gt;.content&lt;/code&gt;) will be converted to &lt;code&gt;toc.yml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;MAML Topic files (&lt;code&gt;.aml&lt;/code&gt;) will be converted to Markdown files (&lt;code&gt;.md&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Namespace summaries will be converted to overwrite files (&lt;code&gt;.md&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Other content files like images will be copied&lt;/li&gt;
&lt;li&gt;By default &lt;code&gt;content&lt;/code&gt; subfolder will be rebased to &lt;code&gt;docs&lt;/code&gt;
and &lt;code&gt;icons&lt;/code&gt;, &lt;code&gt;media&lt;/code&gt; subfolders will be rebased to &lt;code&gt;images&lt;/code&gt;
to match &lt;code&gt;docfx&lt;/code&gt; conventions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sample Outputs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  These documentation projects are converted from SHFB to Docfx-Plus:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dotmake.build/docfx-plus/AntPlus/" rel="noopener noreferrer"&gt;Small Earth Technology ANT+ Class Library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dotmake.build/docfx-plus/SandcastleBuilder/" rel="noopener noreferrer"&gt;Sandcastle Help File Builder Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dotmake.build/docfx-plus/SandcastleMAMLGuide/" rel="noopener noreferrer"&gt;Sandcastle MAML Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dotmake.build/docfx-plus/XMLCommentsGuide/" rel="noopener noreferrer"&gt;Sandcastle XML Comments Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Screenshots
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwvqtt3rrt03o4y4xzhrj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwvqtt3rrt03o4y4xzhrj.png" alt="DocFx-Plus light theme" width="800" height="816"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxwncsf2tk3unk5j3zu9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxwncsf2tk3unk5j3zu9.png" alt="DocFx-Plus dark theme" width="800" height="816"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>documentation</category>
      <category>showdev</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Generating SVG sprites (spritesheets) for ASP.NET apps</title>
      <dc:creator>DotMakeBuild</dc:creator>
      <pubDate>Thu, 23 Oct 2025 05:24:22 +0000</pubDate>
      <link>https://dev.to/dotmake/introducing-svg-sprite-a-developer-friendly-svg-sprite-generator-for-net-2ie5</link>
      <guid>https://dev.to/dotmake/introducing-svg-sprite-a-developer-friendly-svg-sprite-generator-for-net-2ie5</guid>
      <description>&lt;p&gt;If you’ve ever wrangled dozens of SVG icons into a sprite sheet, you know how tedious and error-prone it can be. That’s why I built &lt;a href="https://www.nuget.org/packages/svg-sprite" rel="noopener noreferrer"&gt;&lt;code&gt;svg-sprite&lt;/code&gt;&lt;/a&gt; — a fast, standards-compliant CLI tool and library for generating &lt;code&gt;&amp;lt;symbol&amp;gt;&lt;/code&gt;-based SVG sprites with zero fuss.&lt;/p&gt;

&lt;p&gt;Whether you're building a design system, optimizing web assets, or just want clean, reusable icons, &lt;code&gt;svg-sprite&lt;/code&gt; gives you the control and clarity you need.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcy1jr6rure2a6esk33jn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcy1jr6rure2a6esk33jn.png" alt="DotMake Svg-Sprite CLI" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  What It Does
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Builds SVG sprites from individual files using &lt;code&gt;&amp;lt;symbol&amp;gt;&lt;/code&gt; elements
&lt;/li&gt;
&lt;li&gt;Preserves critical attributes like &lt;code&gt;viewBox&lt;/code&gt;, &lt;code&gt;fill&lt;/code&gt;, &lt;code&gt;stroke&lt;/code&gt;, and &lt;code&gt;id&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sanitizes and minifies input for web-ready output
&lt;/li&gt;
&lt;li&gt;Generates an HTML preview page to visually test your sprite
&lt;/li&gt;
&lt;li&gt;Extracts symbols back into individual SVGs for reverse workflows
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Example Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;svg-sprite build icons/&lt;span class="k"&gt;*&lt;/span&gt;.svg &lt;span class="nt"&gt;-o&lt;/span&gt; sprite.svg &lt;span class="nt"&gt;--html-preview&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command:&lt;br&gt;
• Combines all SVGs in &lt;code&gt;icons/&lt;/code&gt; into a single &lt;code&gt;sprite.svg&lt;/code&gt;&lt;br&gt;
• Generates &lt;code&gt;sprite-preview.html&lt;/code&gt; — a responsive grid of icons for QA&lt;/p&gt;


&lt;h3&gt;
  
  
  CLI + API: Use It Your Way
&lt;/h3&gt;

&lt;p&gt;Install the CLI globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet tool &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt; svg-sprite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the library in your .NET project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package DotMake.SvgSprite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Build an SVG sprite file from input SVG files&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;svgDocument&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SvgDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;svgSpriteBuilder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SvgSpriteBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;svgDocument&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Directory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnumerateFiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"inputs\"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"*.svg"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;svgDocumentToAdd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SvgDocument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;symbolId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetFileNameWithoutExtension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;svgSpriteBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddSymbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;svgDocumentToAdd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;symbolId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;svgDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"sprite.svg"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Why It’s Different
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Built with developer ergonomics in mind&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handles edge cases like missing IDs, duplicate names, and attribute conflicts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Designed for CI/CD pipelines, design systems, and static site generators&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fully open-source: &lt;a href="https://github.com/dotmake-build/svg-sprite" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Using generated SVG sprites
&lt;/h3&gt;

&lt;p&gt;Once you have an SVG sprite, for example &lt;code&gt;sprite.svg&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;symbol&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 640 640"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"address-book"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"currentColor"&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M448 112C456.8 112 464 119.2 464 128L464 512C464 520.8 456.8 528 448 528L160 528C151.2 528 144 520.8 144 512L144 128C144 119.2 151.2 112 160 112L448 112zM160 64C124.7 64 96 92.7 96 128L96 512C96 547.3 124.7 576 160 576L448 576C483.3 576 512 547.3 512 512L512 128C512 92.7 483.3 64 448 64L160 64zM304 312C334.9 312 360 286.9 360 256C360 225.1 334.9 200 304 200C273.1 200 248 225.1 248 256C248 286.9 273.1 312 304 312zM272 352C227.8 352 192 387.8 192 432C192 440.8 199.2 448 208 448L400 448C408.8 448 416 440.8 416 432C416 387.8 380.2 352 336 352L272 352zM576 144C576 135.2 568.8 128 560 128C551.2 128 544 135.2 544 144L544 208C544 216.8 551.2 224 560 224C568.8 224 576 216.8 576 208L576 144zM560 256C551.2 256 544 263.2 544 272L544 336C544 344.8 551.2 352 560 352C568.8 352 576 344.8 576 336L576 272C576 263.2 568.8 256 560 256zM576 400C576 391.2 568.8 384 560 384C551.2 384 544 391.2 544 400L544 464C544 472.8 551.2 480 560 480C568.8 480 576 472.8 576 464L576 400z"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;symbol&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 640 640"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"alarm-clock"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"currentColor"&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M466.6 114.2C461.2 115.9 455.3 116 450.4 113.3C444.6 110.1 438.6 107.1 432.6 104.4C422.2 99.7 418.9 86.1 428.5 79.8C443.5 69.9 461.5 64.1 480.8 64.1C533.4 64.1 576 106.7 576 159.3C576 172.5 573.3 185.1 568.4 196.6C563.9 207.1 550 206.4 543.5 197C539.7 191.5 535.7 186.2 531.5 181C528 176.6 527 170.8 527.7 165.2C527.9 163.3 528.1 161.3 528.1 159.3C528.1 133.2 506.9 112.1 480.9 112.1C476 112.1 471.2 112.9 466.7 114.3zM96.5 196.9C90 206.3 76 207 71.6 196.5C66.7 185 64 172.4 64 159.2C64 106.6 106.6 64 159.2 64C178.5 64 196.5 69.8 211.5 79.7C221.1 86 217.8 99.6 207.4 104.3C201.3 107.1 195.4 110 189.6 113.2C184.7 115.9 178.7 115.8 173.4 114.1C168.9 112.7 164.2 111.9 159.2 111.9C133.1 111.9 112 133.1 112 159.1C112 161.1 112.1 163.1 112.4 165C113.1 170.6 112.1 176.4 108.6 180.8C104.4 186 100.4 191.3 96.6 196.8zM496 352C496 254.8 417.2 176 320 176C222.8 176 144 254.8 144 352C144 449.2 222.8 528 320 528C417.2 528 496 449.2 496 352zM460.5 526.5C422.1 557.4 373.2 576 320 576C266.8 576 217.9 557.4 179.5 526.5L137 569C127.6 578.4 112.4 578.4 103.1 569C93.8 559.6 93.7 544.4 103.1 535.1L145.6 492.6C114.6 454.1 96 405.2 96 352C96 228.3 196.3 128 320 128C443.7 128 544 228.3 544 352C544 405.2 525.4 454.1 494.5 492.5L537 535C546.4 544.4 546.4 559.6 537 568.9C527.6 578.2 512.4 578.3 503.1 568.9L460.6 526.4zM344 248L344 342.1L385 383.1C394.4 392.5 394.4 407.7 385 417C375.6 426.3 360.4 426.4 351.1 417L303.1 369C298.6 364.5 296.1 358.4 296.1 352L296.1 248C296.1 234.7 306.8 224 320.1 224C333.4 224 344.1 234.7 344.1 248z"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/symbol&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use symbols from this sprite in your HTML pages like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;use&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"sprite.svg#address-book"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"width: 48px; height: 48px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;use&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"sprite.svg#alarm-clock"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that &lt;code&gt;&amp;lt;use&amp;gt;&lt;/code&gt; tag does not work cross-origin, including local HTML files (when not viewed from a web server),&lt;br&gt;
so in that case you should put/inline the SVG sprite into your HTML page and &lt;br&gt;
then you should only include the URL fragment in &lt;code&gt;href&lt;/code&gt; attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;svg&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;use&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#address-book"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"width: 48px; height: 48px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;use&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#alarm-clock"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that for &lt;code&gt;&amp;lt;use&amp;gt;&lt;/code&gt; tag, the old attribute &lt;code&gt;xlink:href&lt;/code&gt; is deprecated and the attribute &lt;code&gt;href&lt;/code&gt; is used since browser&lt;br&gt;
versions released from 2016-2019.&lt;/p&gt;




&lt;h3&gt;
  
  
  Feedback Welcome
&lt;/h3&gt;

&lt;p&gt;I built &lt;code&gt;svg-sprite&lt;/code&gt; to solve real-world pain points in icon workflows. If you have ideas, edge cases, or feature requests, I’d love to hear them.&lt;/p&gt;




&lt;h3&gt;
  
  
  Additional info
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dotmake.build/svg-sprite/api/" rel="noopener noreferrer"&gt;DotMake Svg-Sprite API docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://css-tricks.com/svg-symbol-good-choice-icons/" rel="noopener noreferrer"&gt;SVG symbol a Good Choice for Icons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@hayavuk/complete-guide-to-svg-sprites-7e202e215d34" rel="noopener noreferrer"&gt;Complete guide to SVG sprites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/use" rel="noopener noreferrer"&gt;The &lt;code&gt;&amp;lt;use&amp;gt;&lt;/code&gt; element&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/symbol" rel="noopener noreferrer"&gt;The &lt;code&gt;&amp;lt;symbol&amp;gt;&lt;/code&gt; element&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/svg" rel="noopener noreferrer"&gt;The &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; element &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>svg</category>
      <category>sprite</category>
      <category>spritesheet</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Building a Command-Line (CLI) app using System.CommandLine library in C# and .NET</title>
      <dc:creator>DotMakeBuild</dc:creator>
      <pubDate>Mon, 29 Jan 2024 13:42:27 +0000</pubDate>
      <link>https://dev.to/dotmake/building-a-command-line-cli-app-using-systemcommandline-library-in-c-and-net-6n1</link>
      <guid>https://dev.to/dotmake/building-a-command-line-cli-app-using-systemcommandline-library-in-c-and-net-6n1</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe62b5yx5loshffqilm66.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe62b5yx5loshffqilm66.png" alt="Create a CLI program fast and easily!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;System.CommandLine is a very good parser but you need a lot of boilerplate code to get going and the API is hard to discover.&lt;br&gt;
This becomes complicated to newcomers and also you would have a lot of ugly code in your &lt;code&gt;Program.cs&lt;/code&gt; to maintain. &lt;br&gt;
What if you had an easy class-based layer combined with a good parser?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/dotmake-build/command-line" rel="noopener noreferrer"&gt;DotMake.CommandLine&lt;/a&gt; is a library which provides declarative syntax for &lt;br&gt;
&lt;a href="https://github.com/dotnet/command-line-api" rel="noopener noreferrer"&gt;System.CommandLine&lt;/a&gt; &lt;br&gt;
via attributes for easy, fast, strongly-typed (no reflection) usage. The library includes includes a source generator &lt;br&gt;
which automagically converts your classes to CLI commands and properties to CLI options or CLI arguments. &lt;br&gt;
Supports &lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/trim-self-contained" rel="noopener noreferrer"&gt;trimming&lt;/a&gt;, &lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot" rel="noopener noreferrer"&gt;AOT compilation&lt;/a&gt; and&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection" rel="noopener noreferrer"&gt;dependency injection&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.nuget.org/packages/DotMake.CommandLine" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fnuget%2Fv%2FDotMake.CommandLine%3Fstyle%3Dfor-the-badge%26logo%3Dnuget" alt="Nuget"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Install the library to your console app project with  &lt;a href="https://www.nuget.org/" rel="noopener noreferrer"&gt;NuGet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In your project directory, via dotnet cli:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;

dotnet add package DotMake.CommandLine


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;or in Visual Studio Package Manager Console:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;

&lt;/span&gt;&lt;span class="gp"&gt;PM&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Install-Package DotMake.CommandLine
&lt;span class="go"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;.NET 6.0 and later project or .NET Standard 2.0 and later project (note that .NET Framework 4.7.2+ can reference netstandard2.0 libraries).
If your target framework is below net5.0, you also need &lt;code&gt;&amp;lt;LangVersion&amp;gt;9.0&amp;lt;/LangVersion&amp;gt;&lt;/code&gt; tag (minimum) in your .csproj file.&lt;/li&gt;
&lt;li&gt;Visual Studio 2022 v17.3+ or .NET SDK 6.0.407+ (our incremental source generator requires performance features added first in these versions).&lt;/li&gt;
&lt;li&gt;Usually a console app project but you can also use a class library project which will be consumed later.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Delegate-based model
&lt;/h3&gt;

&lt;p&gt;Create a CLI App with DotMake.Commandline in seconds!&lt;br&gt;
In Program.cs, add this simple code:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="n"&gt;Cli&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="n"&gt;CliArgument&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;argument1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;option1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$@"Value for &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argument1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt; parameter is '&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;argument1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$@"Value for &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;option1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt; parameter is '&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;option1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And that's it! You now have a fully working command-line app.&lt;/p&gt;

&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Pass a delegate (a parenthesized lambda expression or a method reference) which has parameters that represent your options and arguments, to &lt;code&gt;Cli.Run&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A parameter is by default considered as a CLI option but you can;

&lt;ul&gt;
&lt;li&gt;Mark a parameter with &lt;code&gt;CliArgument&lt;/code&gt; attribute to make it a CLI argument and specify settings (see &lt;a href="https://dotmake.build/api/html/T_DotMake_CommandLine_CliArgumentAttribute.htm" rel="noopener noreferrer"&gt;CliArgumentAttribute&lt;/a&gt; docs for more info).&lt;/li&gt;
&lt;li&gt;Mark a parameter with &lt;code&gt;CliOption&lt;/code&gt; attribute to specify CLI option settings (see &lt;a href="https://dotmake.build/api/html/T_DotMake_CommandLine_CliOptionAttribute.htm" rel="noopener noreferrer"&gt;CliOptionAttribute&lt;/a&gt; docs for more info).&lt;/li&gt;
&lt;li&gt;Mark the delegate itself with &lt;code&gt;CliCommand&lt;/code&gt; attribute to specify CLI command settings (see &lt;a href="https://dotmake.build/api/html/T_DotMake_CommandLine_CliCommandAttribute.htm" rel="noopener noreferrer"&gt;CliCommandAttribute&lt;/a&gt; docs for more info).&lt;/li&gt;
&lt;li&gt;Note that for being able to mark a parameter with an attribute in an anonymous lambda function, 
if your target framework is below net6.0, you also need &lt;code&gt;&amp;lt;LangVersion&amp;gt;10.0&amp;lt;/LangVersion&amp;gt;&lt;/code&gt; tag (minimum) in your .csproj file.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Set a default value for a parameter if you want it to be optional (not required to be specified on the command-line).&lt;/li&gt;

&lt;li&gt;Your delegate can be &lt;code&gt;async&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;Your delegate can have a return type &lt;code&gt;void&lt;/code&gt; or &lt;code&gt;int&lt;/code&gt; and if it's async &lt;code&gt;Task&lt;/code&gt; or &lt;code&gt;Task&amp;lt;int&amp;gt;&lt;/code&gt;.&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Class-based model
&lt;/h3&gt;

&lt;p&gt;While delegate-based model above is useful for simple apps, for more complex apps, you can use the class-based model.&lt;br&gt;
Create a simple class like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;DotMake.CommandLine&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;CliCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"A root cli command"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RootCliCommand&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;CliOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Description for Option1"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Option1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"DefaultForOption1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;CliArgument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Description for Argument1"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Argument1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$@"Handler for '&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;FullName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;' is run:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$@"Value for &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Option1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt; property is '&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Option1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$@"Value for &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Argument1&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s"&gt; property is '&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Argument1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In Program.cs, add this single line:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="n"&gt;Cli&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RootCliCommand&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And that's it! You now have a fully working command-line app. You just specify the name of your class which represents your root command to &lt;code&gt;Cli.Run&amp;lt;&amp;gt;&lt;/code&gt; method and everything is wired.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;args&lt;/code&gt; is the string array typically passed to a program. This is usually&lt;br&gt;
the special variable &lt;code&gt;args&lt;/code&gt; available in &lt;code&gt;Program.cs&lt;/code&gt; (new style with top-level statements)&lt;br&gt;
or the string array passed to the program's &lt;code&gt;Main&lt;/code&gt; method (old style).&lt;br&gt;
We also have method signatures which does not require &lt;code&gt;args&lt;/code&gt;, &lt;br&gt;
for example you can also call &lt;code&gt;Cli.Run&amp;lt;RootCliCommand&amp;gt;()&lt;/code&gt; and in that case &lt;code&gt;args&lt;/code&gt; will be retrieved automatically from the current process via &lt;code&gt;Cli.GetArgs()&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want to go async, just use this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Cli&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RootCliCommand&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To handle exceptions, you just use a try-catch block:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="k"&gt;try&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Cli&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RootCliCommand&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"Exception in main: {0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;System.CommandLine, by default overtakes your exceptions that are thrown in command handlers (even if you don't set an exception handler explicitly) but DotMake.CommandLine, by default allows the exceptions to pass through. However if you wish, you can easily use an exception handler by using &lt;code&gt;configureBuilder&lt;/code&gt; delegate parameter like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="n"&gt;Cli&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RootCliCommand&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseExceptionHandler&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"Exception in command handler: {0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you need to simply parse the command-line arguments without invocation, use this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rootCliCommand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Cli&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RootCliCommand&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you need to examine the parse result, such as errors:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rootCliCommand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Cli&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RootCliCommand&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;parseResult&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parseResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Mark the class with &lt;code&gt;CliCommand&lt;/code&gt; attribute to make it a CLI command (see &lt;a href="https://dotmake.build/api/html/T_DotMake_CommandLine_CliCommandAttribute.htm" rel="noopener noreferrer"&gt;CliCommandAttribute&lt;/a&gt; docs for more info).&lt;/li&gt;
&lt;li&gt;Mark a property with &lt;code&gt;CliOption&lt;/code&gt; attribute to make it a CLI option (see &lt;a href="https://dotmake.build/api/html/T_DotMake_CommandLine_CliOptionAttribute.htm" rel="noopener noreferrer"&gt;CliOptionAttribute&lt;/a&gt; docs for more info).&lt;/li&gt;
&lt;li&gt;Mark a property with &lt;code&gt;CliArgument&lt;/code&gt; attribute to make it a CLI argument (see &lt;a href="https://dotmake.build/api/html/T_DotMake_CommandLine_CliArgumentAttribute.htm" rel="noopener noreferrer"&gt;CliArgumentAttribute&lt;/a&gt; docs for more info).&lt;/li&gt;
&lt;li&gt;Add a method with name &lt;code&gt;Run&lt;/code&gt; or &lt;code&gt;RunAsync&lt;/code&gt; to make it the handler for the CLI command. The method can have one of the following signatures: &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;-&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

   &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
```c#
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;int Run()&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  - 
   ```c#


   async Task RunAsync()


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
```c#
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;async Task RunAsync()&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Optionally the method signature can have a System.CommandLine.Invocation.InvocationContext parameter in case you need to access it:

  - 
   ```c#


   Run(InvocationContext context)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;-&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

   &lt;span class="nf"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InvocationContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The signatures which return int value, sets the ExitCode of the app.&lt;br&gt;
  If no handler method is provided, then by default it will show help for the command.&lt;br&gt;
  This can be also controlled manually by extension method &lt;code&gt;ShowHelp&lt;/code&gt; in &lt;code&gt;InvocationContext&lt;/code&gt;.&lt;br&gt;
  Other extension methods &lt;code&gt;IsEmptyCommand&lt;/code&gt; and &lt;code&gt;ShowValues&lt;/code&gt; are also useful.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call &lt;code&gt;Cli.Run&amp;lt;&amp;gt;&lt;/code&gt; or&lt;code&gt;Cli.RunAsync&amp;lt;&amp;gt;&lt;/code&gt; method with your class name to run your CLI app (see &lt;a href="https://dotmake.build/api/html/T_DotMake_CommandLine_Cli.htm" rel="noopener noreferrer"&gt;Cli&lt;/a&gt; docs for more info).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Additional documentation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dotmake.build/api/" rel="noopener noreferrer"&gt;DotMake Command-Line API docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/dotnet/standard/commandline/syntax" rel="noopener noreferrer"&gt;Command-line syntax overview for System.CommandLine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cli</category>
      <category>console</category>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
