<?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>Forem: Diógenes Polanco</title>
    <description>The latest articles on Forem by Diógenes Polanco (@diogenespolanco).</description>
    <link>https://forem.com/diogenespolanco</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%2F247106%2Fb1a0440e-208c-4656-b773-9834af724dd2.png</url>
      <title>Forem: Diógenes Polanco</title>
      <link>https://forem.com/diogenespolanco</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/diogenespolanco"/>
    <language>en</language>
    <item>
      <title>nopCommerce CLI</title>
      <dc:creator>Diógenes Polanco</dc:creator>
      <pubDate>Mon, 27 Sep 2021 13:56:06 +0000</pubDate>
      <link>https://forem.com/diogenespolanco/nopcommerce-cli-4do5</link>
      <guid>https://forem.com/diogenespolanco/nopcommerce-cli-4do5</guid>
      <description>&lt;h1&gt;The modern web developer's tool.&lt;/h1&gt;
 

&lt;p&gt; 
  nopCommerce CLI is a development tool for build plugins for nopCommerce Solutions.
&lt;/p&gt; 
 



&lt;h2&gt;
  
  
  Development Setup
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Install &lt;a href="https://nodejs.org/es/download/" rel="noopener noreferrer"&gt;[node.js] &lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install &lt;a href="https://dotnet.microsoft.com/download" rel="noopener noreferrer"&gt;[dotnet core]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Clone &lt;a href="https://github.com/nopSolutions/nopCommerce" rel="noopener noreferrer"&gt;[nopCommerce]&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Setting Up a Plugin of nopCommerce
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install -g nopcli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ nopcli new -g=[GROUP NAME] -p=[PLUGIN NAME]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build the plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ nopcli build -g=[GROUP NAME] -p=[PLUGIN NAME]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;nopCommerce CLI is cross-platform, fast, scalable, has incredible tooling, and is loved by millions.&lt;/p&gt;

&lt;p&gt;
    &lt;a href="https://www.paypal.com/donate/?hosted_button_id=VM4NMF6PY4SMG" rel="noopener noreferrer"&gt;
    &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FDiogenesPolanco%2FnopCommerce-cli%2Fdevelopment%2Fsrc%2Fassets%2Fimages%2Fbadge.svg" alt="Badge" width="80" height="20"&gt;
    &lt;/a&gt;
    &lt;br&gt;&lt;br&gt;
    &lt;b&gt;🙌 Use &lt;a href="https://www.npmjs.com/package/nopcli" rel="noopener noreferrer"&gt;donations&lt;/a&gt; to help support &lt;b&gt;this&lt;/b&gt; project! 🙌&lt;/b&gt;
    &lt;br&gt; 
    &lt;br&gt; 
    &lt;b&gt;Love &lt;a href="https://github.com/DiogenesPolanco/nopCommerce-cli" rel="noopener noreferrer"&gt;nopCommerce CLI?&lt;/a&gt; Give our repo a star ⭐ ⬆️.&lt;/b&gt;
&lt;/p&gt;

</description>
      <category>nopcommerce</category>
      <category>cli</category>
      <category>ecommerce</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Which do you prefer vscode or Atom?</title>
      <dc:creator>Diógenes Polanco</dc:creator>
      <pubDate>Mon, 02 Dec 2019 04:48:33 +0000</pubDate>
      <link>https://forem.com/diogenespolanco/which-do-you-prefer-vscode-or-atom-2j02</link>
      <guid>https://forem.com/diogenespolanco/which-do-you-prefer-vscode-or-atom-2j02</guid>
      <description>&lt;p&gt;I have always had the need to find new tools for development purposes. They can be text editors, a library to manage tasks, a script to build an upcoming project, etc. The tools simplify the work environment and improve productivity at the same time. Among all text editors, Atom and Visual Studio Code are favorites among designers and developers. but is it interesting to know which one is preferred?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>healthydebate</category>
      <category>vscode</category>
      <category>atom</category>
    </item>
    <item>
      <title>Fluent validation with NetCore</title>
      <dc:creator>Diógenes Polanco</dc:creator>
      <pubDate>Sat, 23 Nov 2019 18:52:14 +0000</pubDate>
      <link>https://forem.com/diogenespolanco/fluent-validation-with-netcore-4o2h</link>
      <guid>https://forem.com/diogenespolanco/fluent-validation-with-netcore-4o2h</guid>
      <description>&lt;p&gt;Validations are usually a repetitive and sometimes complex process, depending on the project and its architecture.&lt;/p&gt;

&lt;p&gt;There are currently many libraries that allow you to automate the rules or validations that your project needs to achieve those milestones or functionalities.&lt;/p&gt;

&lt;p&gt;The library that I currently use is a fluent validation call that allows me to create processes to validate and verify the data inserted by the user in the view. ASP.NET MVC provides several validation mechanisms, such as Remote Validation, Validation through data logging, Fluent Validation and Custom Validation. In this article, we will read about Fluent validation. The fluent validation contains .NET libraries and the validation is done using the Lambda expression. Use fluent validation when you want to create advanced and complex validation for user data. &lt;/p&gt;

&lt;p&gt;Let's start these examples of use.&lt;/p&gt;

&lt;p&gt;You can install it using the NuGet package manager console within Visual Studio or VSCode by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package FluentValidation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, imagine that you have a Product class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; public class Product {
  public int Id { get; set; }
  public string Name { get; set; }
  public string Type { get; set; }
  public decimal Discount { get; set; }
  public decimal Price { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would define a set of validation rules for this class by inheriting from AbstractValidator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using FluentValidation; 

public class ProductValidator : AbstractValidator&amp;lt;Product&amp;gt; {
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The validation rules themselves should be defined in the validator class’s constructor.&lt;/p&gt;

&lt;p&gt;To specify a validation rule for a particular property, call the RuleFor method, passing a lambda expression that indicates the property that you wish to validate. For example, to ensure that the Surname property is not null, the validator class would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using FluentValidation;

public class ProductValidator : AbstractValidator&amp;lt;Product&amp;gt; {
  public ProductValidator() {
    RuleFor(product =&amp;gt; product.Name).NotNull();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run the validator, instantiate the validator object and call the Validate method, passing in the object to validate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Product product = new Product();
ProductValidator validator = new ProductValidator();

ValidationResult result = validator.Validate(product);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Validate method returns a ValidationResult object. This contains two properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IsValid - a boolean that says whether the validation suceeded.&lt;/li&gt;
&lt;li&gt;Errors - a collection of ValidationFailure objects containing details about any validation failures.
The following code would write any validation failures to the console:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Product product = new Product();
ProductValidator validator = new ProductValidator();

ValidationResult results = validator.Validate(product);

if(! results.IsValid) {
  foreach(var failure in results.Errors) {
    Console.WriteLine("Property " + failure.PropertyName)
    Console.WriteLine("Failed validation. Error was: " + failure.ErrorMessage);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use Fluent validation if you want to implement a complex or high level validation. &lt;a href="https://github.com/JeremySkinner/FluentValidation" rel="noopener noreferrer"&gt;I recommend using this library&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>the new features of AutoMapper in .net</title>
      <dc:creator>Diógenes Polanco</dc:creator>
      <pubDate>Wed, 13 Nov 2019 20:34:59 +0000</pubDate>
      <link>https://forem.com/diogenespolanco/the-new-features-of-automapper-in-net-5im</link>
      <guid>https://forem.com/diogenespolanco/the-new-features-of-automapper-in-net-5im</guid>
      <description>&lt;h1&gt;
  
  
  Table Of Contents
&lt;/h1&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    * [What is Automapper?](#Automapper)
    * [New features](#Features)
    * [Installation](#Installation)
    * [How to Use Automapper?](#AutomapperApplication) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  What is Automapper? &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;AutoMapper is an object-object mapper. Object-object mapping works by transforming an input object of one type into an output object of a different type. What makes AutoMapper interesting is that it provides some interesting conventions to take the dirty work out of figuring out how to map type A to type B. As long as type B follows AutoMapper’s established convention, almost zero configuration is needed to map two types.&lt;/p&gt;
&lt;h1&gt;
  
  
  New features &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    * Remove static API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
the way to do it now is:&lt;br&gt;&lt;/p&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
        * Remove dynamic maps&lt;br&gt;&lt;/p&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
the way to do it now is:&lt;br&gt;&lt;/p&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
        * Update Conditional Mapping&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
        * Help the runtime find the AM assembly&lt;br&gt;&lt;/p&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    * Match destination enumerable types with it's enumerable for LINQ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h1&gt;
  
  
  Installation &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;The first step is to install the corresponding NuGet package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package AutoMapper --version 9.0.0   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h1&gt;
  
  
  Now, what is the way to Use Automapper? &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;a href="https://github.com/DiogenesPolanco/AutoMapperDemo.git" rel="noopener noreferrer"&gt;You can clone my code!&lt;/a&gt;
&lt;/h1&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>automapper</category>
      <category>showdev</category>
    </item>
    <item>
      <title>My recommended list of dotnet nugets packages</title>
      <dc:creator>Diógenes Polanco</dc:creator>
      <pubDate>Thu, 07 Nov 2019 05:02:17 +0000</pubDate>
      <link>https://forem.com/diogenespolanco/my-recommended-list-of-dotnet-nugets-packages-1fib</link>
      <guid>https://forem.com/diogenespolanco/my-recommended-list-of-dotnet-nugets-packages-1fib</guid>
      <description>&lt;p&gt;I remember that when I was a novice developer, my colleagues always told me that I had to write code without having to use Tools, Add-ons, IDE, DLL, etc. to get guides, good practices or maybe not redo the wheel. Well, times have changed and now developers, regardless of whether they are new or superior, do not have such prejudices, but today they dare to tell me why I do this in this way if there is already a package that solves it and it is really phenomenal all the packages you can find in &lt;strong&gt;&lt;a href="https://www.nuget.org/" rel="noopener noreferrer"&gt;nuget&lt;/a&gt;&lt;/strong&gt;. So many solutions, algorithms and tools that make our lives easier every day.&lt;/p&gt;

&lt;p&gt;So here I share my recommended list of dotnet nugets packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/FluentValidation/" rel="noopener noreferrer"&gt;FluentValidation&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;A validation library for .NET that uses a fluent interface to construct strongly-typed validation rules.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/Autofac/" rel="noopener noreferrer"&gt;Autofac&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/NUnit/" rel="noopener noreferrer"&gt;NUnit&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;fluent assert syntax, parameterized, generic and theory tests and is user-extensible.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/Moq/" rel="noopener noreferrer"&gt;Moq&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;is the most popular and friendly mocking framework for .NET.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/iTextSharp/" rel="noopener noreferrer"&gt;iTextSharp&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt; is a PDF library that allows you to CREATE, ADAPT, INSPECT and MAINTAIN documents in the Portable Document Format (PDF), allowing you to add PDF functionality to your software projects with ease.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/Lib.AspNetCore.Security/" rel="noopener noreferrer"&gt;Lib.AspNetCore.Security&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;is a library which provides security features like Content Security Policy, Strict Transport Security or Expect-CT for ASP.NET &lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/Swashbuckle.AspNetCore.Swagger/" rel="noopener noreferrer"&gt;Swagger&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;Middleware to expose Swagger JSON endpoints from API's built on ASP.NET.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/elmah/" rel="noopener noreferrer"&gt;Elmah&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;is an application-wide error logging facility that is completely pluggable. &lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/HtmlAgilityPack/" rel="noopener noreferrer"&gt;HtmlAgilityPack&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;This is an agile HTML parser that builds a read/write DOM and supports plain XPATH or XSLT.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/StackExchange.Redis/" rel="noopener noreferrer"&gt;StackExchange.Redis&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;High performance Redis client, incorporating both synchronous and asynchronous usage.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/Hangfire/" rel="noopener noreferrer"&gt;HangFire&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;An easy and reliable way to perform fire-and-forget, delayed and recurring, long-running, short-running, CPU or I/O intensive tasks inside ASP.NET applications.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/MiniProfiler/" rel="noopener noreferrer"&gt;MiniProfiler&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;Lightweight mini-profiler, designed for ASP.NET (including MVC) (non-.NET Core) websites&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/Audit.NET/" rel="noopener noreferrer"&gt;Audit.NET&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;An extensible framework to audit executing operations in .NET and .NET Core.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/EnterpriseLibrary.Common/" rel="noopener noreferrer"&gt;EnterpriseLibrary.Common&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;The Enterprise Library Common assembly contains elements that are shared among multiple application blocks. &lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/EnterpriseLibrary.Data/" rel="noopener noreferrer"&gt;EnterpriseLibrary.Data&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;The Enterprise Library Data Access Application Block simplifies the development of tasks that implement common data access functionality. &lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/Dapper/" rel="noopener noreferrer"&gt;Dapper&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;A high performance Micro-ORM supporting SQL Server, MySQL, Sqlite, SqlCE, Firebird etc..&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/Npgsql/" rel="noopener noreferrer"&gt;Npgsql&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;Npgsql is the open source .NET data provider for PostgreSQL.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/LinqKit/" rel="noopener noreferrer"&gt;LinqKit&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;LinqKit.EntityFramework contains extensions for LINQ to SQL and Entity Framework. Include(...) and IAsync are supported.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/DocumentFormat.OpenXml/" rel="noopener noreferrer"&gt;DocumentFormat.OpenXml&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;The Open XML SDK provides tools for working with Office Word, Excel, and PowerPoint documents. &lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/Newtonsoft.Json" rel="noopener noreferrer"&gt;Newtonsoft.json&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;Json.NET is a popular high-performance JSON framework for .NET&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.nuget.org/packages/Unity/" rel="noopener noreferrer"&gt;Unity&lt;/a&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;This package contains Unity Container and Abstractions libraries as a single package.&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;



</description>
      <category>productivity</category>
      <category>codenewbie</category>
      <category>beginners</category>
      <category>showdev</category>
    </item>
    <item>
      <title>What is your favorite operating system?</title>
      <dc:creator>Diógenes Polanco</dc:creator>
      <pubDate>Tue, 05 Nov 2019 20:13:44 +0000</pubDate>
      <link>https://forem.com/diogenespolanco/what-is-your-favorite-operating-system-jn1</link>
      <guid>https://forem.com/diogenespolanco/what-is-your-favorite-operating-system-jn1</guid>
      <description></description>
      <category>healthydebate</category>
    </item>
    <item>
      <title>Implementing a Angular project with AspNet Core</title>
      <dc:creator>Diógenes Polanco</dc:creator>
      <pubDate>Mon, 04 Nov 2019 15:13:20 +0000</pubDate>
      <link>https://forem.com/diogenespolanco/implementing-a-angular-project-with-aspnet-core-2ik</link>
      <guid>https://forem.com/diogenespolanco/implementing-a-angular-project-with-aspnet-core-2ik</guid>
      <description>&lt;p&gt;This article will help us understand how to use the .NET Core command line interface to create and run an ASP.NET Core web application.&lt;/p&gt;

&lt;p&gt;This way of implementing an Angular project provides a convenient starting point for ASP.NET Core applications that use Angular and the Angular CLI to implement a rich client-side user interface (UI).&lt;/p&gt;

&lt;p&gt;The mechanism is equivalent to creating an ASP.NET Core project to act as an API back-end and an angular CLI project to act as an UI. This route offers the convenience of hosting both types of projects in a single application project. Consequently, the application project can be built and published as a single unit, which also allows us to deploy it to nopcommerce as a plugin.&lt;/p&gt;

&lt;p&gt;You'll learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a web app project&lt;/li&gt;
&lt;li&gt;How to use the SPA&lt;strong&gt; &lt;/strong&gt;subdirectory&lt;strong&gt; &lt;/strong&gt;approach&lt;/li&gt;
&lt;li&gt;Add pages, images, styles, modules&lt;/li&gt;
&lt;li&gt;Run the app&lt;/li&gt;
&lt;li&gt;Publish and deploy&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;&lt;strong&gt;Create a web app project&lt;/strong&gt;&lt;/h5&gt;

&lt;p&gt;Open a command shell, and enter the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dotnet new angular&lt;/code&gt;&lt;/pre&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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F11%2FDeepinScreenshot_select-area_20191103000136.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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F11%2FDeepinScreenshot_select-area_20191103000136.png" alt="" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-build" rel="noopener noreferrer"&gt;dotnet build&lt;/a&gt; to verify the app builds correctly. On the first run, the build process restores npm dependencies, which can take several minutes. Subsequent builds are much faster.&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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F11%2FDeepinScreenshot_select-area_20191103000316.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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F11%2FDeepinScreenshot_select-area_20191103000316.png" alt="" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-run" rel="noopener noreferrer"&gt;dotnet run&lt;/a&gt; to start the app. A message similar to the following is logged:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Now listening on: http://localhost:&amp;lt;port&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Navigate to this URL in a browser.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;In ASP.NET Core, supporting SPAs works via a middleware to then point to this directory (no matter what you call it). It does this by injecting the middleware as the last step in Startup’s Configure method:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.SpaServices.AngularCli;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace test
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            // In production, the Angular files will be served from this directory
            services.AddSpaStaticFiles(configuration =&amp;gt;
            {
                configuration.RootPath = "ClientApp/dist";
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            if (!env.IsDevelopment())
            {
                app.UseSpaStaticFiles();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =&amp;gt;
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller}/{action=Index}/{id?}");
            });

            app.UseSpa(spa =&amp;gt;
            {
                // To learn more about options for serving an Angular SPA from ASP.NET Core,
                // see https://go.microsoft.com/fwlink/?linkid=864501

                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This involves two calls: &lt;strong&gt;UseSpaStaticFiles &lt;/strong&gt;and &lt;strong&gt;UseSpa&lt;/strong&gt;. These calls set up the ability to get calls from a generated index.html that Angular-CLI builds for you. In this case, you’ll see that during development, it will launch ‘npm start’ for you; that is part of how it launches the development build of the Angular app.&lt;/p&gt;

&lt;p&gt;While the middleware is a good option if you’re building a single, monolithic SPA without much use for other web pages, I think for most developers, integrating ASP.NET Core into a traditional MVC application makes the most sense. You can typically keep an SPA as a separate folder and treat it as a child-project, without having to do a lot of integration between the two projects.&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;How to use the SPA subdirectory approach&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;suppose you have an Angular project in a subdirectory called &lt;strong&gt;ClientApp&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because this directory has its own&lt;strong&gt; package.json&lt;/strong&gt;, you can just use the CLI of the library you’re working with to do builds and such. You could even develop it in isolation without invoking the ASP.NET Core project, but since I’m usually adding the SPA to an existing Razor view, I generally just run them both.&lt;/p&gt;

&lt;p&gt;One issue with this method is that the build directory for the SPA project is usually in this directory. You could use the &lt;strong&gt;SpaStaticFiles &lt;/strong&gt;middleware to solve this, but I usually just change the configuration of the SPA to build into my &lt;strong&gt;wwwroot &lt;/strong&gt;directory. For example, this is what that looks like in the angular.json file (for the Vue.js CLI):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "test": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "progress": true,
            "extractCss": true,
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": ["src/assets"],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "src/styles.css"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "test:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "test:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "test:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.spec.json",
            "karmaConfig": "src/karma.conf.js",
            "styles": ["styles.css"],
            "scripts": [],
            "assets": ["src/assets"]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"],
            "exclude": ["**/node_modules/**"]
          }
        },
        "server": {
          "builder": "@angular-devkit/build-angular:server",
          "options": {
            "outputPath": "dist-server",
            "main": "src/main.ts",
            "tsConfig": "src/tsconfig.server.json"
          },
          "configurations": {
            "dev": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": true
            },
            "production": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false
            }
          }
        }
      }
    },
    "test-e2e": {
      "root": "e2e/",
      "projectType": "application",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "test:serve"
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": "e2e/tsconfig.e2e.json",
            "exclude": ["**/node_modules/**"]
          }
        }
      }
    }
  },
  "defaultProject": "test"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this case, I’m just telling the Vue.js CLI to output the build to a subdirectory of the &lt;strong&gt;js &lt;/strong&gt;folder in &lt;strong&gt;wwwroot&lt;/strong&gt;, so I don’t need to configure ASP.NET Core to look into the SPA directory directly. Angular and React both support this kind of output directory, if you don’t want to use the &lt;strong&gt;SpaStaticFiles &lt;/strong&gt;middleware.&lt;/p&gt;

&lt;p&gt;By using one or more subdirectories with their own build, you can have many SPA projects (even if they’re different frameworks) in one ASP.NET Core project. But it does have some limitations involving deployment and dependency management. By doing this, each project will have it’s own node_modules directory which means that build times can get very lengthy.&lt;/p&gt;

&lt;p&gt;Because you’re configuring the output directory into &lt;strong&gt;wwwroot&lt;/strong&gt;, you don’t need to specify including a directory when you deploy the project, but you will need to tell the MSBuild (e.g. &lt;strong&gt;csproj &lt;/strong&gt;file) to build the SPA project before you deploy. The trick here is to add a Target to your .&lt;strong&gt;csproj &lt;/strong&gt;file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish"&amp;gt;
    &amp;lt;!-- As part of publishing, ensure the JS resources are freshly built in production mode --&amp;gt;
    &amp;lt;Exec WorkingDirectory="$(SpaRoot)" Command="npm install" /&amp;gt;
    &amp;lt;Exec WorkingDirectory="$(SpaRoot)" Command="npm run build -- --prod" /&amp;gt;
    &amp;lt;Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:ssr -- --prod" Condition=" '$(BuildServerSideRenderer)' == 'true' " /&amp;gt;

    &amp;lt;!-- Include the newly-built files in the publish output --&amp;gt;
    &amp;lt;ItemGroup&amp;gt;
      &amp;lt;DistFiles Include="$(SpaRoot)dist\**; $(SpaRoot)dist-server\**" /&amp;gt;
      &amp;lt;DistFiles Include="$(SpaRoot)node_modules\**" Condition="'$(BuildServerSideRenderer)' == 'true'" /&amp;gt;
      &amp;lt;ResolvedFileToPublish Include="@(DistFiles-&amp;gt;'%(FullPath)')" Exclude="@(ResolvedFileToPublish)"&amp;gt;
        &amp;lt;RelativePath&amp;gt;%(DistFiles.Identity)&amp;lt;/RelativePath&amp;gt;
        &amp;lt;CopyToPublishDirectory&amp;gt;PreserveNewest&amp;lt;/CopyToPublishDirectory&amp;gt;
        &amp;lt;ExcludeFromSingleFile&amp;gt;true&amp;lt;/ExcludeFromSingleFile&amp;gt;
      &amp;lt;/ResolvedFileToPublish&amp;gt;
    &amp;lt;/ItemGroup&amp;gt;
  &amp;lt;/Target&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;strong&gt;Target &lt;/strong&gt;specifies that it should consider something before it computes the files to publish (so before it looks at &lt;strong&gt;wwwroot &lt;/strong&gt;for the files to include). The two ‘&lt;strong&gt;Exec&lt;/strong&gt;’ lines are just a way to run the install and build steps in the &lt;strong&gt;ClientApp&lt;/strong&gt; directory. This is only executed during a publish, so it won’t impact your development cycle.&lt;/p&gt;

&lt;p&gt;The big drawback is more about Visual Studio than about ASP.NET Core. Because the &lt;strong&gt;project.json&lt;/strong&gt; is in a subdirectory (not in the root of the ASP.NET Core project), you can’t get the Task Runner Explorer to find the build. This means you’ll have to run it separately. If you’re using Visual Studio Code, Rider, or other IDE, you might already be used to opening console/terminal windows and doing the build yourself so this might not be much of a hardship.&lt;/p&gt;

&lt;p&gt;The other limitation is related to this one, more than one &lt;strong&gt;package.json&lt;/strong&gt; to manage. This is the one that hurts me the most. Most of my ASP.NET Core projects already use NPM to manage other dependencies (both dev and production dependencies). Having to manage two or more &lt;strong&gt;package.json&lt;/strong&gt; files makes me a little frustrated. That’s why I usually resolve to use the last of the options — fully integrate the SPA into the ASP.NET Core project.&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;Add pages, images, styles, modules&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;The &lt;em&gt;ClientApp&lt;/em&gt; directory contains a standard Angular CLI app. See the official &lt;a href="https://github.com/angular/angular-cli/wiki" rel="noopener noreferrer"&gt;Angular documentation&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;There are slight differences between the Angular app created by this template and the one created by Angular CLI itself (via &lt;code&gt;ng new&lt;/code&gt;); however, the app's capabilities are unchanged. The app created by the template contains a &lt;a href="https://getbootstrap.com/" rel="noopener noreferrer"&gt;Bootstrap&lt;/a&gt;-based layout and a basic routing example.&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;Run the app&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;If you have the &lt;code&gt;ng&lt;/code&gt; tool installed globally, you can run any of its commands. For example, you can run &lt;code&gt;ng lint&lt;/code&gt;, &lt;code&gt;ng test&lt;/code&gt;, or any of the other &lt;a href="https://github.com/angular/angular-cli/wiki#additional-commands" rel="noopener noreferrer"&gt;Angular CLI commands&lt;/a&gt;. There's no need to run &lt;code&gt;ng serve&lt;/code&gt; though, because your ASP.NET Core app deals with serving both server-side and client-side parts of your app. Internally, it uses &lt;code&gt;ng serve&lt;/code&gt; in development.&lt;/p&gt;

&lt;p&gt;If you don't have the &lt;code&gt;ng&lt;/code&gt; tool installed, run &lt;code&gt;npm run ng&lt;/code&gt; instead. For example, you can run &lt;code&gt;npm run ng lint&lt;/code&gt; or &lt;code&gt;npm run ng test&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In a command prompt, switch to the &lt;em&gt;ClientApp&lt;/em&gt; subdirectory:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ClientApp &amp;amp;&amp;amp; npm start&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Use &lt;code&gt;npm start&lt;/code&gt; to launch the Angular CLI development server, not &lt;code&gt;ng serve&lt;/code&gt;, so that the configuration in &lt;em&gt;package.json&lt;/em&gt; is respected. To pass additional parameters to the Angular CLI server, add them to the relevant &lt;code&gt;scripts&lt;/code&gt; line in your &lt;em&gt;package.json&lt;/em&gt; file.&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;Publish and deploy&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;In development, the app runs in a mode optimized for developer convenience. For example, JavaScript bundles include source maps (so that when debugging, you can see your original TypeScript code). The app watches for TypeScript, HTML, and CSS file changes on disk and automatically recompiles and reloads when it sees those files change.&lt;/p&gt;

&lt;p&gt;In production, serve a version of your app that's optimized for performance. This is configured to happen automatically. When you publish, the build configuration emits a minified, ahead-of-time (AoT) compiled build of your client-side code. Unlike the development build, the production build doesn't require Node.js to be installed on the server (unless you have enabled server-side rendering (SSR)).&lt;/p&gt;

&lt;p&gt;I will soon be publishing the code on GitHub and some extra steps to deploy it in the cloud ...&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>angular</category>
      <category>aspnetcore</category>
      <category>csharp</category>
    </item>
    <item>
      <title>How to develop a plugin for NopCommerce</title>
      <dc:creator>Diógenes Polanco</dc:creator>
      <pubDate>Sat, 26 Oct 2019 01:33:22 +0000</pubDate>
      <link>https://forem.com/diogenespolanco/how-to-develop-a-plugin-for-nopcommerce-46ho</link>
      <guid>https://forem.com/diogenespolanco/how-to-develop-a-plugin-for-nopcommerce-46ho</guid>
      <description>&lt;p&gt;The add-ons are specialized modules which maximize the functionality of nopcommerce such as payment processors, shipping provider, etc.&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;Before launching the code, it is necessary to know the following of nopcommerce:&lt;/strong&gt;&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Architecture of nopCommerce&lt;/li&gt;
&lt;li&gt;Types of plugin  &lt;/li&gt;
&lt;li&gt;Register new routes&lt;/li&gt;
&lt;li&gt;The plugin structure, required files, and locations&lt;/li&gt;
&lt;li&gt;Understanding Layout / Design&lt;/li&gt;
&lt;li&gt;Handling "Install" and "Uninstall" methods&lt;/li&gt;
&lt;li&gt;Handling requests. Controllers, models and views&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Architecture of nopCommerce&lt;/h4&gt;

&lt;p&gt;It is an open source e-commerce, so you can download from &lt;a href="https://github.com/nopSolutions/nopCommerce" rel="noopener noreferrer"&gt;github &lt;/a&gt;without any inconvenience and even collaborate. Projects and folders are listed in the order in which they appear in Visual Studio. To build a plugin my recommendation is not to change the source code of the libraries of the solution framework.&lt;/p&gt;

&lt;h4 id="librariesnopcore"&gt;&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Libraries/Nop.Core" rel="noopener noreferrer"&gt;\Libraries\Nop.Core&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;The Nop.Core project contains a set of core classes for nopCommerce, such as caching, events, helpers, and business objects (for example, Order and Customer entities).&lt;/p&gt;

&lt;h4 id="librariesnopdata"&gt;&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Libraries/Nop.Data" rel="noopener noreferrer"&gt;\Libraries\Nop.Data&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;The Nop.Data project contains a set of classes and functions for reading from and writing to a database or other data store. It helps separate data-access logic from your business objects.  &lt;/p&gt;

&lt;h4 id="librariesnopservices"&gt;&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Libraries/Nop.Services" rel="noopener noreferrer"&gt;\Libraries\Nop.Services&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;This project contains a set of core services, business logic, validations or calculations related with the data, if needed. Some people call it Business Access Layer (BAL).&lt;/p&gt;

&lt;h4 id="projects-into-plugins-solution-folder"&gt;
&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Plugins" rel="noopener noreferrer"&gt;Projects into \&lt;/a&gt;&lt;strong&gt;&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Plugins" rel="noopener noreferrer"&gt;Plugins\&lt;/a&gt;&lt;/strong&gt;&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Plugins" rel="noopener noreferrer"&gt; solution folder&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;\Plugins&lt;/code&gt; is a Visual Studio solution folder that contains plugin projects. Physically it's located in the root of your solution. But plugins DLLs are automatically copied in &lt;code&gt;\Presentation\Nop.Web\Plugins\&lt;/code&gt; directory which is used for already deployed plugins because the build output paths of all plugins are set to &lt;code&gt;..\..\Presentation\Nop.Web\Plugins\{Group}.{Name}\&lt;/code&gt;. This allows plugins to contain some external files, such as static content (CSS or JS files) without having to copy files between projects to be able to run the project.&lt;/p&gt;

&lt;h4 id="presentationnopweb"&gt;&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Presentation/Nop.Web" rel="noopener noreferrer"&gt;\Presentation\Nop.Web&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;Nop.Web&lt;/code&gt; is an MVC web application project, a presentation layer for public store which also contains administration panel included as an area. If you haven't used &lt;code&gt;ASP.NET&lt;/code&gt; before, please find more info &lt;a href="http://www.asp.net/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. This is the application that you actually run. It is the startup project of the application.&lt;/p&gt;

&lt;h4 id="presentationnopwebframework"&gt;&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Presentation/Nop.Web.Framework" rel="noopener noreferrer"&gt;\Presentation\Nop.Web.Framework&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;Nop.Web.Framework is a class library project containing some common presentation things for &lt;code&gt;Nop.Web&lt;/code&gt; project.&lt;/p&gt;

&lt;h4 id="testnopcoretests"&gt;&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Tests/Nop.Core.Tests" rel="noopener noreferrer"&gt;\Test\Nop.Core.Tests&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;Nop.Core.Tests is the test project for the Nop.Core project.&lt;/p&gt;

&lt;h4 id="testnopservicestests"&gt;&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Tests/Nop.Services.Tests" rel="noopener noreferrer"&gt;\Test\Nop.Services.Tests&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;Nop.Services.Tests is the test project for the Nop.Services project.&lt;/p&gt;

&lt;h4 id="testnoptests"&gt;&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Tests/Nop.Tests" rel="noopener noreferrer"&gt;\Test\Nop.Tests&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;Nop.Tests is a class library project containing some common test classes and helpers for other test projects. It does not have any test.&lt;/p&gt;

&lt;h4 id="testnopwebmvctests"&gt;&lt;a href="https://github.com/nopSolutions/nopCommerce/tree/develop/src/Tests/Nop.Web.MVC.Tests" rel="noopener noreferrer"&gt;\Test\Nop.Web.MVC.Tests&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;Nop.Web.MVC.Tests is the test project for the presentation layer projects.&lt;/p&gt;

&lt;h4&gt;Types of plugin  &lt;/h4&gt;

&lt;p&gt;The type of its complement is defined by the interface that implements the main complement class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discount Rules (IDiscountRequirementRule)&lt;/strong&gt;For defining requirements that must be met my an order for a discount to be applied&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exchange Rate Prodider (IExchangeRateProvider)&lt;/strong&gt;For getting the exchange rates for currencies&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;External Authentication Method (IExternalAuthenticationMethod)&lt;/strong&gt;For adding new external authentication methods (e.g. “Login with Facebook”)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Widgets (IWidgetsPlugin)&lt;/strong&gt;For when your plugin doesn’t fit any of the other types&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Payment Method (IPaymentMethod)&lt;/strong&gt;For example, Paypal or Worldpay&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shipping Rate Computation Method (IShippingRateComputationMethod)&lt;/strong&gt;For calculating shipping rates (many plugins of this time call web services provided by couriers to retrieve rates)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pickup points&lt;/strong&gt; is an option providing customers the flexibility to select a point where they can receive parcels.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tax Provider (ITaxProvider)&lt;/strong&gt;For calculating tax rates&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Widget (IWidgetPlugin)&lt;/strong&gt;Widgets are blocks of content shown throughout the site. The default theme contains many widget “areas”.&lt;br&gt;You can assign your new widget to one of these areas, and wherever the area is referenced in the theme, your widget will appear.&lt;/p&gt;

&lt;h4&gt;Register new routes&lt;/h4&gt;

&lt;p&gt;ASP.NET Core routing is responsible for assigning incoming browser requests via a get to the MVC controller. NopCommerce has an IRouteProvider interface that is used for route registration during application startup. All main routes are registered in the RouteProvider class located in the Nop.Web project.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;The plugin structure, required files, and locations&lt;/h4&gt;

&lt;p&gt;First thing you need to do is to create a new "Class Library" project in the solution. It's a good practice to place all plugins into &lt;code&gt;\Plugins&lt;/code&gt; directory in the root of your solution (do not mix up with \Plugins subdirectory located in &lt;code&gt;\Nop.Web&lt;/code&gt; directory which is used for already deployed plugins). It's a good practice to place all plugins into "Plugins" solution folder (you can find more information about solution folders &lt;a href="http://msdn.microsoft.com/en-us/library/sx2027y2.aspx" rel="noopener noreferrer"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;A recommended name for a plugin project is "Nop.Plugin.{Group}.{Name}". {Group} is your plugin group (for example, "Payment" or "Shipping"). {Name} is your plugin name (for example, "PayPalStandard"). For example, PayPal Standard payment plugin has the following name: Nop.Plugin.Payments.PayPalStandard. But please note that it's not a requirement. And you can choose any name for a plugin. For example, "MyCustomPlugin".&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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-6.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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-6.png" alt="" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the plugin project is created you have to open its &lt;code&gt;.csproj&lt;/code&gt; file in any text editor and replace its content with the following one:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2Fnop-plugin-1.jpg" 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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2Fnop-plugin-1.jpg" alt="" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is creating a &lt;strong&gt; plugin.json&lt;/strong&gt; file required for each plugin. This file contains meta information describing your plugin. Just copy this file from any other existing plugin and modify it for your needs. For example, PayPal Standard payment plugin has the following &lt;strong&gt;plugin.json&lt;/strong&gt; file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Add a class &lt;strong&gt;MyCustomPlugin.cs&lt;/strong&gt; and use the following code: &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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-1-1024x440.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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-1-1024x440.png" alt="" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;Handling "Install" and "Uninstall" methods&lt;/h4&gt;

&lt;p&gt;Some plugins can require additional logic during plugin installation. For example, a plugin can insert new locale resources. So open your IPlugin implementation (in most case it'll be derived from BasePlugin class) and override the following methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install. This method will be invoked during plugin installation. You can initialize any settings here, insert new locale resources, or create some new database tables (if required).&lt;/li&gt;
&lt;li&gt;Uninstall. This method will be invoked during plugin uninstallation.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;Understanding Layout / Design&lt;/h4&gt;

&lt;p&gt;What are layouts? Every web developer/designer wants to maintain a consistent look and feel across all of the pages within the website. Back in the days, the concept of "Master Pages" was introduced in ASP.NET 2.0 which helps in maintaining a consistent look of the website by mapping it with .aspx pages.&lt;/p&gt;

&lt;p&gt;Razor also supports this similar concept with a feature called "Layouts". Basically, it allows you to define a common site template and then inherit its look and feel across all the views/pages on your website.&lt;/p&gt;

&lt;p&gt;In nopCommerce, there are 2 different kinds of layouts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_ColumnsOne.cshtml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_ColumnsTwo.cshtml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these 2 layouts are inherited from one main layout called: &lt;code&gt;_Root.cshtml&lt;/code&gt;. The &lt;code&gt;_Root.cshtml&lt;/code&gt; itself is inherited from &lt;code&gt;_Root.Head.cshtml&lt;/code&gt;. &lt;code&gt;_Root.Head.cshtml&lt;/code&gt; is the file you need to look into if you are linked css stylesheet and jquery files (you can add/link more &lt;code&gt;.css&lt;/code&gt; and &lt;code&gt;.js&lt;/code&gt; files here). The location of all these layouts in nopCommerce is as follows: nopCommerce root &lt;code&gt;directory/Views/Shared/...&lt;/code&gt;. If you are using source code version then: &lt;code&gt;\Presentation\Nop.Web\Views\Shared\...&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2Froot-layout.jpg" alt="" width="800" height="400"&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;h4&gt;Handling requests. Controllers, models and views&lt;/h4&gt;

&lt;p&gt;Add a class MyCustomPluginController.cs (in folder “Controllers” within your plugin) and use the following code:   &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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-2.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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-2.png" alt="" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Add a &lt;strong&gt;Configure.cshtml (View)&lt;/strong&gt; – In this case we are creating a blank plugin.&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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-3-1024x596.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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-3-1024x596.png" alt="" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we will add the menu item by adding this code in “MyCustomPlugin.cs”:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We can see our menu item here:&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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-4.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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-4.png" alt="" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s create a “WidgetsMyCustomPluginViewComponent” file inside the “Components” folder of your custom plugin and simply paste the default home view (PublicInfo.cshtml) from Nop.Web like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Make sure the output directory (in properties) for your home view (PublicInfo.cshtml) is defined as “Copy if newer”. Rebuild your plugin and try going to your public store (since your plugin is already installed)&lt;/p&gt;

&lt;p&gt;We should see the plugin view overriding the default home view like this:&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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-5-1024x727.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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FCapture-5-1024x727.png" alt="" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I let you share the source code &lt;a href="https://github.com/DiogenesPolanco/nopCommerce/tree/develop/src/Plugins/Nop.Plugin.Widgets.MyCustomPlugin" rel="noopener noreferrer"&gt;link on GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>aspnetcore</category>
      <category>nopcommerce</category>
    </item>
    <item>
      <title>Creating a NopCommerce plugin with .Net Core and Angular - Part I</title>
      <dc:creator>Diógenes Polanco</dc:creator>
      <pubDate>Fri, 18 Oct 2019 02:55:14 +0000</pubDate>
      <link>https://forem.com/diogenespolanco/creating-a-nopcommerce-plugin-with-net-core-and-angular-part-i-b8h</link>
      <guid>https://forem.com/diogenespolanco/creating-a-nopcommerce-plugin-with-net-core-and-angular-part-i-b8h</guid>
      <description>&lt;h4&gt;&lt;strong&gt;Objective:&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt; We will create a plugin for nopcommerce taking advantage of the power of aspnet core and the angular fluids for the frontend. We will create a plugin that will import the products from an external service.&lt;/p&gt;


















&lt;h4 id="how-to-write-a-plugin-for-nopcommerce-390-and-previous-versions"&gt;&lt;strong&gt;You have to understand how to:&lt;/strong&gt;&lt;/h4&gt;











&lt;p&gt; &lt;strong&gt;Create a plugin for nopCommerce?&lt;/strong&gt;&lt;/p&gt;





&lt;p&gt;The add-ons are specialized modules which maximize the functionality of nopcommerce such as payment processors, shipping provider, etc. Currently you can take advantage of their official documentation by entering this &lt;a href="https://dev.to/diogenespolanco/how-to-develop-a-plugin-for-nopcommerce-46ho"&gt;&lt;strong&gt;link&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;





&lt;p&gt;&lt;strong&gt;Develop a webapp with AspNet Core?&lt;/strong&gt;&lt;/p&gt;





&lt;p&gt;The applications with asp net core are very easy to develop these days and when I say easy it is because I remember how it was a bit complex to develop with aspnet in the previous versions. but in another article I will talk about the differences between .Net vs .Net Core. So for the purposes you must also have basic knowledge of aspnet core and can start with this&lt;strong&gt; &lt;/strong&gt;&lt;a href="https://docs.microsoft.com/en-us/aspnet/core/getting-started/?view=aspnetcore-3.0&amp;amp;tabs=linux" rel="noopener noreferrer"&gt;&lt;strong&gt;link&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;





&lt;h4&gt;&lt;strong&gt;Project Architecture&lt;/strong&gt;&lt;/h4&gt;





&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FScreenshot-from-2019-10-17-20.21.40.jpeg" alt="" width="800" height="400"&gt; 

&lt;p&gt;  The product importer plugin is responsible for extracting the products from the ODataProducts service and rules configured in the plugin to upload them to the nopcommerce catalog.    &lt;/p&gt;







&lt;h4&gt;&lt;strong&gt;Source code&lt;/strong&gt;&lt;/h4&gt;





&lt;p&gt;This plugin only has one component that is responsible for importing the products of the external service so we will only have to develop a class that has the functionality to synchronize the products of the service against the nopcommerce catalog for that we will use C#.&lt;/p&gt;





&lt;p&gt;You have to create a console test project in which we will do the service.&lt;/p&gt;





&lt;p&gt;Let's execute the following commands:&lt;/p&gt;





&lt;pre&gt;&lt;code&gt;~/ProductsImport$ dotnet  new console &lt;/code&gt;&lt;/pre&gt;





&lt;pre&gt;&lt;code&gt;~/ProductsImport$ dotnet add package Newtonsoft.Json&lt;/code&gt;&lt;/pre&gt;





&lt;p&gt;We will create the following classes:&lt;/p&gt;




&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;&lt;strong&gt;The result of the console:&lt;/strong&gt;&lt;/h4&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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FScreenshot-from-2019-10-17-22.12.56.jpeg" 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%2Fdiogenespolanco.com%2Fwp-content%2Fuploads%2F2019%2F10%2FScreenshot-from-2019-10-17-22.12.56.jpeg" alt="" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nopcommerce</category>
      <category>angular</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
