<?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: Jaydeep Patil</title>
    <description>The latest articles on DEV Community by Jaydeep Patil (@jaydeep007).</description>
    <link>https://dev.to/jaydeep007</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%2F931960%2F2f229f57-40d7-45f4-b9c1-e879b98532ee.png</url>
      <title>DEV Community: Jaydeep Patil</title>
      <link>https://dev.to/jaydeep007</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jaydeep007"/>
    <language>en</language>
    <item>
      <title>Host and Publish .NET Core 6 Web API Application on IIS Server</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Tue, 15 Aug 2023 05:28:21 +0000</pubDate>
      <link>https://dev.to/jaydeep007/host-and-publish-net-core-6-web-api-application-on-iis-server-232p</link>
      <guid>https://dev.to/jaydeep007/host-and-publish-net-core-6-web-api-application-on-iis-server-232p</guid>
      <description>&lt;p&gt;We are going to discuss how to host and publish the.NET Core 6 Web API on IIS Server&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Basically, Internet Information Service (IIS) is the flexible and general-purpose web server provided by Microsoft that will be run on Windows and used to serve requested files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Required Tools
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;IIS Manager&lt;/li&gt;
&lt;li&gt;.NET Core SDK 6&lt;/li&gt;
&lt;li&gt;Visual Studio 2022&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s start,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new .NET Core Web API Project&lt;/p&gt;

&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%2Faqacje1nunnii63185uy.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%2Faqacje1nunnii63185uy.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Configure your new project&lt;/p&gt;

&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%2Ferhgwzqv3jqgdysor1h2.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%2Ferhgwzqv3jqgdysor1h2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Provide additional information like .NET Framework Version, Open API, and HTTPS&lt;/p&gt;

&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%2Ft7xme3znxvqq8knptvl3.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%2Ft7xme3znxvqq8knptvl3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4)&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&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%2Fff2zcy94vj2jei87rouw.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%2Fff2zcy94vj2jei87rouw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the Product Controller, add one endpoint inside that class and also check other files which are created by default&lt;/p&gt;

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

using Microsoft.AspNetCore.Mvc;
namespace WebAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {
        [HttpGet]
        [Route("list")]
        public IDictionary&amp;lt;int, string&amp;gt; Get()
        {
            IDictionary&amp;lt;int, string&amp;gt; list = new Dictionary&amp;lt;int, string&amp;gt;();
            list.Add(1, "IPhone");
            list.Add(2, "Laptop");
            list.Add(3, "Samsung TV");
            return list;
        }
    }
}


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Program.cs file&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

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

var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment() || app.Environment.IsProduction())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();


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

&lt;/div&gt;

&lt;p&gt;Here also, you can see that we configure the HTTP request pipeline for both the development and Production environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;WebAPI.csproj file&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

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

&amp;lt;Project Sdk="Microsoft.NET.Sdk.Web"&amp;gt;
  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;TargetFramework&amp;gt;net6.0&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;Nullable&amp;gt;enable&amp;lt;/Nullable&amp;gt;
    &amp;lt;ImplicitUsings&amp;gt;enable&amp;lt;/ImplicitUsings&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;
  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;
&amp;lt;/Project&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;launchSetting.json file&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

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

{
  "$schema": "https://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:11254",
      "sslPort": 44315
    }
  },
  "profiles": {
    "WebAPI": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "launchUrl": "swagger",
      "applicationUrl": "https://localhost:7047;http://localhost:5047",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "swagger",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 6)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run your application and hit the API endpoint using Swagger UI&lt;/p&gt;

&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%2Fn7xvzxrtaa0viqrraswm.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%2Fn7xvzxrtaa0viqrraswm.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check if all IIS Services are running on your system properly or not. If not, then open the control panel, go to program and features, and click on Turn Windows Feature on or off&lt;/p&gt;

&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%2Fp9av025536ljisv5h7ms.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%2Fp9av025536ljisv5h7ms.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Fioccbaxugeqskgpqhyug.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%2Fioccbaxugeqskgpqhyug.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apply the changes as I showed you in the above image, click on Apply, and then restart your computer&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After restarting your computer, you will see IIS Manager in the search box. Open it.&lt;/p&gt;

&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%2F9zz7gpa0m2n20vhh2mpz.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%2F9zz7gpa0m2n20vhh2mpz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, check your running IIS using localhost in the browser&lt;/p&gt;

&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%2Fu27rf482kw2lbn4ypx94.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%2Fu27rf482kw2lbn4ypx94.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install ASP.NET Core 6.9 Runtime — Windows Hosting Bundle Installer&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-aspnetcore-6.0.6-windows-hosting-bundle-installer" rel="noopener noreferrer"&gt;Windows hosting bundle installer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, we are going to publish our application for that, right-click on Web API Project and click on Publish&lt;/p&gt;

&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%2Fniunalz00bsvqh5fvxhh.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%2Fniunalz00bsvqh5fvxhh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Fry1nt9m6xbjpphuanqh7.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%2Fry1nt9m6xbjpphuanqh7.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you see it will take the default path, so change that path to c:\inetpub\wwwroot\publish after creating publish folder over there &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 11)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here you can see all the configurations related to publishing like path and some environmental variables and later on click on Publish&lt;/p&gt;

&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%2Ftytv7z8cakf9xbs46db4.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%2Ftytv7z8cakf9xbs46db4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 12)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open IIS Manager and create a new Web Application after right click on the sites&lt;/p&gt;

&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%2Feqglel4le56dg0xyikcv.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%2Feqglel4le56dg0xyikcv.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 13)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Click on Web API and on the right side you can see the browse option so click on that and open the application inside the browser&lt;/p&gt;

&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%2Fifk0637rkqitknx4g01u.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%2Fifk0637rkqitknx4g01u.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 14)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the browser when you hit the Web API endpoint using Swagger then will see the following list of products as an output&lt;/p&gt;

&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%2Fkebm2m844spyhlclsga6.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%2Fkebm2m844spyhlclsga6.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we discussed .NET Core 6 Web API hosting and publish related things using IIS and things related to that step-by-step. I hope you understand all things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Coding!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>dotnetcore</category>
      <category>iis</category>
      <category>deployment</category>
    </item>
    <item>
      <title>JWT Token Authentication in Angular 14 and the .NET Core 6 Web API</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Sun, 06 Aug 2023 05:31:08 +0000</pubDate>
      <link>https://dev.to/jaydeep007/jwt-token-authentication-in-angular-14-and-the-net-core-6-web-api-1pfg</link>
      <guid>https://dev.to/jaydeep007/jwt-token-authentication-in-angular-14-and-the-net-core-6-web-api-1pfg</guid>
      <description>&lt;p&gt;We are going to discuss JWT Authentication in Angular 14 step-by-step.&lt;/p&gt;

&lt;p&gt;If you want to learn the basics and details of the JWT Token, then check out the following URL.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javascript.plainenglish.io/introduction-and-detail-about-the-jwt-authentication-and-authorization-5a812e6d154c"&gt;A Detailed Introduction to JWT Authentication and Authorization&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over there, I have explained the basics and details of JWT Authentication and Authorization.&lt;/p&gt;

&lt;p&gt;Also, I recommend you read the following article before starting this article, I explained how to set up a backend server application using.NET Core 6.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javascript.plainenglish.io/jwt-token-authentication-using-the-net-core-6-web-api-24e585ecc24a"&gt;​JWT Token Authentication using the .NET Core 6 Web API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this section, we are going to discuss the following things step-by-step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Create Angular Application&lt;/li&gt;
&lt;li&gt;Add Bootstrap and Toaster Modules&lt;/li&gt;
&lt;li&gt;Auth Guards&lt;/li&gt;
&lt;li&gt;Angular Service&lt;/li&gt;
&lt;li&gt;Create Angular Components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s start above things one by one&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON Web Token is the open standard (RFC 7519) self-contained way that will be used to transmit the data securely over the different environments as a JSON Object.&lt;/li&gt;
&lt;li&gt;RFC (Request for Comment) is the shortened form of Remote Function Call and Formal Document from the Internet Engineering Task Force. RFC 7519: JSON Web Token (JWT) May 2015 Copyright Notice Copyright: 2015 IETF Trust and the persons identified as the document authors All rights reserved.&lt;/li&gt;
&lt;li&gt;JWT is the trusted way of authentication because it is digitally signed and secret using the HMAC algorithm, or sometimes using a public/private key using RSA.&lt;/li&gt;
&lt;li&gt;Basically, HMAC stands for Hashed-based Message Authentication Code, it uses some great cryptographic hashing techniques that provide us with great security.&lt;/li&gt;
&lt;li&gt;Also, the JWT is part of great Authentication and Authorization Frameworks like OAuth and OpenID, which will provide a great mechanism to transfer data securely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create Angular Application&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create an Angular Application using the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ng new WebAPP&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We use Bootstrap in this application. So, use the following command to install Bootstrap:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install bootstrap&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, add the bootstrap script inside the angular.json file inside the scripts and styles section&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"styles": [
             "src/styles.css",
             "./node_modules/bootstrap/dist/css/bootstrap.min.css"
           ],
           "scripts": [
             "./node_modules/bootstrap/dist/js/bootstrap.min.js"
           ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install Toaster module for pop-up and notification&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install ngx-toastr –save&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, add the toaster in the styles section inside the angular.json file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"styles": [
             "src/styles.css",
             "node_modules/ngx-toastr/toastr.css",
             "./node_modules/bootstrap/dist/css/bootstrap.min.css"
           ],
           "scripts": [
             "./node_modules/bootstrap/dist/js/bootstrap.min.js"
           ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Application structure&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IxCS0ckY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fwlenv7adury9ku7t65z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IxCS0ckY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fwlenv7adury9ku7t65z.png" alt="Image description" width="242" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create config folder inside assets and create config.json file inside that as shown below and put backend application API URL inside that&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "apiServer": {
      "url": "https://localhost:7299",
      "version": "v1"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create Auth Guard inside the guard’s folder&lt;br&gt;
So, here you can see we take the JWT token from the local storage and later on check if the token is expired or not, If the token is expired then it will redirect to login and return false.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the App Component files and add the following code inside that&lt;/p&gt;

&lt;p&gt;app.component.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'ProductWebAPP';
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;app.component.html&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;router-outlet&amp;gt;&amp;lt;/router-outlet&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 8:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a Model folder inside the app directory and create a Product class inside that&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class Products {
    productId: any;
    productName?: string;
    productCost?: number;
    productDescription?: string;
    productStock?: number;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 9:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create Homepage component&lt;/p&gt;

&lt;p&gt;homepage.component.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { JwtHelperService } from '@auth0/angular-jwt';
@Component({
  selector: 'app-homepage',
  templateUrl: './homepage.component.html',
  styleUrls: ['./homepage.component.css']
})
export class HomepageComponent  {
  constructor(private jwtHelper: JwtHelperService, private router: Router) {
  }
  isUserAuthenticated() {
    const token = localStorage.getItem("jwt");
    if (token &amp;amp;&amp;amp; !this.jwtHelper.isTokenExpired(token)) {
      return true;
    }
    else {
      return false;
    }
  }
  public logOut = () =&amp;gt; {
    localStorage.removeItem("jwt");
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;homepage.component.html&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;nav class="navbar navbar-expand-lg navbar navbar-dark bg-dark"&amp;gt;
  &amp;lt;a class="navbar-brand" href="#"&amp;gt;Product Application&amp;lt;/a&amp;gt;
  &amp;lt;button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation"&amp;gt;
    &amp;lt;span class="navbar-toggler-icon"&amp;gt;&amp;lt;/span&amp;gt;
  &amp;lt;/button&amp;gt;
  &amp;lt;div class="collapse navbar-collapse" id="navbarText"&amp;gt;
    &amp;lt;ul class="navbar-nav mr-auto"&amp;gt;
      &amp;lt;li *ngIf="isUserAuthenticated()" class="nav-item"&amp;gt;
        &amp;lt;a class="nav-link" routerLink="/product"&amp;gt;Products&amp;lt;/a&amp;gt;
      &amp;lt;/li&amp;gt;
      &amp;lt;li *ngIf="isUserAuthenticated()" class="nav-item"&amp;gt;
        &amp;lt;a class="nav-link" (click)="logOut()"&amp;gt;Logout&amp;lt;/a&amp;gt;
      &amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/nav&amp;gt;
&amp;lt;div *ngIf="!isUserAuthenticated()"&amp;gt;
  &amp;lt;login&amp;gt;&amp;lt;/login&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div *ngIf="isUserAuthenticated()" style="color:green;"&amp;gt;
  &amp;lt;h2&amp;gt;
    Welcome to the Product Application
  &amp;lt;/h2&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 10:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create Login Component&lt;/p&gt;

&lt;p&gt;login.component.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Component } from '@angular/core';
import { Router } from "@angular/router";
import { NgForm } from '@angular/forms';
import configurl from '../../assets/config/config.json';
import { JwtHelperService } from '@auth0/angular-jwt';
import { ToastrService } from 'ngx-toastr';
@Component({
  selector: 'login',
  templateUrl: './login.component.html'
})
export class LoginComponent {
  invalidLogin?: boolean;
  url = configurl.apiServer.url + '/api/authentication/';
  constructor(private router: Router, private http: HttpClient,private jwtHelper : JwtHelperService,
    private toastr: ToastrService) { }
  public login = (form: NgForm) =&amp;gt; {
    const credentials = JSON.stringify(form.value);
    this.http.post(this.url +"login", credentials, {
      headers: new HttpHeaders({
        "Content-Type": "application/json"
      })
    }).subscribe(response =&amp;gt; {
      const token = (&amp;lt;any&amp;gt;response).token;
      localStorage.setItem("jwt", token);
      this.invalidLogin = false;
      this.toastr.success("Logged In successfully");
      this.router.navigate(["/product"]);
    }, err =&amp;gt; {
      this.invalidLogin = true;
    });
  }
  isUserAuthenticated() {
    const token = localStorage.getItem("jwt");
    if (token &amp;amp;&amp;amp; !this.jwtHelper.isTokenExpired(token)) {
      return true;
    }
    else {
      return false;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;login.component.html&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form class="form-signin" #loginForm="ngForm" (ngSubmit)="login(loginForm)"&amp;gt;
    &amp;lt;div class="container-fluid"&amp;gt;
        &amp;lt;h2 class="form-signin-heading"&amp;gt;Login&amp;lt;/h2&amp;gt;
        &amp;lt;div *ngIf="invalidLogin" class="alert alert-danger"&amp;gt;Invalid username or password.&amp;lt;/div&amp;gt;
        &amp;lt;br/&amp;gt;
        &amp;lt;label for="username" class="sr-only"&amp;gt;Email address&amp;lt;/label&amp;gt;
        &amp;lt;input type="email" id="username" name="username" ngModel class="form-control" placeholder="User Name" required autofocus&amp;gt;
        &amp;lt;br/&amp;gt;
        &amp;lt;label for="password" class="sr-only"&amp;gt;Password&amp;lt;/label&amp;gt;
        &amp;lt;input type="password" id="password" name="password" ngModel class="form-control" placeholder="Password" required&amp;gt;
        &amp;lt;br/&amp;gt;
        &amp;lt;button class="btn btn-lg btn-primary btn-block" type="submit"&amp;gt;Login&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 11:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create Products Component&lt;/p&gt;

&lt;p&gt;products.component.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { Observable } from 'rxjs';
import { ProductsService } from '../products/products.service';
import { Products } from '../Models/Products';
import { Router } from '@angular/router';
import { JwtHelperService } from '@auth0/angular-jwt';
import { ToastrService } from 'ngx-toastr';
@Component({
  selector: 'app-product',
  templateUrl: './products.component.html',
  styleUrls: ['./products.component.css']
})
export class ProductsComponent implements OnInit {
  ProductList?: Observable&amp;lt;Products[]&amp;gt;;
  ProductList1?: Observable&amp;lt;Products[]&amp;gt;;
  productForm: any;
  massage = "";
  prodCategory = "";
  productId = 0;
  constructor(private formbulider: FormBuilder,
     private productService: ProductsService,private router: Router,
     private jwtHelper : JwtHelperService,private toastr: ToastrService) { }
  ngOnInit() {
    this.prodCategory = "0";
    this.productForm = this.formbulider.group({
      productName: ['', [Validators.required]],
      productCost: ['', [Validators.required]],
      productDescription: ['', [Validators.required]],
      productStock: ['', [Validators.required]]
    });
    this.getProductList();
  }
  getProductList() {
    this.ProductList1 = this.productService.getProductList();
    this.ProductList = this.ProductList1;
  }
  PostProduct(product: Products) {
    const product_Master = this.productForm.value;
    this.productService.postProductData(product_Master).subscribe(
      () =&amp;gt; {
        this.getProductList();
        this.productForm.reset();
        this.toastr.success('Data Saved Successfully');
      }
    );
  }
  ProductDetailsToEdit(id: string) {
    this.productService.getProductDetailsById(id).subscribe(productResult =&amp;gt; {
      this.productId = productResult.productId;
      this.productForm.controls['productName'].setValue(productResult.productName);
      this.productForm.controls['productCost'].setValue(productResult.productCost);
      this.productForm.controls['productDescription'].setValue(productResult.productDescription);
      this.productForm.controls['productStock'].setValue(productResult.productStock);
    });
  }
  UpdateProduct(product: Products) {
    product.productId = this.productId;
    const product_Master = this.productForm.value;
    this.productService.updateProduct(product_Master).subscribe(() =&amp;gt; {
      this.toastr.success('Data Updated Successfully');
      this.productForm.reset();
      this.getProductList();
    });
  }
  DeleteProduct(id: number) {
    if (confirm('Do you want to delete this product?')) {
      this.productService.deleteProductById(id).subscribe(() =&amp;gt; {
        this.toastr.success('Data Deleted Successfully');
        this.getProductList();
      });
    }
  }
  Clear(product: Products){
    this.productForm.reset();
  }
  public logOut = () =&amp;gt; {
    localStorage.removeItem("jwt");
    this.router.navigate(["/"]);
  }
  isUserAuthenticated() {
    const token = localStorage.getItem("jwt");
    if (token &amp;amp;&amp;amp; !this.jwtHelper.isTokenExpired(token)) {
      return true;
    }
    else {
      return false;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;products.component.html&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;nav class="navbar navbar-expand-lg navbar navbar-dark bg-dark"&amp;gt;
  &amp;lt;a class="navbar-brand" href="#"&amp;gt;Product Application&amp;lt;/a&amp;gt;
  &amp;lt;button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation"&amp;gt;
    &amp;lt;span class="navbar-toggler-icon"&amp;gt;&amp;lt;/span&amp;gt;
  &amp;lt;/button&amp;gt;
  &amp;lt;div class="collapse navbar-collapse" id="navbarText"&amp;gt;
    &amp;lt;ul class="navbar-nav mr-auto"&amp;gt;
      &amp;lt;li class="nav-item active"&amp;gt;
        &amp;lt;a class="nav-link" routerLink="/"&amp;gt;Home&amp;lt;/a&amp;gt;
      &amp;lt;/li&amp;gt;
      &amp;lt;li class="nav-item"&amp;gt;
        &amp;lt;a class="nav-link" (click)="logOut()"&amp;gt;Logout&amp;lt;/a&amp;gt;
      &amp;lt;/li&amp;gt;
      &amp;lt;li *ngIf="!isUserAuthenticated()" class="nav-item active"&amp;gt;
        &amp;lt;a class="nav-link" routerLink="/product"&amp;gt;Products&amp;lt;/a&amp;gt;
      &amp;lt;/li&amp;gt;
    &amp;lt;/ul&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/nav&amp;gt;
&amp;lt;form class="form-horizontal" [formGroup]="productForm"&amp;gt;
    &amp;lt;h1 style="text-align: center;"&amp;gt;Welcome to Angular 14 CRUD with .NET 6 Web API&amp;lt;/h1&amp;gt;
    &amp;lt;div&amp;gt;
    &amp;lt;div class="form-group"&amp;gt;
      &amp;lt;label class="control-label col-sm-2" for="pwd"&amp;gt;Product Name:&amp;lt;/label&amp;gt;
      &amp;lt;div class="col-sm-10"&amp;gt;
        &amp;lt;input type="text" class="form-control" id="txtProductName" formControlName="productName"
          placeholder="Name of Product"&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;br /&amp;gt;
    &amp;lt;div class="form-group"&amp;gt;
      &amp;lt;label class="control-label col-sm-2" for="pwd"&amp;gt;Product Description :&amp;lt;/label&amp;gt;
      &amp;lt;div class="col-sm-10"&amp;gt;
        &amp;lt;input type="text" class="form-control" id="txtProductDescription" formControlName="productDescription"
          placeholder="Product Description"&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;br /&amp;gt;
    &amp;lt;div class="form-group"&amp;gt;
      &amp;lt;label class="control-label col-sm-2" for="pwd"&amp;gt;Product Cost:&amp;lt;/label&amp;gt;
      &amp;lt;div class="col-sm-10"&amp;gt;
        &amp;lt;input type="text" class="form-control" id="txtProductCost" formControlName="productCost" placeholder="Cost of Product"&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;br /&amp;gt;
    &amp;lt;div class="form-group"&amp;gt;
      &amp;lt;label class="control-label col-sm-2" for="pwd"&amp;gt;Product Stock Available :&amp;lt;/label&amp;gt;
      &amp;lt;div class="col-sm-10"&amp;gt;
        &amp;lt;input type="text" class="form-control" id="txtStock" formControlName="productStock" placeholder="Stock Available"&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;br /&amp;gt;
     &amp;lt;div class="form-group"&amp;gt;
      &amp;lt;div class="container"&amp;gt;
        &amp;lt;div class="row"&amp;gt;
          &amp;lt;div class="col-sm"&amp;gt;
            &amp;lt;button type="submit" class="btn btn-primary" (click)="PostProduct(productForm.value)"&amp;gt;Submit&amp;lt;/button&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div class="col-sm"&amp;gt;
            &amp;lt;button type="submit" class="btn btn-primary" (click)="UpdateProduct(productForm.value)"&amp;gt;Update&amp;lt;/button&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div class="col-sm"&amp;gt;
            &amp;lt;button type="submit" class="btn btn-primary" (click)="Clear(productForm.value)"&amp;gt;Clear&amp;lt;/button&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;br /&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;div class="alert alert-success" style="text-align: center;"&amp;gt;&amp;lt;b&amp;gt;Product List&amp;lt;/b&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;div class="table-responsive" style="text-align: center;"&amp;gt;
        &amp;lt;table class="table table-striped"&amp;gt;
          &amp;lt;thead&amp;gt;
          &amp;lt;tr&amp;gt;
            &amp;lt;th scope="col"&amp;gt;#&amp;lt;/th&amp;gt;
            &amp;lt;th scope="col"&amp;gt;Product Name&amp;lt;/th&amp;gt;
            &amp;lt;th scope="col"&amp;gt;Description&amp;lt;/th&amp;gt;
            &amp;lt;th scope="col"&amp;gt;Cost&amp;lt;/th&amp;gt;
            &amp;lt;th scope="col"&amp;gt;Stock&amp;lt;/th&amp;gt;
            &amp;lt;th scope="col"&amp;gt;Action&amp;lt;/th&amp;gt;
          &amp;lt;/tr&amp;gt;
        &amp;lt;/thead&amp;gt;
        &amp;lt;tbody&amp;gt;
          &amp;lt;tr *ngFor="let prd of ProductList | async; index as i"&amp;gt;
            &amp;lt;th scope="row"&amp;gt;{{ i + 1 }}&amp;lt;/th&amp;gt;
            &amp;lt;td&amp;gt;{{prd.productName}}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;{{prd.productDescription}}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;{{prd.productCost}}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;{{prd.productStock}}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;&amp;lt;button type="button" class="btn1" matTooltip="Click Edit Button" (click)='ProductDetailsToEdit(prd.productId)'&amp;gt;Edit&amp;lt;/button&amp;gt;
              |
              &amp;lt;button type="button" class="btn1" matTooltip="Click Delete Button" (click)="DeleteProduct(prd.productId)"&amp;gt;Delete&amp;lt;/button&amp;gt;
            &amp;lt;/td&amp;gt;
          &amp;lt;/tr&amp;gt;
        &amp;lt;/tbody&amp;gt;
        &amp;lt;/table&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 12:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, create a Product Service to send all our requests and fetch the data from the backend application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Products } from '../Models/Products';
import configurl from '../../assets/config/config.json'
@Injectable({
  providedIn: 'root'
})
export class ProductsService {
  url = configurl.apiServer.url + '/api/product/';
  constructor(private http: HttpClient) { }
  getProductList(): Observable&amp;lt;Products[]&amp;gt; {
    return this.http.get&amp;lt;Products[]&amp;gt;(this.url + 'ProductsList');
  }
  postProductData(productData: Products): Observable&amp;lt;Products&amp;gt; {
    const httpHeaders = { headers:new HttpHeaders({'Content-Type': 'application/json'}) };
    return this.http.post&amp;lt;Products&amp;gt;(this.url + 'CreateProduct', productData, httpHeaders);
  }
  updateProduct(product: Products): Observable&amp;lt;Products&amp;gt; {
    const httpHeaders = { headers:new HttpHeaders({'Content-Type': 'application/json'}) };
    return this.http.post&amp;lt;Products&amp;gt;(this.url + 'UpdateProduct?id=' + product.productId, product, httpHeaders);
  }
  deleteProductById(id: number): Observable&amp;lt;number&amp;gt; {
    return this.http.post&amp;lt;number&amp;gt;(this.url + 'DeleteProduct?id=' + id, null);
  }
  getProductDetailsById(id: string): Observable&amp;lt;Products&amp;gt; {
    return this.http.get&amp;lt;Products&amp;gt;(this.url + 'ProductDetail?id=' + id);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 13:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Put the following code inside the app module&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ProductsComponent } from './products/products.component';
import {HttpClientModule} from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
import { JwtModule } from "@auth0/angular-jwt";
import { AuthGuard } from './guards/auth-guard.service';
import { HomepageComponent } from './homepage/homepage.component';
import { LoginComponent } from './login/login.component';
import { ToastrModule } from 'ngx-toastr';
//all components routes
const routes: Routes = [
  { path: '', component: HomepageComponent },
  { path: 'product', component: ProductsComponent, canActivate: [AuthGuard] },
  { path: 'login', component: LoginComponent },
];
//function is use to get jwt token from local storage
export function tokenGetter() {
  return localStorage.getItem("jwt");
}
@NgModule({
  declarations: [
    AppComponent,
    ProductsComponent,
    HomepageComponent,
    LoginComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule,
    RouterModule.forRoot(routes),
    JwtModule.forRoot({
      config: {
        tokenGetter: tokenGetter,
        allowedDomains: ["localhost:7299"],
        disallowedRoutes: []
      }
  }),
  ToastrModule.forRoot()
  ],
  providers: [AuthGuard],
  bootstrap: [AppComponent]
})
export class AppModule { }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, here you can see, first, we put some routes and create one method to get the JWT token from local storage and Also configure the JWT module and Auth Guard inside that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 14:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, run your application&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You will see the login page when running the application&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KEXT-cUP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0k85l9u7xevlfb7gmoqv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KEXT-cUP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0k85l9u7xevlfb7gmoqv.png" alt="Image description" width="584" height="364"&gt;&lt;/a&gt;&lt;br&gt;
After login, you will see the product page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J9nCX8_X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k59apuwt4fgi70i7m00l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J9nCX8_X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k59apuwt4fgi70i7m00l.png" alt="Image description" width="640" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
So, we discussed all JWT Authentication in Angular 14 step-by-step and how to store tokens in local storage and usage of it inside the product application.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>JWT Token Authentication using the .NET Core 6 Web API</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Sun, 06 Aug 2023 05:01:27 +0000</pubDate>
      <link>https://dev.to/jaydeep007/jwt-token-authentication-using-the-net-core-6-web-api-240l</link>
      <guid>https://dev.to/jaydeep007/jwt-token-authentication-using-the-net-core-6-web-api-240l</guid>
      <description>&lt;p&gt;We are going to discuss JWT Token Authentication and Implementation using .NET Core API 6&lt;/p&gt;

&lt;p&gt;Before looking into this blog, visit my following blog to understand the basics and details of JWT Token Authentication and Authorization and how things work using JWT.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/p/5a812e6d154c" rel="noopener noreferrer"&gt;Introduction and Details about JWT Token Authentication and Authorization&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s start the implementation of the .NET Core 6 Web API,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the .NET Core 6 Web API Application&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install the following NuGet packages, which we are going to use throughout the application.&lt;/p&gt;

&lt;p&gt;Microsoft.AspNetCore.Authentication.JwtBearer&lt;/p&gt;

&lt;p&gt;Microsoft.EntityFrameworkCore&lt;/p&gt;

&lt;p&gt;Microsoft.EntityFrameworkCore.Design&lt;/p&gt;

&lt;p&gt;Microsoft.EntityFrameworkCore.SqlServer&lt;/p&gt;

&lt;p&gt;Microsoft.EntityFrameworkCore.Tools&lt;/p&gt;

&lt;p&gt;Newtonsoft.Json&lt;/p&gt;

&lt;p&gt;StackExchange.Redis&lt;/p&gt;

&lt;p&gt;Swashbuckle.AspNetCore&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, create a new folder called Models inside the solution and create a Product class inside that.&lt;/p&gt;

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

namespace WebAPI.Model
{
    public class Product
    {
        public int ProductId { get; set; }
        public string? ProductName { get; set; }
        public string? ProductDescription { get; set; }
        public int ProductCost { get; set; }
        public int ProductStock { get; set; }
    }
}


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create one DbContextClass inside the Data folder used for Database operations.&lt;/p&gt;

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

using Microsoft.EntityFrameworkCore;
using WebAPI.Model;
namespace WebAPI.Data
{
    public class DbContextClass : DbContext
    {
        protected readonly IConfiguration Configuration;
        public DbContextClass(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
        }
    public DbSet&amp;lt;Product&amp;gt; Products { get; set; }
    }
}


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Later on, Create a product controller inside the Controllers folder.&lt;/p&gt;

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

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using WebAPI.Cache;
using WebAPI.Data;
using WebAPI.Model;
namespace WebAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController, Authorize]
    public class ProductController : ControllerBase
    {
        private readonly DbContextClass _context;
        private readonly ICacheService _cacheService;
        public ProductController(DbContextClass context, ICacheService cacheService)
        {
            _context = context;
            _cacheService = cacheService;
        }
        [HttpGet]
        [Route("ProductsList")]
        public async Task&amp;lt;ActionResult&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;&amp;gt; Get()
        {
            var productCache = new List&amp;lt;Product&amp;gt;();
            productCache = _cacheService.GetData&amp;lt;List&amp;lt;Product&amp;gt;&amp;gt;("Product");
            if (productCache == null)
            {
                var product = await _context.Products.ToListAsync();
                if(product.Count &amp;gt; 0)
                {
                    productCache = product;
                    var expirationTime = DateTimeOffset.Now.AddMinutes(3.0);
                    _cacheService.SetData("Product", productCache, expirationTime);
                }
            }
            return productCache;
        }

        [HttpGet]
        [Route("ProductDetail")]
        public async Task&amp;lt;ActionResult&amp;lt;Product&amp;gt;&amp;gt; Get(int id)
        {
            var productCache = new Product();
            var productCacheList = new List&amp;lt;Product&amp;gt;();
            productCacheList = _cacheService.GetData&amp;lt;List&amp;lt;Product&amp;gt;&amp;gt;("Product");
            productCache = productCacheList.Find(x =&amp;gt; x.ProductId == id);
            if (productCache == null)
            {
                productCache = await _context.Products.FindAsync(id);
            }
            return productCache;
        }

        [HttpPost]
        [Route("CreateProduct")]
        public async Task&amp;lt;ActionResult&amp;lt;Product&amp;gt;&amp;gt; POST(Product product)
        {
            _context.Products.Add(product);
            await _context.SaveChangesAsync();
            _cacheService.RemoveData("Product");
            return CreatedAtAction(nameof(Get), new { id = product.ProductId }, product);
        }
        [HttpPost]
        [Route("DeleteProduct")]
        public async Task&amp;lt;ActionResult&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;&amp;gt; Delete(int id)
        {
            var product = await _context.Products.FindAsync(id);
            if (product == null)
            {
                return NotFound();
            }
            _context.Products.Remove(product);
            _cacheService.RemoveData("Product");
            await _context.SaveChangesAsync();
            return await _context.Products.ToListAsync();
        }

        [HttpPost]
        [Route("UpdateProduct")]
        public async Task&amp;lt;ActionResult&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;&amp;gt; Update(int id, Product product)
        {
            if (id != product.ProductId)
            {
                return BadRequest();
            }
            var productData = await _context.Products.FindAsync(id);
            if (productData == null)
            {
                return NotFound();
            }
            productData.ProductCost = product.ProductCost;
            productData.ProductDescription = product.ProductDescription;
            productData.ProductName = product.ProductName;
            productData.ProductStock = product.ProductStock;
            _cacheService.RemoveData("Product");
            await _context.SaveChangesAsync();
            return await _context.Products.ToListAsync();
        }
    }
}


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 6:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, we are going to use the Redis cache inside this application. If you understand how distributed Redis caches work, check my following blog&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/p/c8276167ef0c" rel="noopener noreferrer"&gt;Implementation of Redis Cache in the.NET Core Web API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the Cache folder inside the solution and create a few classes for Redis and Connection Helper. So, First, create ICacheService and CacheService for Redis Cache.&lt;/p&gt;

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

namespace WebAPI.Cache
{
    public interface ICacheService
    {
        /// &amp;lt;summary&amp;gt;
        /// Get Data using key
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;
        /// &amp;lt;param name="key"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        T GetData&amp;lt;T&amp;gt;(string key);
        /// &amp;lt;summary&amp;gt;
        /// Set Data with Value and Expiration Time of Key
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;
        /// &amp;lt;param name="key"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="value"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="expirationTime"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        bool SetData&amp;lt;T&amp;gt;(string key, T value, DateTimeOffset expirationTime);
        /// &amp;lt;summary&amp;gt;
        /// Remove Data
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="key"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        object RemoveData(string key);
    }
}


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

&lt;/div&gt;

&lt;p&gt;Next, create the CacheService class for Redis Cache-related functionality.&lt;/p&gt;

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

using Newtonsoft.Json;
using StackExchange.Redis;
namespace WebAPI.Cache
{
    public class CacheService : ICacheService
    {
        private IDatabase _db;
        public CacheService()
        {
            ConfigureRedis();
        }
        private void ConfigureRedis()
        {
            _db = ConnectionHelper.Connection.GetDatabase();
        }
        public T GetData&amp;lt;T&amp;gt;(string key)
        {
            var value = _db.StringGet(key);
            if (!string.IsNullOrEmpty(value))
            {
                return JsonConvert.DeserializeObject&amp;lt;T&amp;gt;(value);
            }
            return default;
        }
        public bool SetData&amp;lt;T&amp;gt;(string key, T value, DateTimeOffset expirationTime)
        {
            TimeSpan expiryTime = expirationTime.DateTime.Subtract(DateTime.Now);
            var isSet =_db.StringSet(key, JsonConvert.SerializeObject(value), expiryTime);
            return isSet;
        }
        public object RemoveData(string key)
        {
            bool _isKeyExist = _db.KeyExists(key);
            if (_isKeyExist == true)
            {
                return _db.KeyDelete(key);
            }
            return false;
        }
    }
}


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 8:&lt;/strong&gt;&lt;br&gt;
Create ConfigurationManager class which we use to configure the appsetting.json file&lt;/p&gt;

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

namespace WebAPI
{
    static class ConfigurationManager
    {
        public static IConfiguration AppSetting { get; }
        static ConfigurationManager()
        {
            AppSetting = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json")
                    .Build();
        }
    }
}


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 9:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, create a ConnectionHelper class inside the cache folder to get the RedisURL and configure that in the application.&lt;/p&gt;

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

using StackExchange.Redis;
namespace WebAPI.Cache
{
    public class ConnectionHelper
    {
        static ConnectionHelper()
        {
            ConnectionHelper.lazyConnection = new Lazy&amp;lt;ConnectionMultiplexer&amp;gt;(() =&amp;gt;
            {
                return ConnectionMultiplexer.Connect(ConfigurationManager.AppSetting["RedisURL"]);
            });
        }
        private static Lazy&amp;lt;ConnectionMultiplexer&amp;gt; lazyConnection;
        public static ConnectionMultiplexer Connection
        {
            get
            {
                return lazyConnection.Value;
            }
        }
    }
}


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 10:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, we are going to create Login and JWTTokenResponse class for the JWT Authentication part&lt;/p&gt;

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

namespace WebAPI.Model
{
    public class Login
    {
        public string? UserName { get; set; }
        public string? Password { get; set; }
    }
}


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

&lt;/div&gt;

&lt;p&gt;Also, Create JWTTokenResponse class for token&lt;/p&gt;

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

namespace WebAPI.Model
{
    public class JWTTokenResponse
    {
        public string? Token { get; set; }
    }
}


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 11:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Later, Create an authentication controller inside the Controllers for user authentication.&lt;/p&gt;

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

using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using WebAPI.Model;
namespace WebAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AuthenticationController : ControllerBase
    {
        [HttpPost("login")]
        public IActionResult Login([FromBody] Login user)
        {
            if (user is null)
            {
                return BadRequest("Invalid user request!!!");
            }
            if (user.UserName == "Jaydeep" &amp;amp;&amp;amp; user.Password == "Pass@777")
            {
                var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(ConfigurationManager.AppSetting["JWT:Secret"]));
                var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
                var tokeOptions = new JwtSecurityToken(
                    issuer: ConfigurationManager.AppSetting["JWT:ValidIssuer"],
                    audience: ConfigurationManager.AppSetting["JWT:ValidAudience"],
                    claims: new List&amp;lt;Claim&amp;gt;(),
                    expires: DateTime.Now.AddMinutes(6),
                    signingCredentials: signinCredentials
                );
                var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);
                return Ok(new JWTTokenResponse { Token = tokenString });
            }
            return Unauthorized();
        }
    }
}


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;As you see in the above class, we take the Username and Password from the User, then take the secret key, which we put inside the appsettings.json file&lt;/li&gt;
&lt;li&gt;Next, create signing credentials using a secret key using the HMAC SHA256 Crypto Algorithm for the encoded string.&lt;/li&gt;
&lt;li&gt;Later on, we added a few attributes while creating tokens like signing credentials, expiration time, issuer, audience, and different types of claims as per our needs and requirements.&lt;/li&gt;
&lt;li&gt;Finally, using the token handler, create the token, which is in encoded form and sent to the end-user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 12:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add a few Environmental Variables inside the appsetting.json file&lt;/p&gt;

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

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "RedisURL": "127.0.0.1:6379",
  "JWT": {
    "ValidAudience": "http://localhost:7299",
    "ValidIssuer": "http://localhost:7299",
    "Secret": "JWTAuthentication@777"
  },
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=Server;Initial Catalog=JWTDemo;User Id=sa;Password=****;"
  }
}


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 13:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, register all servers related to JWT Authentication, Swagger UI for Authentication, CORS Policy, and Cache Services inside the Program class as shown below.&lt;/p&gt;

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

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Text;
using WebAPI.Cache;
using WebAPI.Data;
using ConfigurationManager = WebAPI.ConfigurationManager;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =&amp;gt;
{
    options.SwaggerDoc("V1", new OpenApiInfo
    {
        Version = "V1",
        Title = "WebAPI",
        Description = "Product WebAPI"
    });
    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Scheme = "Bearer",
        BearerFormat = "JWT",
        In = ParameterLocation.Header,
        Name = "Authorization",
        Description = "Bearer Authentication with JWT Token",
        Type = SecuritySchemeType.Http
    });
    options.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Id = "Bearer",
                    Type = ReferenceType.SecurityScheme
                }
            },
            new List&amp;lt;string&amp;gt;()
        }
    });
});
builder.Services.AddScoped&amp;lt;ICacheService, CacheService&amp;gt;();
builder.Services.AddDbContext&amp;lt;DbContextClass&amp;gt;();
builder.Services.AddAuthentication(opt =&amp;gt; {
    opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
    .AddJwtBearer(options =&amp;gt;
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = ConfigurationManager.AppSetting["JWT:ValidIssuer"],
            ValidAudience = ConfigurationManager.AppSetting["JWT:ValidAudience"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(ConfigurationManager.AppSetting["JWT:Secret"]))
        };
    });
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI(options =&amp;gt; {
        options.SwaggerEndpoint("/swagger/V1/swagger.json", "Product WebAPI");
    });
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.UseCors(x =&amp;gt; x
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader());
app.Run();


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 14:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, execute the following command in the Package Manager Console for the entity framework for data migration and database updates:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;add-migration “First”&lt;br&gt;
update-database&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 15:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the application, create the token after providing credentials and put it into the Authorize tab inside swagger UI, as shown in the below image&lt;/p&gt;

&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%2Femmguu15ir9h4g9evhd3.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%2Femmguu15ir9h4g9evhd3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Fe6ububu3kz78trxs2d46.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%2Fe6ububu3kz78trxs2d46.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Fqhq3viuq5pz3xjnn7a6p.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%2Fqhq3viuq5pz3xjnn7a6p.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2F2uzrhbtdv851nk9rebog.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%2F2uzrhbtdv851nk9rebog.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Fzvxhrg949pyqoum9bjtn.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%2Fzvxhrg949pyqoum9bjtn.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2Fneonko0oq7jkyd0mdqp2.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%2Fneonko0oq7jkyd0mdqp2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&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%2F80hl2xo35ulef50f49sr.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%2F80hl2xo35ulef50f49sr.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, this is all about JWT Authentication in the.NET Core 6 Web API.&lt;/p&gt;

&lt;p&gt;I hope you understood these things and now have an idea of how things work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>dotnet</category>
      <category>dotnetcore</category>
      <category>dotnetframework</category>
    </item>
    <item>
      <title>A Detailed Introduction to JWT Authentication and Authorization</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Sat, 11 Mar 2023 06:56:51 +0000</pubDate>
      <link>https://dev.to/jaydeep007/a-detailed-introduction-to-jwt-authentication-and-authorization-334c</link>
      <guid>https://dev.to/jaydeep007/a-detailed-introduction-to-jwt-authentication-and-authorization-334c</guid>
      <description>&lt;p&gt;We will discuss authentication and authorization using the JWT token and different cryptographic algorithms and techniques. So, we will be looking at the following things one by one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction of JWT Token
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why JWT Token&lt;/li&gt;
&lt;li&gt;Structure of JWT Token&lt;/li&gt;
&lt;li&gt;Client-Server Scenario with JWT Token&lt;/li&gt;
&lt;li&gt;Client-Server Scenario with JWT Refresh Token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s start one by one with the basics and real-time scenarios.&lt;/p&gt;

&lt;p&gt;Basically, JWT is used for the authentication and authorization of different users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In this process, we send the username and password to the authentication server.&lt;/li&gt;
&lt;li&gt;Authentication Server will validate those credentials and store them somewhere on the browser Session and Cookies and Send the ID to the end-user.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Authorization
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In, the Authorization we check whatever credential entered by the user while the Authentication process and that same user will have granted access to the resource using the credential which we store in the Authentication Process and then Authorize that particular user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, this is all about authentication and authorization, normally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction of JWT Token
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;JSON Web Token is the Open Standard (RFC 7519) Self-Contained way that will be used to transmit the data securely over the different environments as a JSON Object.&lt;/li&gt;
&lt;li&gt;RFC (Request for Comment) is the shortened form of Remote Function Call and Formal Document from the Internet Engineering Task Force. RFC 7519 JSON Web Token (JWT) May 2015 Copyright Notice Copyright © 2015 IETF Trust and the persons identified as the document authors. All rights reserved.&lt;/li&gt;
&lt;li&gt;JWT is the trusted way of authentication because it is digitally signed and secret using HMAC Algorithm or sometimes using a public/private key using RSA.&lt;/li&gt;
&lt;li&gt;Basically, HMAC stands for Hashed-based Message Authentication Code, it uses some great cryptographic hashing technique that provides us great security.&lt;/li&gt;
&lt;li&gt;Also, the JWT is part of great Authentication and Authorization Framework like OAuth and OpenID which will provide a great mechanism to transfer data securely.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why JWT Token
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The User will Authenticate using JWT Token and It is a digitally signed signature with a secret key issued by the issuer. So that will use to Authenticate the User Securely and Also, manage the claims, and many more.&lt;/li&gt;
&lt;li&gt;Instead of storing information User Credentials somewhere on the Server that will get easily by attackers over the internet. So, we use JWT, and using that we maintain user secrets with different Cryptographic Algorithms and Encoded that to Authenticate Users.&lt;/li&gt;
&lt;li&gt;That’s why many web applications use JWT for authentication of users securely&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Structure of JWT Token
&lt;/h2&gt;

&lt;p&gt;Basically, The JSON Web Token consists of three parts which are used to store user information in the Token separated by dots(.)&lt;/p&gt;

&lt;p&gt;For example –&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L_HaD8PP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1hpsyk3wrpzk38gwgjqe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L_HaD8PP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1hpsyk3wrpzk38gwgjqe.png" alt="Image description" width="391" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W1lLG1Ga--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2gaabfcff7cz4eelvyfg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W1lLG1Ga--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2gaabfcff7cz4eelvyfg.png" alt="Image description" width="484" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you see in the above diagram, it is an encoded Base64 URL that stores user secrets and information in three parts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Header&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The header stores information about the JWT token, like the type of token and whatever algorithm we used to create it.&lt;/p&gt;

&lt;p&gt;For Example –&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "alg": "HS256",&lt;br&gt;
  "typ": "JWT"&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;2. Payload&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Payload is the second part of the JWT token, which is used to store information about users like claims, roles, subjects, and some additional information related to a user.&lt;/p&gt;

&lt;p&gt;For Example-&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{&lt;br&gt;
  "sub": "1234567890",&lt;br&gt;
  "name": "Jaydeep Patil",&lt;br&gt;
  "admin": "true"&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Signature&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Signature is used to check user information that is present in the header and payload and validate things with the secret key and data that is present in the base64-encoded string. Basically, the secret key is present on the server, which we use while creating the token. That secret key prevents external attackers from cracking the token. So, in this process, a Base64-encoded string is created to be used for authentication and authorization.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;HMACSHA256(&lt;br&gt;
  base64UrlEncode(header) + "." +&lt;br&gt;
  base64UrlEncode(payload),//This is the Secret Key which is store at server side and use in signature&lt;br&gt;
your-256-bit-secret)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So, these are the three parts of the token that are present in the Base64Url string, which is separated by a dot and stores secret information of the user for validating users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Client-Server Scenario with JWT Token
&lt;/h2&gt;

&lt;p&gt;You can see in the following diagram how the authentication process works for the user when he wants to access the resources from the backend server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5vSqQCV4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wjej33t4xephbterjc75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5vSqQCV4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wjej33t4xephbterjc75.png" alt="Image description" width="720" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, the user sends a request to the Authentication Server with credentials like User Name and Password.&lt;/li&gt;
&lt;li&gt;Then, the Authentication server will validate that information and whatever information is provided by the user that will be correct and successfully authenticate then Auth Server will issue the JWT Valid Access Token to the user.&lt;/li&gt;
&lt;li&gt;Next, The User Sends the first request to the backend server with a Valid JWT Access Token and the Server will provide the requested resource to the user.&lt;/li&gt;
&lt;li&gt;Later on, if the user wants to access another service from the backend server then he will send a second request to the server.&lt;/li&gt;
&lt;li&gt;Now, as you see in the diagram when the user sends the second request to the server to access the protected resource but at that time the token is expired so the server responds to the end-user.&lt;/li&gt;
&lt;li&gt;Finally, as you see in the last part of the diagram user again needs to be login and send the user credential to the authentication server to get a new JWT Valid Access Token and store it somewhere on the client-side in the Local Storage and something like that in the Base64Url Encoded URL.&lt;/li&gt;
&lt;li&gt;So, this way the normal authentication process will work.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Client-Server Scenario with JWT Refresh Token
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You can see in the following diagram how the JWT Refresh Token will work step-by-step.&lt;/li&gt;
&lt;li&gt;First, the user will send the request to the Authentication Server with credentials like User Name and Password.&lt;/li&gt;
&lt;li&gt;Next, the Authentication Server validates the user information and credentials that will be correct then the server will provide the JWT Valid Access Token and Refresh Token. Then, the user will store that token somewhere on the client-side in the Local Storage and something like that as per need and requirement.&lt;/li&gt;
&lt;li&gt;Later on, the user sends the first request to the backend server to access the protected resources with JWT Valid Access Token in the header.&lt;/li&gt;
&lt;li&gt;Next, the backend server checks the roles and permission of the user like the login user is authorized to get the protected resources and that will valid and proper then the backend server provides the requested protected resource to the end-user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TA-_xlfh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7aubmkrpc0cgm3m08oi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TA-_xlfh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7aubmkrpc0cgm3m08oi.png" alt="Image description" width="720" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the meantime, the user sends the second request to the backend server to access another service and if meanwhile the JWT Valid Access Token is expired in that case the server will respond to the end-user as you see above image.&lt;/li&gt;
&lt;li&gt;In that case, when the JWT Valid Access Token is expired then the user sends the authentication request to the Auth Server with Refresh Token to get a new JWT Access Token.&lt;/li&gt;
&lt;li&gt;Next, the server will validate the user information and provide a new access token with a refresh token to the end-user and the refresh token have more life than the Simple JWT Valid Access Token&lt;/li&gt;
&lt;li&gt;So, all the above steps are executed continuously while navigating the web application and accessing the new services and resources over the internet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, this is all about the JWT token and how things are going to work during the authentication and authorization process.&lt;/p&gt;

&lt;p&gt;I hope you understand all things related to JWT and now have a basic idea about it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>security</category>
      <category>api</category>
    </item>
    <item>
      <title>Dependency Injection and Different ways to inject it using .NET Core API</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Sun, 05 Mar 2023 05:15:45 +0000</pubDate>
      <link>https://dev.to/jaydeep007/dependency-injection-and-different-ways-to-inject-it-using-net-core-api-5570</link>
      <guid>https://dev.to/jaydeep007/dependency-injection-and-different-ways-to-inject-it-using-net-core-api-5570</guid>
      <description>&lt;p&gt;In this blog, we are going to discuss dependency injection and its usage and benefits. Also, discuss different ways to implement dependency injection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites:
&lt;/h2&gt;

&lt;p&gt;Basic understanding of C# Programming Language.&lt;br&gt;
Understanding of Object-Oriented Programming.&lt;br&gt;
Basic Understanding of .NET Core.&lt;/p&gt;
&lt;h2&gt;
  
  
  The purpose behind the dependency injection design patterns is:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In simple words, dependency means the object depends on another object to do some work.&lt;/li&gt;
&lt;li&gt;Using Dependency Injection we are able to write loosely coupled classes and because of that our current functionality of one class does not directly depend on another class because of that we can easily maintain, change and unit test code properly.&lt;/li&gt;
&lt;li&gt;It also takes care of the open-closed principle using abstraction and interface we are able to make some future changes easily without modifying existing functionality.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Dependency Injection:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Dependency Injection is used to inject the Object of the class into another class.&lt;/li&gt;
&lt;li&gt;Dependency Injection uses Inversion of Control to create an object outside the class and use that object using different ways like using Service Container which .NET Core provides.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Now we are looking what is the problem we have faced without using Dependency Injection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suppose we have a class car, and that depends on the BMW 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 Car
{
    private BMW _bmw;
    public Car()
    {
        _bmw = new BMW();
    }
}
public class BMW
{
    public BMW()
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here in this example class, Car depends on the BMW class, and because they are tightly coupled, we need to create an object of the BMW class each time.&lt;/p&gt;

&lt;p&gt;In the future, suppose we want to add some parameters to the BMW Class Constructor, like the model name, as shown in the below example.&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 Car
{
    private BMW _bmw;
    public Car()
    {
        _bmw = new BMW("BMW X1");
    }
}
public class BMW
{
    public BMW(string ModelName)
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, in this case, we need to add the Model Name parameter into the Car class, and again, we need to change the constructor and pass the parameter. This is not a good practice in software development, and because of that, there is a hard dependency created, and when our application is large, it’s hard to maintain.&lt;/p&gt;

&lt;p&gt;These are the challenges we face while implementing functionality without Dependency Injection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uses of Dependency Injection in .NET Core:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;.NET Core provides a mechanism like IOC Container that will respond to take care of the following things.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Registration of services with type and class in a container and due to this we are able to inject the services as per our need.&lt;/li&gt;
&lt;li&gt;The IOC Container also resolves the dependencies of classes of the required class.&lt;/li&gt;
&lt;li&gt;It also manages the lifetime of the object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ways to register Lifetime of Services in startup class:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scope:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It will create a single instance per scope.&lt;/li&gt;
&lt;li&gt;It will create instances of every request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Singleton:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It will create only a single instance per request and be used throughout the application.&lt;/li&gt;
&lt;li&gt;It also shared that same instance throughout the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Transient:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It will make a new instance at each time and not share with other applications.&lt;/li&gt;
&lt;li&gt;It is used for small and lightweight applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Now we are going to create .NET Core Product Application using Dependency Injection one by one.&lt;/strong&gt;&lt;/p&gt;

&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%2Fdc7fuvkqgua7hpowsmp5.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%2Fdc7fuvkqgua7hpowsmp5.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Then configure the project&lt;/p&gt;

&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%2Fw0i5qw7j2ch4j264k689.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%2Fw0i5qw7j2ch4j264k689.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Provide additional information like .NET Version and other configuration&lt;/p&gt;

&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%2Fkn7a7jw57dtxwo3lj8n1.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%2Fkn7a7jw57dtxwo3lj8n1.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Then, install the following NuGet Packages which we need for Swagger, SQL Server, Migration, and Database Update.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microsoft.EntityFrameworkCore

Microsoft.EntityFrameworkCore.Design

Microsoft.EntityFrameworkCore.SqlServer

Microsoft.EntityFrameworkCore.Tools

Swashbuckle.AspNetCore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&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%2Fl6zbydev6rt42ztatjje.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%2Fl6zbydev6rt42ztatjje.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Now, Create the ProductDetail Class inside the Model Folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.ComponentModel.DataAnnotations;
namespace Product.Model
{
    public class ProductDetail
    {
        [Key]
        public int Id { get; set; }
        public string Name { get; set; }
        public int Cost { get; set; }
        public int NoOfStock { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later on, Create DBContextClass for the database-related operation of entity framework&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.EntityFrameworkCore;
using Product.Model;
namespace Product.Data
{
    public class DBContextClass : DbContext
    {
        public DBContextClass(DbContextOptions&amp;lt;DBContextClass&amp;gt; options) : base(options)
        {
        }
        public DbSet&amp;lt;ProductDetail&amp;gt; Products { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the Database Connection string of SQL Server in the appsetting.json file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=ServerName;Initial Catalog=ProductData;User Id=Test;Password=database@123;"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the ProductService and IProductService Classes inside Service Folder for data manipulation using Dependency Injection&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Product.Model;
using System.Collections.Generic;
namespace Product.Service
{
    public interface IProductService
    {
        ProductDetail AddProduct(ProductDetail employee);
        List&amp;lt;ProductDetail&amp;gt; GetProducts();
        void UpdateProduct(ProductDetail employee);
        void DeleteProduct(int Id);
        ProductDetail GetProduct(int Id);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create ProductService Class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Product.Data;
using Product.Model;
using System.Collections.Generic;
using System.Linq;
namespace Product.Service
{
    public class ProductService : IProductService
    {
        private readonly DBContextClass _context;
public ProductService(DBContextClass context)
        {
            _context = context;
        }
        public ProductDetail AddProduct(ProductDetail product)
        {
            _context.Products.Add(product);
            _context.SaveChanges();
            return product;
        }
public void DeleteProduct(int Id)
        {
            var product = _context.Products.FirstOrDefault(x =&amp;gt; x.Id == Id);
            if (product != null)
            {
                _context.Remove(product);
                _context.SaveChanges();
            }
        }
public ProductDetail GetProduct(int Id)
        {
            return _context.Products.FirstOrDefault(x =&amp;gt; x.Id == Id);
        }
public List&amp;lt;ProductDetail&amp;gt; GetProducts()
        {
            return _context.Products.OrderBy(a =&amp;gt; a.Name).ToList();
        }
public void UpdateProduct(ProductDetail product)
        {
            _context.Products.Update(product);
            _context.SaveChanges();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, Create ProductController and inside that, you can see we inject product service into the constructor easily without being tightly coupled. So it helps to extend the functionality of the Product without modifying existing functionality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Mvc;
using Product.Model;
using Product.Service;
using System.Collections.Generic;
namespace Product.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductController : ControllerBase
    {
        private readonly IProductService productService;
        public ProductController(IProductService _productService)
        {
            productService = _productService;
        }
        [HttpGet]
        [Route("api/Product/GetProducts")]
        public IEnumerable&amp;lt;ProductDetail&amp;gt; GetProducts()
        {
            return productService.GetProducts();
        }
        [HttpPost]
        [Route("api/Product/AddProduct")]
        public IActionResult AddProduct(ProductDetail product)
        {
            productService.AddProduct(product);
            return Ok();
        }
        [HttpPut]
        [Route("api/Product/UpdateProduct")]
        public IActionResult UpdateProduct(ProductDetail product)
        {
            productService.UpdateProduct(product);
            return Ok();
        }
        [HttpDelete]
        [Route("api/Product/DeleteProduct")]
        public IActionResult DeleteProduct(int id)
        {
            var existingProduct = productService.GetProduct(id);
            if (existingProduct != null)
            {
                productService.DeleteProduct(existingProduct.Id);
                return Ok();
            }
            return NotFound($"Product Not Found with ID : {existingProduct.Id}");
        }
        [HttpGet]
        [Route("GetProduct")]
        public ProductDetail GetProduct(int id)
        {
            return productService.GetProduct(id);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, Register the service inside the ConfigureServices method and also add Db Provider and configure the Database connection string which we put in the app settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Product.Data;
using Product.Service;
namespace Product
{
    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.AddControllers();
            //DBContext Configuration
            services.AddDbContext&amp;lt;DBContextClass&amp;gt;(options =&amp;gt;
           options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            //Register the ProductService for DI purpose
            services.AddScoped&amp;lt;IProductService, ProductService&amp;gt;();
            //enable swagger
            services.AddSwaggerGen(c =&amp;gt;
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "Product", Version = "v1" });
            });
        }
        // 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();
                app.UseSwagger();
                app.UseSwaggerUI(c =&amp;gt; c.SwaggerEndpoint("/swagger/v1/swagger.json", "Product v1"));
            }
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =&amp;gt;
            {
                endpoints.MapControllers();
            });
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our Project structure looks like as shown in the image&lt;/p&gt;

&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%2F2l4dsoaezbo5pnot6ftz.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%2F2l4dsoaezbo5pnot6ftz.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Finally, we are going to create a database and migrations using Entity Framework. So for that open the Package Manager Console in Visual Studio and enter the following command for migration one by one.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Add-Migration "FirstMigration"&lt;br&gt;
database-update&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, run the Product Application and open the swagger dashboard and use the endpoints.&lt;/p&gt;

&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%2Fq0v09bjysmcek0a0rnld.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%2Fq0v09bjysmcek0a0rnld.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
There are also following different ways to inject the DI without Controller Constructor&lt;/p&gt;

&lt;p&gt;Method 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HttpGet]
[Route("api/Product/GetProducts")]
public IEnumerable&amp;lt;ProductDetail&amp;gt; GetProducts()
{
    //method 1
    var services = this.HttpContext.RequestServices;
    var productService = (IProductService)services.GetService(typeof(IProductService));
    return productService.GetProducts();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Method 2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HttpPost]
[Route("api/Product/AddProduct")]
public IActionResult AddProduct(ProductDetail product)
{
    //Method 2
    var productService =
   (IProductService)this.HttpContext.RequestServices.GetService(typeof(IProductService));
    productService.AddProduct(product);
    return Ok();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Method 3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Method 3
public IActionResult UpdateProduct([FromServices] IProductService productService,
ProductDetail product)
{
    productService.UpdateProduct(product);
    return Ok();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, This is all about Dependency Injection. I hope you understand&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Coding!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>dotnetcore</category>
      <category>asp</category>
    </item>
    <item>
      <title>Implementation of the REDIS Cache in the.NET Core API</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Sat, 25 Feb 2023 05:44:02 +0000</pubDate>
      <link>https://dev.to/jaydeep007/implementation-of-the-redis-cache-in-thenet-core-api-38oh</link>
      <guid>https://dev.to/jaydeep007/implementation-of-the-redis-cache-in-thenet-core-api-38oh</guid>
      <description>&lt;p&gt;We'll go over caching and how it works in.NET Core. So, we look at the following things one by one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduction of Caching&lt;/li&gt;
&lt;li&gt;What is Cache&lt;/li&gt;
&lt;li&gt;Types of cache&lt;/li&gt;
&lt;li&gt;Cache Implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, let’s start one by one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Caching is very popular nowadays in the software industry because it will improve the performance and scalability of the application, as we see with many web applications like e-mail and Facebook and how responsive they are and how great the user experience is while using them. There are a lot of users using the internet, and if an application has huge network traffic and demand, we need to take care of many things that help us improve the performance and responsiveness of the application. As a result, one of the solutions is caching, which is where caching enters the picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Caching?
&lt;/h2&gt;

&lt;p&gt;The cache is the memory storage that is used to store the frequent access data into the temporary storage, it will improve the performance drastically, avoid unnecessary database hits, and store frequently used data into the buffer whenever we need it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nuTapI5Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aerrcy8dlsvgnirev88f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nuTapI5Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aerrcy8dlsvgnirev88f.png" alt="Image description" width="531" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oCszXQy2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6ofbj7i77fvwgj4hlyy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oCszXQy2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6ofbj7i77fvwgj4hlyy.png" alt="Image description" width="531" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you see in the above image there are two scenarios one is without using cache and another is with cache and how it works, So here when we do not use the cache, in that case, suppose users want data then they will hit each time database and it will increase the time complexity and reduce performance in case there is some static data users want and it is same for all user, in that case when we do not use cache then each one hit the unnecessary database to fetch data and on the other side as you can see we use cache and in that case if there same static and same data for all users then only the first user will hit the database and fetch data and store it into the cache memory and then other two users used that from the cache without unnecessarily hit database to fetch data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Cache
&lt;/h2&gt;

&lt;p&gt;Basically, there are two types of caching .NET Core supports&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In-Memory Caching&lt;/li&gt;
&lt;li&gt;Distributed Caching&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When we use In-Memory Cache then in that case data is stored in the application server memory and whenever we need then we fetch data from that and use it wherever we need it. And in Distributed Caching there are many third-party mechanisms like REDIS and many others. But in this section, we look into the REDIS Cache in detail and how it works in the .NET Core&lt;/p&gt;

&lt;h2&gt;
  
  
  Distributed Caching
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VV5C2n6v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sglmrf1l5vq7xlxj04lg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VV5C2n6v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sglmrf1l5vq7xlxj04lg.png" alt="Image description" width="531" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basically, in the distributed caching data are stored and shared between multiple servers&lt;br&gt;
Also, it’s easy to improve scalability and performance of application after managing the load between multiple servers when we use multi-tenant application&lt;br&gt;
Suppose, In the future, if one server is crashed and restarted then the application does not have any impact because multiple servers are as per our need if we want&lt;br&gt;
REDIS is the most popular cache which is used by many companies nowadays to improve the performance and scalability of the application. So, we are going to discuss REDIS and usage one by one.&lt;/p&gt;
&lt;h2&gt;
  
  
  REDIS Cache
&lt;/h2&gt;

&lt;p&gt;REDIS is an Open Source (BSD Licensed) in-memory Data Structure store used as a database.&lt;br&gt;
Basically, it is used to store the frequently used and some static data inside the cache and use and reserve that as per user requirement.&lt;br&gt;
There are many data structures present in the REDIS which we are able to use like List, Set, Hashing, Stream, and many more to store the data.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installation of REDIS Cache
&lt;/h2&gt;

&lt;p&gt;Step 1)&lt;/p&gt;

&lt;p&gt;Download the REDIS Server using the following URL&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/microsoftarchive/redis/releases/tag/win-3.0.504"&gt;https://github.com/microsoftarchive/redis/releases/tag/win-3.0.504&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 2)&lt;/p&gt;

&lt;p&gt;Extract the zip file and later on open the REDIS Server and REDIS CLI&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WHZHwL-6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v2lz5u5g55sv7uwaell2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WHZHwL-6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v2lz5u5g55sv7uwaell2.png" alt="Image description" width="777" height="456"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Implementation of REDIS Cache using .NET Core API
&lt;/h2&gt;

&lt;p&gt;Step 1)&lt;/p&gt;

&lt;p&gt;Create the .NET Core API Web Application&lt;/p&gt;

&lt;p&gt;Step 2)&lt;/p&gt;

&lt;p&gt;Install the following NuGet Packages which need step by step in our application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
Swashbuckle.AspNetCore
StackExchange.Redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3)&lt;/p&gt;

&lt;p&gt;Create the Model folder and create one Product Class inside that with details&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace RedisCacheDemo.Model
{
    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public string ProductDescription { get; set; }
        public int Stock { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4)&lt;/p&gt;

&lt;p&gt;Next, Create the DbContextClass Class for Database related operations as I showed below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.EntityFrameworkCore;
using RedisCacheDemo.Model;
namespace RedisCacheDemo.Data
{
    public class DbContextClass: DbContext
    {
        public DbContextClass(DbContextOptions&amp;lt;DbContextClass&amp;gt; options) : base(options)
        {
        }
        public DbSet&amp;lt;Product&amp;gt; Products { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5)&lt;/p&gt;

&lt;p&gt;Now, we are going to create ICacheService Interface and CacheService Class for Redis Cache-related usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
namespace RedisCacheDemo.Cache
{
    public interface ICacheService
    {
        /// &amp;lt;summary&amp;gt;
        /// Get Data using key
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;
        /// &amp;lt;param name="key"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        T GetData&amp;lt;T&amp;gt;(string key);
        /// &amp;lt;summary&amp;gt;
        /// Set Data with Value and Expiration Time of Key
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;
        /// &amp;lt;param name="key"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="value"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="expirationTime"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        bool SetData&amp;lt;T&amp;gt;(string key, T value, DateTimeOffset expirationTime);
        /// &amp;lt;summary&amp;gt;
        /// Remove Data
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="key"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        object RemoveData(string key);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, Create CacheService Class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Newtonsoft.Json;
using StackExchange.Redis;
using System;
namespace RedisCacheDemo.Cache
{
    public class CacheService : ICacheService
    {
        private IDatabase _db;
        public CacheService()
        {
            ConfigureRedis();
        }
        private void ConfigureRedis()
        {
            _db = ConnectionHelper.Connection.GetDatabase();
        }
        public T GetData&amp;lt;T&amp;gt;(string key)
        {
            var value = _db.StringGet(key);
            if (!string.IsNullOrEmpty(value))
            {
                return JsonConvert.DeserializeObject&amp;lt;T&amp;gt;(value);
            }
            return default;
        }
        public bool SetData&amp;lt;T&amp;gt;(string key, T value, DateTimeOffset expirationTime)
        {
            TimeSpan expiryTime = expirationTime.DateTime.Subtract(DateTime.Now);
            var isSet =_db.StringSet(key, JsonConvert.SerializeObject(value), expiryTime);
            return isSet;
        }
        public object RemoveData(string key)
        {
            bool _isKeyExist = _db.KeyExists(key);
            if (_isKeyExist == true)
            {
                return _db.KeyDelete(key);
            }
            return false;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6)&lt;/p&gt;

&lt;p&gt;Create the ProductController class create the following method as shown below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Mvc;
using RedisCacheDemo.Cache;
using RedisCacheDemo.Data;
using RedisCacheDemo.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace RedisCacheDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductController : ControllerBase
    {
        private readonly DbContextClass _dbContext;
        private readonly ICacheService _cacheService;
        public ProductController(DbContextClass dbContext, ICacheService cacheService)
        {
            _dbContext = dbContext;
            _cacheService = cacheService;
        }
        [HttpGet("products")]
        public IEnumerable&amp;lt;Product&amp;gt; Get()
        {
            var cacheData = _cacheService.GetData&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;("product");
            if (cacheData != null)
            {
                return cacheData;
            }
            var expirationTime = DateTimeOffset.Now.AddMinutes(5.0);
            cacheData = _dbContext.Products.ToList();
            _cacheService.SetData&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;("product", cacheData, expirationTime);
            return cacheData;
        }
        [HttpGet("product")]
        public Product Get(int id)
        {
            Product filteredData;
            var cacheData = _cacheService.GetData&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;("product");
            if (cacheData != null)
            {
                filteredData = cacheData.Where(x =&amp;gt; x.ProductId == id).FirstOrDefault();
                return filteredData;
            }
            filteredData = _dbContext.Products.Where(x =&amp;gt; x.ProductId == id).FirstOrDefault();
            return filteredData;
        }
        [HttpPost("addproduct")]
        public async Task&amp;lt;Product&amp;gt; Post(Product value)
        {
            var obj = await _dbContext.Products.AddAsync(value);
            _cacheService.RemoveData("product");
            _dbContext.SaveChanges();
            return obj.Entity;
        }
        [HttpPut("updateproduct")]
        public void Put(Product product)
        {
            _dbContext.Products.Update(product);
            _cacheService.RemoveData("product");
            _dbContext.SaveChanges();
        }
        [HttpDelete("deleteproduct")]
        public void Delete(int Id)
        {
            var filteredData = _dbContext.Products.Where(x =&amp;gt; x.ProductId == Id).FirstOrDefault();
            _dbContext.Remove(filteredData);
            _cacheService.RemoveData("product");
            _dbContext.SaveChanges();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 7)&lt;/p&gt;

&lt;p&gt;Add the SQL Server connection string and Redis URL inside appsetting.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "RedisURL": "127.0.0.1:6379",
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=Server;Initial Catalog=RedisCache;User Id=sa;Password=***;"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 8)&lt;/p&gt;

&lt;p&gt;Next, Register the ICacheService inside Configure Service method of Startup Class and also add some configuration related to Swagger to test our API endpoints&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using RedisCacheDemo.Cache;
using RedisCacheDemo.Data;
namespace RedisCacheDemo
{
    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.AddControllers();
            services.AddScoped&amp;lt;ICacheService, CacheService&amp;gt;();
            services.AddDbContext&amp;lt;DbContextClass&amp;gt;(options =&amp;gt;
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.AddSwaggerGen(c =&amp;gt;
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "RedisCacheDemo", Version = "v1" });
            });
        }
        // 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();
                app.UseSwagger();
                app.UseSwaggerUI(c =&amp;gt; c.SwaggerEndpoint("/swagger/v1/swagger.json", "RedisCacheDemo v1"));
            }
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =&amp;gt;
            {
                endpoints.MapControllers();
            });
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 9)&lt;/p&gt;

&lt;p&gt;Create one ConfigurationManger Class to configure app setting over there&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.Extensions.Configuration;
using System.IO;
namespace RedisCacheDemo
{
    static class ConfigurationManager
    {
        public static IConfiguration AppSetting { get; }
        static ConfigurationManager()
        {
            AppSetting = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json")
                    .Build();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 10)&lt;/p&gt;

&lt;p&gt;Next, Create Connection Helper Class for REDIS Connection&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using StackExchange.Redis;
using System;
namespace RedisCacheDemo.Cache
{
    public class ConnectionHelper
    {
        static ConnectionHelper()
        {
            ConnectionHelper.lazyConnection = new Lazy&amp;lt;ConnectionMultiplexer&amp;gt;(() =&amp;gt;
            {
                return ConnectionMultiplexer.Connect(ConfigurationManager.AppSetting["RedisURL"]);
            });
        }
        private static Lazy&amp;lt;ConnectionMultiplexer&amp;gt; lazyConnection;
        public static ConnectionMultiplexer Connection
        {
            get
            {
                return lazyConnection.Value;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 11)&lt;/p&gt;

&lt;p&gt;Perform Migration and Database Update for DB Creation using the following commands in Package Manager Console.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;add-migration “FirstMigration”&lt;br&gt;
update-database&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So, when you enter and execute this command it will generate a few things related to migration and create the database inside SQL Server as you put inside Connection String in the appsetting.json&lt;/p&gt;

&lt;p&gt;Step 12)&lt;/p&gt;

&lt;p&gt;Finally, run the application and add the data using swagger UI and then check how caching works inside products and product endpoint.&lt;/p&gt;

&lt;p&gt;Basically, I added cache into the product and products endpoints in the controller, as you see when the user wants to fetch data of all products then firstly it will check whether the data is present inside the Redis Cache or not and if it’s present inside the cache then return that data to the user and if the data is not present inside the cache, then it will fetch the data from database and also, set that into the cache. So next time user will get that from cache only and avoid hitting the database unnecessarily&lt;/p&gt;

&lt;p&gt;Also, when the user wants to fetch data from by using product id as you see in the controller in product second endpoint, we fetch data from cache of all products then filter using product id and if that will present then return to user from cache and not then fetch from database and return to the user after applying the filter.&lt;/p&gt;

&lt;p&gt;So, as you see inside the update, delete and post endpoint of the Product Controller then we use the remove method to remove the data of the product key which is present inside the cache. So, there are many scenarios and use of memory caches you can use as per your need and requirements. I just want to introduce the basics of the REDIS Cache and How it works inside the .NET Core that I covered here.&lt;/p&gt;

&lt;p&gt;Also, there is one scenario you need to take care of while using caching like suppose, there are two users using your application then the following scenarios will come&lt;/p&gt;

&lt;p&gt;When the First User sends the request to fetch the data of all products then the first request comes and then it will check if the data is present inside the cache or not and if the data is present inside the cache, then it will fetch the data from and database and also set it to the cache.&lt;br&gt;
Meanwhile, the Second user sends the request to get the product details then what happened is that request also hits the database before completing the first user’s request and because of that second user also hit the database to fetch product details.&lt;br&gt;
So, there is one solution for this to use the Lock Mechanism as shown below&lt;br&gt;
Create this private object of lock on top of the class&lt;/p&gt;

&lt;p&gt;&lt;code&gt;private static object _lock = new object()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, Modify the Get method as I showed below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public IEnumerable&amp;lt;Product&amp;gt; Get()
{
    var cacheData = _cacheService.GetData&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;("product");
    if (cacheData != null)
    {
        return cacheData;
    }
    lock (_lock)
    {
        var expirationTime = DateTimeOffset.Now.AddMinutes(5.0);
        cacheData = _dbContext.Products.ToList();
        _cacheService.SetData&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;("product", cacheData, expirationTime);
    }
    return cacheData;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So here as you see first, we check if the data is present inside the cache or not if data is available then return that. Next, if the value is not present in the REDIS cache, then we apply the lock over there and then the request is locked and entered into the section and fetch the product details from the database, and then also set it to the cache and then returns the data. So, what happened when the second user sends a request before the user one’s request is complete. So, in that case, the second request is in the queue and after completing the first user request the second request comes into the picture&lt;/p&gt;

&lt;p&gt;Also, you can see key details which already present inside REDIS using REDIS CLI as shown below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eihphzRk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yvf6gf20ala0s02jmqh8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eihphzRk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yvf6gf20ala0s02jmqh8.png" alt="Image description" width="766" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, here you can see there are many commands which provide us information about keys that are present in the REDIS Cache.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Link
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Jaydeep-007/RedisCacheDemo"&gt;https://github.com/Jaydeep-007/RedisCacheDemo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is all about REDIS Cache in .NET Core. I hope you understand things related to that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Coding!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>dotnetcore</category>
      <category>csharp</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Implement In-Memory Cache in the NET Core API</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Sun, 19 Feb 2023 07:38:49 +0000</pubDate>
      <link>https://dev.to/jaydeep007/implement-in-memory-cache-in-the-net-core-api-1c30</link>
      <guid>https://dev.to/jaydeep007/implement-in-memory-cache-in-the-net-core-api-1c30</guid>
      <description>&lt;p&gt;We are going to discuss Caching in .NET Core and How it works. So, we look at the following things one by one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduction of Caching&lt;/li&gt;
&lt;li&gt;What is Cache&lt;/li&gt;
&lt;li&gt;Types of cache&lt;/li&gt;
&lt;li&gt;Cache Implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, Let’s start one by one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Caching is very popular nowadays in the software industry because it will improve the performance and scalability of the application, as we use and see many web applications like g-mail and Facebook and how responsive they are and great user experience while we using that. There are a lot of users using the internet and if an application has huge network traffic and demand and due that we need to take care of many things which help us to improve the performance and responsiveness of the application. So, because of that, there is one of the solutions is caching and that’s why caching comes into the picture.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Caching?
&lt;/h2&gt;

&lt;p&gt;The cache is the memory storage that is used to store the frequent access data into the temporary storage, it will improve the performance drastically and avoid the unnecessary database hit and store frequently used data into the buffer whenever we need it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eTwZFQlC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzeryxnkrpqgouskgbmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eTwZFQlC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gzeryxnkrpqgouskgbmd.png" alt="Image description" width="531" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nAZK6qzG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9q5jhvab7r686hu1dkd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nAZK6qzG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9q5jhvab7r686hu1dkd.png" alt="Image description" width="531" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you see in the above image there are two scenarios one is without using cache and another is with cache and how it works, So here when we do not use the cache, in that case, suppose users want data then they will hit each time database and it will increase the time complexity and reduce performance in case there is some static data users want and it is same for all user, in that case when we do not use cache then each one hit the unnecessary database to fetch data and on the other side as you can see we use cache and in that case if there same static and same data for all users then only the first user will hit the database and fetch data and store it into the cache memory and then other two users used that from the cache without unnecessarily hit database to fetch data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Cache
&lt;/h2&gt;

&lt;p&gt;Basically, there are two types of caching .NET Core supports&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In-Memory Caching&lt;/li&gt;
&lt;li&gt;Distributed Caching&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When we use In-Memory Cache then in that case data is stored in the application server memory and whenever we need then we fetch data from that and use it wherever we need it. And in Distributed Caching there are many third-party mechanisms like Redis and many others. But in this section, we look into the In-Memory Cache in detail and how it works in the .NET Core&lt;/p&gt;

&lt;h2&gt;
  
  
  In-Memory Cache
&lt;/h2&gt;

&lt;p&gt;Basically, In-Memory Cache is used for lightweight and small applications and that will work well in that. it stores data into the server memory on the application side and users used that whenever need that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of In-Memory Cache
&lt;/h2&gt;

&lt;p&gt;Users fetch data rapidly when we use In-Memory Cache.&lt;br&gt;
It will increase the performance of the application.&lt;br&gt;
Best suited for small application which is deployed on a single server.&lt;/p&gt;
&lt;h2&gt;
  
  
  Disadvantages of In-Memory Cache
&lt;/h2&gt;

&lt;p&gt;Sometimes In-Memory cache increases the maintenance of the application&lt;br&gt;
In the In-Memory Cache data is persisted on a single server and if the server will crash then data is lost also it’s hard to scale the application in some scenarios.&lt;br&gt;
Now we are going to create one .NET Core API Implement the caching into that and understand how things are going to work&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the .NET Core API Web Application&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install the following NuGet Packages which need step by step in our application&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Microsoft.EntityFrameworkCore&lt;br&gt;
Microsoft.EntityFrameworkCore.Design&lt;br&gt;
Microsoft.EntityFrameworkCore.SqlServer&lt;br&gt;
Microsoft.EntityFrameworkCore.Tools&lt;br&gt;
Swashbuckle.AspNetCore&lt;br&gt;
System.Runtime.Caching&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the Model folder and create one Product Class inside that with details&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace MemoryCacheDemo.Model
{
    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public string ProductDescription { get; set; }
        public int Stock { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, Create the DbContextClass Class for Database related operations as I have shown below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using MemoryCacheDemo.Model;
using Microsoft.EntityFrameworkCore;
namespace MemoryCacheDemo.Data
{
    public class DbContextClass: DbContext
    {
        public DbContextClass(DbContextOptions&amp;lt;DbContextClass&amp;gt; options) : base(options)
        {
        }
        public DbSet&amp;lt;Product&amp;gt; Products { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, we are going to create ICacheService Interface and CacheService Class for In-Memory Cache-related usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;
namespace MemoryCacheDemo.Cache
{
    public interface ICacheService
    {
        /// &amp;lt;summary&amp;gt;
        /// Get Data using key
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;
        /// &amp;lt;param name="key"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        T GetData&amp;lt;T&amp;gt;(string key);
        /// &amp;lt;summary&amp;gt;
        /// Set Data with Value and Expiration Time of Key
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;
        /// &amp;lt;param name="key"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="value"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;param name="expirationTime"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        bool SetData&amp;lt;T&amp;gt;(string key, T value, DateTimeOffset expirationTime);
        /// &amp;lt;summary&amp;gt;
        /// Remove Data
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="key"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        object RemoveData(string key);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, Create Cache Service&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Linq;
using System.Runtime.Caching;
namespace MemoryCacheDemo.Cache
{
    public class CacheService : ICacheService
    {
        ObjectCache _memoryCache = MemoryCache.Default;
        public T GetData&amp;lt;T&amp;gt;(string key)
        {
            try
            {
                T item = (T)_memoryCache.Get(key);
                return item;
            }
            catch (Exception e)
            {
                throw;
            }
        }
        public bool SetData&amp;lt;T&amp;gt;(string key, T value, DateTimeOffset expirationTime)
        {
            bool res = true;
            try
            {
                if (!string.IsNullOrEmpty(key))
                {
                    _memoryCache.Set(key, value, expirationTime);
                }
            }
            catch (Exception e)
            {
                throw;
            }
            return res;
        }
        public object RemoveData(string key)
        {
            try
            {
                if (!string.IsNullOrEmpty(key))
                {
                    return _memoryCache.Remove(key);
                }
            }
           catch(Exception e)
            {
                throw;
            }
            return false;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the ProductController class create the following method as shown below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using MemoryCacheDemo.Cache;
using MemoryCacheDemo.Data;
using MemoryCacheDemo.Model;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MemoryCacheDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductController : ControllerBase
    {
        private readonly DbContextClass _dbContext;
        private readonly ICacheService _cacheService;
        public ProductController(DbContextClass dbContext, ICacheService cacheService)
        {
            _dbContext = dbContext;
            _cacheService = cacheService;
        }
        [HttpGet("products")]
        public IEnumerable&amp;lt;Product&amp;gt; Get()
        {
            var cacheData = _cacheService.GetData&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;("product");
            if (cacheData!=null)
            {
                return cacheData;
            }
            var expirationTime = DateTimeOffset.Now.AddMinutes(5.0);
            cacheData = _dbContext.Products.ToList();
            _cacheService.SetData&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;("product", cacheData, expirationTime);
            return cacheData;
        }
        [HttpGet("product")]
        public Product Get(int id)
        {
            Product filteredData;
            var cacheData = _cacheService.GetData&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;("product");
            if (cacheData != null)
            {
                filteredData = cacheData.Where(x =&amp;gt; x.ProductId == id).FirstOrDefault();
                return filteredData;
            }
            filteredData = _dbContext.Products.Where(x =&amp;gt; x.ProductId == id).FirstOrDefault();
            return filteredData;
        }
        [HttpPost("addproduct")]
        public async Task&amp;lt;Product&amp;gt; Post(Product value)
        {
            var obj = await _dbContext.Products.AddAsync(value);
            _cacheService.RemoveData("product");
            _dbContext.SaveChanges();
            return obj.Entity;
        }
        [HttpPut("updateproduct")]
        public void Put(Product product)
        {
            _dbContext.Products.Update(product);
            _cacheService.RemoveData("product");
            _dbContext.SaveChanges();
        }
        [HttpDelete("deleteproduct")]
        public void Delete(int Id)
        {
            var filteredData = _dbContext.Products.Where(x =&amp;gt; x.ProductId == Id).FirstOrDefault();
            _dbContext.Remove(filteredData);
            _cacheService.RemoveData("product");
            _dbContext.SaveChanges();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 7)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add the SQL Server connection string inside appsetting.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=server;Initial Catalog=MemoryCache;User Id=****;Password=***;"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 8)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, Register the ICacheService inside Configure Service method of Startup Class and also add some configuration related to Swagger to test our API endpoints&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using MemoryCacheDemo.Cache;
using MemoryCacheDemo.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
namespace MemoryCacheDemo
{
    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.AddControllers();
            services.AddScoped&amp;lt;ICacheService, CacheService&amp;gt;();
            services.AddDbContext&amp;lt;DbContextClass&amp;gt;(options =&amp;gt;
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
            services.AddSwaggerGen(c =&amp;gt;
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "MemoryCacheDemo", Version = "v1" });
            });
        }
        // 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();
                app.UseSwagger();
                app.UseSwaggerUI(c =&amp;gt; c.SwaggerEndpoint("/swagger/v1/swagger.json", "MemoryCacheDemo v1"));
            }
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =&amp;gt;
            {
                endpoints.MapControllers();
            });
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 9)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Perform Migration and Database Update for DB Creation using the following commands in Package Manager Console.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;add-migration “FirstMigration”&lt;br&gt;
update-database&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So, when you enter and execute this command it will generate a few things related to migration and create the database inside SQL Server as you put inside Connection String in the appsetting.json&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, run the application and add the data using swagger UI and then check how caching works inside products and product endpoint.&lt;/p&gt;

&lt;p&gt;Basically, I added cache into the product and products endpoints in the controller, as you see when the user wants to fetch data of all products then firstly it will check whether the data is present inside the In-Memory Cache or not and if it’s present inside the cache then return that data to the user and if the data is not present inside the cache, then it will fetch the data from database and also, set that into the cache. So next time user will get that from cache only and avoid hitting the database unnecessarily&lt;/p&gt;

&lt;p&gt;Also, when the user wants to fetch data from by using product id as you see in the controller in product second endpoint, we fetch data from cache of all products then filter using product id and if that will present then return to user from cache and not then fetch from database and return to the user after applying the filter.&lt;/p&gt;

&lt;p&gt;So, as you see inside the update, delete and post endpoint of the Product Controller then we use the remove method to remove the data of product key which is present inside the cache. So, there are many scenarios and use of memory caches you can use as per your need and requirements. I just want to introduce the basics of the Memory Cache and How it works inside the .NET Core that I covered here.&lt;/p&gt;

&lt;p&gt;Also, there is one scenario you need to take care of while using caching like suppose, there are two users using your application then the following scenarios will come&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When the First User sends the request to fetch the data of all products then the first request comes and then it will check if the data is present inside the cache or not and if the data is present inside the cache, then it will fetch the data from and database and also set it to the cache.&lt;/li&gt;
&lt;li&gt;Meanwhile, the Second user sends the request to get the product details then what happened is that request also hits the database before completing the first user’s request and because of that second user also hit the database to fetch product details.&lt;/li&gt;
&lt;li&gt;So, there is one solution for this to use the Lock Mechanism as shown below&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add create a lock object top of the class and then in the method as I showed below&lt;/p&gt;

&lt;p&gt;&lt;code&gt;private static object _lock = new object();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, add the lock in Get Method&lt;/p&gt;

&lt;p&gt;&lt;code&gt;public IEnumerable&amp;lt;Product&amp;gt; Get()&lt;br&gt;
{&lt;br&gt;
    var cacheData = _cacheService.GetData&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;("product");&lt;br&gt;
    if (cacheData != null)&lt;br&gt;
    {&lt;br&gt;
        return cacheData;&lt;br&gt;
    }&lt;br&gt;
    lock (_lock)&lt;br&gt;
    {&lt;br&gt;
        var expirationTime = DateTimeOffset.Now.AddMinutes(5.0);&lt;br&gt;
        cacheData = _dbContext.Products.ToList();&lt;br&gt;
        _cacheService.SetData&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;("product", cacheData, expirationTime);&lt;br&gt;
    }&lt;br&gt;
    return cacheData;&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So here as you see first, we check if the data is present inside the cache or not if data is available then return that. Next, if the value is not present in the memory cache, then we apply the lock over there and then the request is locked and entered into the section and fetch the product details from the database, and then also set it to the cache and then return the data. So, what happened when the second user sends a request before the user one request is complete. So, in that case, the second request is in the queue and after completing the first user request the second request comes into the picture&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Link&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Jaydeep-007/MemoryCacheDemo"&gt;https://github.com/Jaydeep-007/MemoryCacheDemo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is all about In-Memory Cache in .NET Core. I hope you understand things related to that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Coding!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Apache Kafka Introduction, Installation, and Implementation Using .NET Core 6</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Sat, 04 Feb 2023 06:48:46 +0000</pubDate>
      <link>https://dev.to/jaydeep007/apache-kafka-introduction-installation-and-implementation-using-net-core-6-4p2f</link>
      <guid>https://dev.to/jaydeep007/apache-kafka-introduction-installation-and-implementation-using-net-core-6-4p2f</guid>
      <description>&lt;p&gt;We will go over Apache Kafka basics, installation, and operation, as well as step-by-step implementation using a.NET Core 6 Web Application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Overview of the Event Streaming&lt;/li&gt;
&lt;li&gt;Introduction of Apache Kafka&lt;/li&gt;
&lt;li&gt;Main concepts and foundation of Kafka&lt;/li&gt;
&lt;li&gt;Different Kafka APIs&lt;/li&gt;
&lt;li&gt;Use Cases of Apache Kafka&lt;/li&gt;
&lt;li&gt;Installation of Kafka on Windows 10&lt;/li&gt;
&lt;li&gt;Step-by-step implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visual Studio 2022&lt;/li&gt;
&lt;li&gt;.NET Core 6 SDK&lt;/li&gt;
&lt;li&gt;SQL Server&lt;/li&gt;
&lt;li&gt;Java JDK 11&lt;/li&gt;
&lt;li&gt;Apache Kafka&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overview of the Event Streaming
&lt;/h2&gt;

&lt;p&gt;Events are the things that happen within our application when we navigate something. Ex- We Sign up on any website and order something. So, these are the events.&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%2F6g99ll18l724nvbqdtcm.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%2F6g99ll18l724nvbqdtcm.png" alt="Image description" width="720" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event streaming platform records different types of data like transaction, historical, and real-time data.&lt;/li&gt;
&lt;li&gt;Also, this platform is used to process events and allow the different consumers to process results immediately and timely manner.&lt;/li&gt;
&lt;li&gt;An event-driven platform allows us to monitor our business and real-time data from different types of devices like IoT and many more, after analyzing it provides a good customer experience based on different types of events and needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction of Apache Kafka
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Kafka is a distributed event store and stream-processing platform.&lt;/li&gt;
&lt;li&gt;Kafka is an open source and is written in Java and Scala.&lt;/li&gt;
&lt;li&gt;The primary purpose to designed Kafka by Apache foundation is to handle real-time data feeds and provide high throughput and low latency platforms.&lt;/li&gt;
&lt;li&gt;Kafka is an event streaming platform that has many capabilities to publish(write) and subscribe to (read) streams of events from a different system.&lt;/li&gt;
&lt;li&gt;Also, to store and process events durably as long as we want, by default Kafka store event 7 days of the time period but we can increase that as per need and requirement.&lt;/li&gt;
&lt;/ul&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%2F5n0ueb1jsx3rfp23vm0f.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%2F5n0ueb1jsx3rfp23vm0f.png" alt="Image description" width="720" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kafka has distributed system which has servers and clients that can communicate via TCP protocol.&lt;/li&gt;
&lt;li&gt;It can be deployed on different virtual machines and containers in on-premise as well as cloud environments as per requirements.&lt;/li&gt;
&lt;li&gt;In the Kafka world, a producer sends messages to the Kafka broker. The messages will get stored inside the topics and the consumer subscribes to that topic to consume messages sent by the producer.&lt;/li&gt;
&lt;li&gt;Zookeeper is used to manage metadata of Kafka-related things. it tracks which brokers are part of the Kafka cluster and partitions of different topics. Also, manage the status of Kafka nodes and maintain a list of Kafka topics and a list of messages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Main concepts and foundation of Kafka
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Event&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An event or record is the message that we read and write to the Kafka server; we do this in the form of events in our business world, and it contains key, value, timestamp, and other metadata headers.&lt;/p&gt;

&lt;p&gt;Key: “Jaydeep”&lt;/p&gt;

&lt;p&gt;Value: “Booked BMW”&lt;/p&gt;

&lt;p&gt;Event Timestamp: “Dec. 11, 2022, at 12:00 p.m.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Producer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The producer is a client application that sends messages to the Kafka Node/Broker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Consumer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The consumer is an application that receives data from Kafka.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Kafka Cluster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Kafka cluster is the set of computers that share the workload with each other and serve some purpose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Broker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The broker is a Kafka server that acts as an agent between both the producer and consumer, who communicate via the broker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Topic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The events are stored inside the Topic it’s similar to our folder in which we store multiple files.&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%2Fm6ckv5cqmbzzln2hv3yu.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%2Fm6ckv5cqmbzzln2hv3yu.png" alt="Image description" width="720" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each topic has one or more producers and consumer which write and reads data from the topic.&lt;/li&gt;
&lt;li&gt;Events in topic we can read as often as needed it persists events and it’s not like another messaging system that removes messages after consuming that.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;7. Partitions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Topics are partitions, meaning the topic is spread over multiple partitions that we created inside the topic. When the producer sends some event to the topic, it will store it inside the particular partitions, and then the consumer can read the event from the corresponding topic partition in sequence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Offset&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kafka assigns one unique ID to the message stored inside the topic partition when the message arrives from the producer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Consumer Groups&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the Kafka world, the consumer group acts as a single logical unit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Replica&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Kafka, to make data fault-tolerant and highly available, we can replicate topics in different regions and brokers. So, in case something wrong happens with data in one topic we can easily get that from another where replicate the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Different Kafka APIs
&lt;/h2&gt;

&lt;p&gt;Kafka has five core APIs which serve different purposes&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Admin API&lt;/strong&gt;&lt;br&gt;
This API manages different topics, brokers, and Kafka objects&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Producer API&lt;/strong&gt;&lt;br&gt;
This API is used to write/publish events to different Kafka topics&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consumer API&lt;/strong&gt;&lt;br&gt;
This API is used to receive the different messages corresponding to the topics which are subscribed by the consumer&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kafka Stream API&lt;/strong&gt;&lt;br&gt;
This API is used to perform different types of operations like windowing, joins, aggregation, and many others. Basically, it uses to transform objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kafka Connect API&lt;/strong&gt;&lt;br&gt;
This API works as a connector to Kafka, which helps different systems connect with Kafka easily. It has different types of ready-to-use connectors related to Kafka.&lt;/p&gt;
&lt;h2&gt;
  
  
  Use Cases of Apache Kafka
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Messaging&lt;/li&gt;
&lt;li&gt;User Activity Tracking&lt;/li&gt;
&lt;li&gt;Log Aggregation&lt;/li&gt;
&lt;li&gt;Stream Processing&lt;/li&gt;
&lt;li&gt;Realtime Data Analytics&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Installation of Kafka on Windows 10
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Download and install the Java SDK of version 8 or more. (Note: I have Java 11 that’s why I put the same path in all commands which I used over here)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.oracle.com/java/technologies/downloads/#java8" rel="noopener noreferrer"&gt;https://www.oracle.com/java/technologies/downloads/#java8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open and install exe&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Set the environment variable for Java using the command prompt as admin.&lt;/p&gt;

&lt;p&gt;setx -m JAVA_HOME “C:\Program Files\Java\jdk-11.0.16.1”&lt;br&gt;
setx -m PATH “%JAVA_HOME%\bin;%PATH%”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After that, download and install Kafka&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kafka.apache.org/downloads" rel="noopener noreferrer"&gt;https://kafka.apache.org/downloads&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Extract the downloaded Kafka file at rename it as Kafka.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open D:\Kafka\config\ and create a zookeeper-data and kafka-logs folder inside that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, open D:\Kafka\config\zookeeper.properties file and add the folder path inside that.&lt;/p&gt;

&lt;p&gt;D:\Kafka\config\zookeeper.properties&lt;/p&gt;

&lt;p&gt;dataDir=D:/Kafka/zookeeper-data&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After that, open D:\Kafka\config\server.properties file and change the log path over there&lt;/p&gt;

&lt;p&gt;D:\Kafka\config\server.properties&lt;/p&gt;

&lt;p&gt;log.dirs=D:/Kafka/kafka-logs&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Saves and closes both files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run zookeeper&lt;/p&gt;

&lt;p&gt;D:\Kafka&amp;gt; .\bin\windows\zookeeper-server-start.bat .\config\zookeeper.properties&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%2Fjdutkr0du7pkai90jylb.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%2Fjdutkr0du7pkai90jylb.png" alt="Image description" width="720" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 11&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Start Kafka&lt;/p&gt;

&lt;p&gt;D:\Kafka&amp;gt; .\bin\windows\kafka-server-start.bat .\config\server.properties&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%2F9p3a6d1t0rrhb45xo8uo.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%2F9p3a6d1t0rrhb45xo8uo.png" alt="Image description" width="720" height="139"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 12&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create Kafka Topic&lt;/p&gt;

&lt;p&gt;D:\Kafka\bin\windows&amp;gt;kafka-topics.bat — create — bootstrap-server localhost:9092 — replication-factor 1 — partitions 1 — topic testdata&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%2F5ps3n6pxhqhylm1h9zms.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%2F5ps3n6pxhqhylm1h9zms.png" alt="Image description" width="720" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 13&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a producer and send some messages after you've started both a producer and a consumer.&lt;/p&gt;

&lt;p&gt;D:\Kafka\bin\windows&amp;gt;kafka-console-producer.bat — broker-list localhost:9092 — topic testdata&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%2Fpfgg3ww8mqvu9sitdgl6.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%2Fpfgg3ww8mqvu9sitdgl6.png" alt="Image description" width="720" height="114"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 14&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, Create a Consumer and you can see a message when the producer sent.&lt;/p&gt;

&lt;p&gt;D:\Kafka\bin\windows&amp;gt;kafka-console-consumer.bat — bootstrap-server localhost:9092 — topic testdata&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%2Ffnj95asdg7au30napkwd.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%2Ffnj95asdg7au30napkwd.png" alt="Image description" width="720" height="107"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step-by-step implementation
&lt;/h2&gt;

&lt;p&gt;Let’s start with practical implementation&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new .NET Core Producer Web API&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%2Fhgbaqntwa7getak85kfe.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%2Fhgbaqntwa7getak85kfe.png" alt="Image description" width="720" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Configure your application&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%2Fz0wrny0wwkro0qjtai8i.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%2Fz0wrny0wwkro0qjtai8i.png" alt="Image description" width="705" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Provide additional details&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%2Ff6zjahg9k2l6yypnn298.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%2Ff6zjahg9k2l6yypnn298.png" alt="Image description" width="685" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install the following two NuGet packages&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%2F5nznkdedxn9iy89po2xm.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%2F5nznkdedxn9iy89po2xm.png" alt="Image description" width="546" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add configuration details inside the appsettings.json file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "producerconfiguration": {
    "bootstrapservers": "localhost:9092"
  },
  "TopicName": "testdata"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Register a few services inside the Program class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Confluent.Kafka;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var producerConfiguration = new ProducerConfig();
builder.Configuration.Bind("producerconfiguration", producerConfiguration);

builder.Services.AddSingleton&amp;lt;ProducerConfig&amp;gt;(producerConfiguration);

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 7&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, Create CarDetails model class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Authentication;

namespace ProducerApplication.Models
{
    public class CarDetails
    {
        public int CarId { get; set; }
        public string CarName { get; set; }
        public string BookingStatus { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create CarsController&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Confluent.Kafka;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using ProducerApplication.Models;

namespace ProducerApplication.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CarsController : ControllerBase
    {
        private ProducerConfig _configuration;
        private readonly IConfiguration _config;
        public CarsController(ProducerConfig configuration, IConfiguration config)
        {
            _configuration = configuration;
            _config = config;
        }
        [HttpPost("sendBookingDetails")]
        public async Task&amp;lt;ActionResult&amp;gt; Get([FromBody] CarDetails employee)
        {
            string serializedData = JsonConvert.SerializeObject(employee);

            var topic = _config.GetSection("TopicName").Value;

            using (var producer = new ProducerBuilder&amp;lt;Null, string&amp;gt;(_configuration).Build())
            {
                await producer.ProduceAsync(topic, new Message&amp;lt;Null, string&amp;gt; { Value = serializedData });
                producer.Flush(TimeSpan.FromSeconds(10));
                return Ok(true);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 9&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, run the application and send a message&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%2Falgcr5ljcfy71nb6yodt.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%2Falgcr5ljcfy71nb6yodt.png" alt="Image description" width="557" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, create a Consumer application&lt;/p&gt;

&lt;p&gt;For that, Create a new .NET Core Console Application&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%2Fyekvch5qwfgxn2g4rz6g.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%2Fyekvch5qwfgxn2g4rz6g.png" alt="Image description" width="704" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 11&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Configure your application&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%2F4c9yxjykm888tzx053k1.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%2F4c9yxjykm888tzx053k1.png" alt="Image description" width="628" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 12&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Provide additional information&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%2Ftgzu8udl1vzqqnoxsxn1.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%2Ftgzu8udl1vzqqnoxsxn1.png" alt="Image description" width="593" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 13&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install this NuGet&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%2Fvqe1rtl482htr7o7qk8x.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%2Fvqe1rtl482htr7o7qk8x.png" alt="Image description" width="526" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 14&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add the following code which consumes messages sent by the consumer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Confluent.Kafka;

var config = new ConsumerConfig
{
    GroupId = "gid-consumers",
    BootstrapServers = "localhost:9092"
};

using (var consumer = new ConsumerBuilder&amp;lt;Null, string&amp;gt;(config).Build())
{
    consumer.Subscribe("testdata");
    while (true)
    {
        var bookingDetails = consumer.Consume();
        Console.WriteLine(bookingDetails.Message.Value);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 15&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, run both producer and consumer, sent a message using the producer app and you can see the message immediately inside the consumer console sent by the producer&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%2Fowi6oaz83n5qfv75191m.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%2Fowi6oaz83n5qfv75191m.png" alt="Image description" width="720" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub URL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Jaydeep-007/Kafka-Demo" rel="noopener noreferrer"&gt;https://github.com/Jaydeep-007/Kafka-Demo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Here we discussed Apache Kafka introduction, working, benefits, and step-by-step implementation using .NET Core 6.&lt;/p&gt;

&lt;h2&gt;
  
  
  Happy Coding!
&lt;/h2&gt;

</description>
      <category>devto</category>
      <category>announcement</category>
      <category>community</category>
    </item>
    <item>
      <title>Unit Of Work with Generic Repository implementation using .NET Core 6 Web API</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Thu, 26 Jan 2023 07:04:22 +0000</pubDate>
      <link>https://dev.to/jaydeep007/unit-of-work-with-generic-repository-implementation-using-net-core-6-web-api-1me6</link>
      <guid>https://dev.to/jaydeep007/unit-of-work-with-generic-repository-implementation-using-net-core-6-web-api-1me6</guid>
      <description>&lt;p&gt;We are going to discuss the Unit of work design pattern with the help of a generic repository and step-by-step implementation using .NET Core 6 Web API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;p&gt;Repository Pattern&lt;br&gt;
Unit of Work&lt;br&gt;
Step-by-step Implementation&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Visual Studio 2022&lt;br&gt;
SQL Server&lt;br&gt;
.NET Core 6 SDK&lt;/p&gt;
&lt;h2&gt;
  
  
  Repository Pattern
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The repository pattern is used to create an abstraction layer between the data access layer and the business layer of an application&lt;/li&gt;
&lt;li&gt;This pattern helps to reduce code duplication and follows the DRY principle.&lt;/li&gt;
&lt;li&gt;It also helps to create loose coupling between multiple components, when we want to change something inside the data access layer that time does not need to change another layer where we consume that functionality.&lt;/li&gt;
&lt;li&gt;Separation of concern makes things easier to maintain the code.&lt;/li&gt;
&lt;li&gt;Implementing repository patterns helps us write unit test cases efficiently and easily.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Unit of Work
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Repository pattern helps us create an abstraction, decouple the code, and avoid redundant code.&lt;/li&gt;
&lt;/ul&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%2F3h46jcdgtxjwu39wboxw.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%2F3h46jcdgtxjwu39wboxw.png" alt="Image description" width="635" height="615"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fig- diagram is from Microsoft technical documentation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;But sometimes it could partially update data because when the application is huge and repositories share the same database context throughout the application and perform operations like insert, update and read. So, in that case, there might be a chance fail some transactions and few are executed successfully due to concurrency issues. So, for this reason, we use a unit of work to maintain the data integrity inside the application.&lt;/li&gt;
&lt;li&gt;Also, the unit of work manages an in-memory database when we perform CRUD operations on some entity classes as one transaction and if there are some database operations will fail then that case all operations will roll back.&lt;/li&gt;
&lt;li&gt;It also helps to make layers loosely coupled using dependency injection and follow Test Driven Development (TDD) principles.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step-by-step Implementation
&lt;/h2&gt;

&lt;p&gt;Step 1&lt;/p&gt;

&lt;p&gt;Create a new .NET Core Web API&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%2Fhsp8hwmw75sybbp8rswl.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%2Fhsp8hwmw75sybbp8rswl.png" alt="Image description" width="720" height="322"&gt;&lt;/a&gt;&lt;br&gt;
Step 2&lt;/p&gt;

&lt;p&gt;Configure your application&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%2Fiw3onuzceylqy3wai3ja.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%2Fiw3onuzceylqy3wai3ja.png" alt="Image description" width="720" height="353"&gt;&lt;/a&gt;&lt;br&gt;
Step 3&lt;/p&gt;

&lt;p&gt;Provide some additional details&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%2Fq6h7fzzn3piqkublwflu.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%2Fq6h7fzzn3piqkublwflu.png" alt="Image description" width="679" height="416"&gt;&lt;/a&gt;&lt;br&gt;
Project Structure&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%2Fs6m2g4a0kiywixm34xz7.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%2Fs6m2g4a0kiywixm34xz7.png" alt="Image description" width="349" height="483"&gt;&lt;/a&gt;&lt;br&gt;
Step 4&lt;/p&gt;

&lt;p&gt;Create three class library projects inside the main solution&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%2F9ii535a2vqjm1mrdvzgl.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%2F9ii535a2vqjm1mrdvzgl.png" alt="Image description" width="296" height="105"&gt;&lt;/a&gt;&lt;br&gt;
Step 5&lt;/p&gt;

&lt;p&gt;Next, add one model class inside the UnitOfWorkDemo.Core project and also add some interfaces.&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%2F3ufpbvvv5lqrw9wjt0xt.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%2F3ufpbvvv5lqrw9wjt0xt.png" alt="Image description" width="230" height="150"&gt;&lt;/a&gt;&lt;br&gt;
ProductDetails.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace UnitOfWorkDemo.Core.Models
{
    public class ProductDetails
    {
        public int Id { get; set; }
        public string ProductName { get; set; }
        public string ProductDescription { get; set; }
        public int ProductPrice { get; set; }
        public int ProductStock { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IGenericRepository.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UnitOfWorkDemo.Core.Interfaces
{
    public interface IGenericRepository&amp;lt;T&amp;gt; where T : class
    {
        Task&amp;lt;T&amp;gt; GetById(int id);
        Task&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt; GetAll();
        Task Add(T entity);
        void Delete(T entity);
        void Update(T entity);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IProductRepository.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using UnitOfWorkDemo.Core.Models;

namespace UnitOfWorkDemo.Core.Interfaces
{
    public interface IProductRepository : IGenericRepository&amp;lt;ProductDetails&amp;gt;
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IUnitOfWork.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace UnitOfWorkDemo.Core.Interfaces
{
    public interface IUnitOfWork : IDisposable
    {
        IProductRepository Products { get; }

        int Save();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6&lt;/p&gt;

&lt;p&gt;Now, we are going to add an implementation of all repositories that we created earlier and also create one DbContextClass inside that.&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%2Fupqzahwpocxas5c5asae.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%2Fupqzahwpocxas5c5asae.png" alt="Image description" width="241" height="188"&gt;&lt;/a&gt;&lt;br&gt;
Project file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Project Sdk="Microsoft.NET.Sdk"&amp;gt;

  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;TargetFramework&amp;gt;net6.0&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;ImplicitUsings&amp;gt;enable&amp;lt;/ImplicitUsings&amp;gt;
    &amp;lt;Nullable&amp;gt;enable&amp;lt;/Nullable&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;ProjectReference Include="..\UnitOfWorkDemo.Core\UnitOfWorkDemo.Core.csproj" /&amp;gt;
    &amp;lt;PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.8" /&amp;gt;
    &amp;lt;PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.8" /&amp;gt;
    &amp;lt;PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.8" /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;

&amp;lt;/Project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GenericRepository.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnitOfWorkDemo.Core.Interfaces;

namespace UnitOfWorkDemo.Infrastructure.Repositories
{
    public abstract class GenericRepository&amp;lt;T&amp;gt; : IGenericRepository&amp;lt;T&amp;gt; where T : class
    {
        protected readonly DbContextClass _dbContext;

        protected GenericRepository(DbContextClass context)
        {
            _dbContext = context;
        }

        public async Task&amp;lt;T&amp;gt; GetById(int id)
        {
            return await _dbContext.Set&amp;lt;T&amp;gt;().FindAsync(id);
        }

        public async Task&amp;lt;IEnumerable&amp;lt;T&amp;gt;&amp;gt; GetAll()
        {
            return await _dbContext.Set&amp;lt;T&amp;gt;().ToListAsync();
        }

        public async Task Add(T entity)
        {
            await _dbContext.Set&amp;lt;T&amp;gt;().AddAsync(entity);
        }

        public void Delete(T entity)
        {
            _dbContext.Set&amp;lt;T&amp;gt;().Remove(entity);
        }

        public void Update(T entity)
        {
            _dbContext.Set&amp;lt;T&amp;gt;().Update(entity);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ProductRepository.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using UnitOfWorkDemo.Core.Interfaces;
using UnitOfWorkDemo.Core.Models;

namespace UnitOfWorkDemo.Infrastructure.Repositories
{
    public class ProductRepository : GenericRepository&amp;lt;ProductDetails&amp;gt;, IProductRepository
    {
        public ProductRepository(DbContextClass dbContext) : base(dbContext)
        {

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

&lt;/div&gt;



&lt;p&gt;UnitOfWork.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnitOfWorkDemo.Core.Interfaces;

namespace UnitOfWorkDemo.Infrastructure.Repositories
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly DbContextClass _dbContext;
        public IProductRepository Products { get; }

        public UnitOfWork(DbContextClass dbContext,
                            IProductRepository productRepository)
        {
            _dbContext = dbContext;
            Products = productRepository;
        }

        public int Save()
        {
            return _dbContext.SaveChanges();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                _dbContext.Dispose();
            }
        }

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

&lt;/div&gt;



&lt;p&gt;DbContextClass.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnitOfWorkDemo.Core.Models;

namespace UnitOfWorkDemo.Infrastructure
{
    public class DbContextClass : DbContext
    {
        public DbContextClass(DbContextOptions&amp;lt;DbContextClass&amp;gt; contextOptions) : base(contextOptions)
        {

        }

        public DbSet&amp;lt;ProductDetails&amp;gt; Products { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, create one extension class for which we are used to registering DI services, and configure that inside the Program.cs file inside the root project.&lt;/p&gt;

&lt;p&gt;ServiceExtension.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnitOfWorkDemo.Core.Interfaces;
using UnitOfWorkDemo.Infrastructure.Repositories;

namespace UnitOfWorkDemo.Infrastructure.ServiceExtension
{
    public static class ServiceExtension
    {
        public static IServiceCollection AddDIServices(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddDbContext&amp;lt;DbContextClass&amp;gt;(options =&amp;gt;
            {
                options.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
            });
            services.AddScoped&amp;lt;IUnitOfWork, UnitOfWork&amp;gt;();
            services.AddScoped&amp;lt;IProductRepository, ProductRepository&amp;gt;();

            return services;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, add migration and update the database inside the infrastructure project using the following command&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;add-migration “v1”&lt;br&gt;
update-database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Step 5&lt;/p&gt;

&lt;p&gt;Next, create a product service inside the Services project which we inject and consume inside the main controller&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%2F2ibhjrmnan4ahw7n6chs.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%2F2ibhjrmnan4ahw7n6chs.png" alt="Image description" width="206" height="101"&gt;&lt;/a&gt;&lt;br&gt;
IProductService.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnitOfWorkDemo.Core.Models;

namespace UnitOfWorkDemo.Services.Interfaces
{
    public interface IProductService
    {
        Task&amp;lt;bool&amp;gt; CreateProduct(ProductDetails productDetails);

        Task&amp;lt;IEnumerable&amp;lt;ProductDetails&amp;gt;&amp;gt; GetAllProducts();

        Task&amp;lt;ProductDetails&amp;gt; GetProductById(int productId);

        Task&amp;lt;bool&amp;gt; UpdateProduct(ProductDetails productDetails);

        Task&amp;lt;bool&amp;gt; DeleteProduct(int productId);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ProductService.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnitOfWorkDemo.Core.Interfaces;
using UnitOfWorkDemo.Core.Models;
using UnitOfWorkDemo.Services.Interfaces;

namespace UnitOfWorkDemo.Services
{
    public class ProductService : IProductService
    {
        public IUnitOfWork _unitOfWork;

        public ProductService(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public async Task&amp;lt;bool&amp;gt; CreateProduct(ProductDetails productDetails)
        {
            if (productDetails != null)
            {
                await _unitOfWork.Products.Add(productDetails);

                var result = _unitOfWork.Save();

                if (result &amp;gt; 0)
                    return true;
                else
                    return false;
            }
            return false;
        }

        public async Task&amp;lt;bool&amp;gt; DeleteProduct(int productId)
        {
            if (productId &amp;gt; 0)
            {
                var productDetails = await _unitOfWork.Products.GetById(productId);
                if (productDetails != null)
                {
                    _unitOfWork.Products.Delete(productDetails);
                    var result = _unitOfWork.Save();

                    if (result &amp;gt; 0)
                        return true;
                    else
                        return false;
                }
            }
            return false;
        }

        public async Task&amp;lt;IEnumerable&amp;lt;ProductDetails&amp;gt;&amp;gt; GetAllProducts()
        {
            var productDetailsList = await _unitOfWork.Products.GetAll();
            return productDetailsList;
        }

        public async Task&amp;lt;ProductDetails&amp;gt; GetProductById(int productId)
        {
            if (productId &amp;gt; 0)
            {
                var productDetails = await _unitOfWork.Products.GetById(productId);
                if (productDetails != null)
                {
                    return productDetails;
                }
            }
            return null;
        }

        public async Task&amp;lt;bool&amp;gt; UpdateProduct(ProductDetails productDetails)
        {
            if (productDetails != null)
            {
                var product = await _unitOfWork.Products.GetById(productDetails.Id);
                if(product != null)
                {
                    product.ProductName= productDetails.ProductName;
                    product.ProductDescription= productDetails.ProductDescription;
                    product.ProductPrice= productDetails.ProductPrice;
                    product.ProductStock= productDetails.ProductStock;

                    _unitOfWork.Products.Update(product);

                    var result = _unitOfWork.Save();

                    if (result &amp;gt; 0)
                        return true;
                    else
                        return false;
                }
            }
            return false;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6&lt;/p&gt;

&lt;p&gt;Now, we create a Products Controller inside the main project and add multiple endpoints.&lt;/p&gt;

&lt;p&gt;ProductsController.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Mvc;
using UnitOfWorkDemo.Core.Models;
using UnitOfWorkDemo.Services.Interfaces;

namespace UnitOfWorkDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {
        public readonly IProductService _productService;
        public ProductsController(IProductService productService)
        {
            _productService = productService;
        }

        /// &amp;lt;summary&amp;gt;
        /// Get the list of product
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        [HttpGet]
        public async Task&amp;lt;IActionResult&amp;gt; GetProductList()
        {
            var productDetailsList = await _productService.GetAllProducts();
            if(productDetailsList == null)
            {
                return NotFound();
            }
            return Ok(productDetailsList);
        }

        /// &amp;lt;summary&amp;gt;
        /// Get product by id
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="productId"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        [HttpGet("{productId}")]
        public async Task&amp;lt;IActionResult&amp;gt; GetProductById(int productId)
        {
            var productDetails = await _productService.GetProductById(productId);

            if (productDetails != null)
            {
                return Ok(productDetails);
            }
            else
            {
                return BadRequest();
            }
        }

        /// &amp;lt;summary&amp;gt;
        /// Add a new product
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="productDetails"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        [HttpPost]
        public async Task&amp;lt;IActionResult&amp;gt; CreateProduct(ProductDetails productDetails)
        {
            var isProductCreated = await _productService.CreateProduct(productDetails);

            if (isProductCreated)
            {
                return Ok(isProductCreated);
            }
            else
            {
                return BadRequest();
            }
        }

        /// &amp;lt;summary&amp;gt;
        /// Update the product
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="productDetails"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        [HttpPut]
        public async Task&amp;lt;IActionResult&amp;gt; UpdateProduct(ProductDetails productDetails)
        {
            if (productDetails != null)
            {
                var isProductCreated = await _productService.UpdateProduct(productDetails);
                if (isProductCreated)
                {
                    return Ok(isProductCreated);
                }
                return BadRequest();
            }
            else
            {
                return BadRequest();
            }
        }

        /// &amp;lt;summary&amp;gt;
        /// Delete product by id
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="productId"&amp;gt;&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
        [HttpDelete("{productId}")]
        public async Task&amp;lt;IActionResult&amp;gt; DeleteProduct(int productId)
        {
            var isProductCreated = await _productService.DeleteProduct(productId);

            if (isProductCreated)
            {
                return Ok(isProductCreated);
            }
            else
            {
                return BadRequest();
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, add a database connection string inside the appsetting.json file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=DESKTOP;Initial Catalog=UnitOfWorkDemoDB;User Id=sa;Password=database;"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, register some services inside the Program class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using UnitOfWorkDemo.Infrastructure.ServiceExtension;
using UnitOfWorkDemo.Services;
using UnitOfWorkDemo.Services.Interfaces;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddDIServices(builder.Configuration);
builder.Services.AddScoped&amp;lt;IProductService, ProductService&amp;gt;();

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, run the project&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%2Fya2zfjyz1ro602vxuy16.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%2Fya2zfjyz1ro602vxuy16.png" alt="Image description" width="720" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub URL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Jaydeep-007/UnitOfWorkDemo" rel="noopener noreferrer"&gt;https://github.com/Jaydeep-007/UnitOfWorkDemo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Here we discussed repository patterns and units of work. also, the benefits and step-by-step implementation using .NET Core Web API.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>CQRS and MediatR Pattern Implementation Using .NET Core 6 Web API</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Thu, 26 Jan 2023 06:54:25 +0000</pubDate>
      <link>https://dev.to/jaydeep007/cqrs-and-mediatr-pattern-implementation-using-net-core-6-web-api-38mb</link>
      <guid>https://dev.to/jaydeep007/cqrs-and-mediatr-pattern-implementation-using-net-core-6-web-api-38mb</guid>
      <description>&lt;p&gt;In this article, we are going to discuss the working of CQRS and MediatR patterns and step-by-step implementation using .NET Core 6 Web API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;p&gt;Introduction of CQRS Pattern&lt;br&gt;
When to use CQRS&lt;br&gt;
MediatR&lt;br&gt;
Step-by-step Implementation&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Visual Studio 2022&lt;br&gt;
SQL Server&lt;br&gt;
.NET Core 6&lt;/p&gt;
&lt;h2&gt;
  
  
  Introduction of CQRS Pattern
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;CQRS stands for Command and Query Responsibility Segregation and uses to separate read(queries) and write(commands).&lt;/li&gt;
&lt;li&gt;In that, queries perform read operation, and command perform writes operation like create, update, delete, and return data.&lt;/li&gt;
&lt;/ul&gt;

&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%2Fgw6m0j475j3lul7pi2qy.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%2Fgw6m0j475j3lul7pi2qy.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As we know, in our application we mostly use a single data model to read and write data, which will work fine and perform CRUD operations easily. But, when the application becomes a vast in that case, our queries return different types of data as an object so that become hard to manage with different DTO objects. Also, the same model is used to perform a write operation. As a result, the model becomes complex.&lt;/li&gt;
&lt;li&gt;Also, when we use the same model for both reads and write operations the security is also hard to manage when the application is large and the entity might expose data in the wrong context due to the workload on the same model.&lt;/li&gt;
&lt;li&gt;CQRS helps to decouple operations and make the application more scalable and flexible on large scale.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  When to use CQRS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;We can use Command Query Responsibility Segregation when the application is huge and access the same data in parallel. CQRS helps reduce merge conflicts while performing multiple operations with data.&lt;/li&gt;
&lt;li&gt;In DDD terminology, if the domain data model is complex and needs to perform many operations on priority like validations and executing some business logic so in that case, we need the consistency that we will by using CQRS.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  MediatR
&lt;/h2&gt;

&lt;p&gt;MediatR pattern helps to reduce direct dependency between multiple objects and make them collaborative through MediatR.&lt;br&gt;
In .NET Core MediatR provides classes that help to communicate with multiple objects efficiently in a loosely coupled manner.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step-by-step Implementation
&lt;/h2&gt;

&lt;p&gt;Step 1&lt;/p&gt;

&lt;p&gt;Create a new application&lt;/p&gt;

&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%2Fwoaznhydvij0nq4zpxo9.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%2Fwoaznhydvij0nq4zpxo9.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Step 2&lt;/p&gt;

&lt;p&gt;Configure your application&lt;/p&gt;

&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%2Fye07yjaoqgyxeoac3q3f.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%2Fye07yjaoqgyxeoac3q3f.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Step 3&lt;/p&gt;

&lt;p&gt;Provide additional information&lt;/p&gt;

&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%2F4a4xmhbnkz2pqufi5ej3.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%2F4a4xmhbnkz2pqufi5ej3.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Step 4&lt;/p&gt;

&lt;p&gt;Project Structure&lt;/p&gt;

&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%2Fyi13tolxsu0nm00sx4hx.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%2Fyi13tolxsu0nm00sx4hx.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Step 5&lt;/p&gt;

&lt;p&gt;Install the Following NuGet Packages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Project Sdk="Microsoft.NET.Sdk.Web"&amp;gt;

  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;TargetFramework&amp;gt;net6.0&amp;lt;/TargetFramework&amp;gt;
    &amp;lt;Nullable&amp;gt;disable&amp;lt;/Nullable&amp;gt;
    &amp;lt;ImplicitUsings&amp;gt;enable&amp;lt;/ImplicitUsings&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;

  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="8.0.0" /&amp;gt;
    &amp;lt;PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.8" /&amp;gt;
    &amp;lt;PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.8"&amp;gt;
      &amp;lt;PrivateAssets&amp;gt;all&amp;lt;/PrivateAssets&amp;gt;
      &amp;lt;IncludeAssets&amp;gt;runtime; build; native; contentfiles; analyzers; buildtransitive&amp;lt;/IncludeAssets&amp;gt;
    &amp;lt;/PackageReference&amp;gt;
    &amp;lt;PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.8" /&amp;gt;
    &amp;lt;PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.8"&amp;gt;
      &amp;lt;PrivateAssets&amp;gt;all&amp;lt;/PrivateAssets&amp;gt;
      &amp;lt;IncludeAssets&amp;gt;runtime; build; native; contentfiles; analyzers; buildtransitive&amp;lt;/IncludeAssets&amp;gt;
    &amp;lt;/PackageReference&amp;gt;
    &amp;lt;PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;

&amp;lt;/Project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6&lt;/p&gt;

&lt;p&gt;Create a Student Details class inside the model folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace CQRSAndMediatRDemo.Models
{
    public class StudentDetails
    {
        public int Id { get; set; }
        public string StudentName { get; set; }
        public string StudentEmail { get; set; }
        public string StudentAddress { get; set; }
        public int StudentAge { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 7&lt;/p&gt;

&lt;p&gt;Next, add DbContextClass inside the Data folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Models;
using Microsoft.EntityFrameworkCore;

namespace CQRSAndMediatRDemo.Data
{
    public class DbContextClass : DbContext
    {
        protected readonly IConfiguration Configuration;

        public DbContextClass(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
        }

        public DbSet&amp;lt;StudentDetails&amp;gt; Students { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 8&lt;/p&gt;

&lt;p&gt;Create one student repository and a class related to that.&lt;/p&gt;

&lt;p&gt;IStudentRepository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Models;

namespace CQRSAndMediatRDemo.Repositories
{
    public interface IStudentRepository
    {
        public Task&amp;lt;List&amp;lt;StudentDetails&amp;gt;&amp;gt; GetStudentListAsync();
        public Task&amp;lt;StudentDetails&amp;gt; GetStudentByIdAsync(int Id);
        public Task&amp;lt;StudentDetails&amp;gt; AddStudentAsync(StudentDetails studentDetails);
        public Task&amp;lt;int&amp;gt; UpdateStudentAsync(StudentDetails studentDetails);
        public Task&amp;lt;int&amp;gt; DeleteStudentAsync(int Id);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;StudentRepository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Data;
using CQRSAndMediatRDemo.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Numerics;

namespace CQRSAndMediatRDemo.Repositories
{
    public class StudentRepository : IStudentRepository
    {
        private readonly DbContextClass _dbContext;

        public StudentRepository(DbContextClass dbContext)
        {
            _dbContext = dbContext;
        }

        public async Task&amp;lt;StudentDetails&amp;gt; AddStudentAsync(StudentDetails studentDetails)
        {
            var result = _dbContext.Students.Add(studentDetails);
            await _dbContext.SaveChangesAsync();
            return result.Entity;
        }

        public async Task&amp;lt;int&amp;gt; DeleteStudentAsync(int Id)
        {
            var filteredData = _dbContext.Students.Where(x =&amp;gt; x.Id == Id).FirstOrDefault();
            _dbContext.Students.Remove(filteredData);
            return await _dbContext.SaveChangesAsync();
        }

        public async Task&amp;lt;StudentDetails&amp;gt; GetStudentByIdAsync(int Id)
        {
            return await _dbContext.Students.Where(x =&amp;gt; x.Id == Id).FirstOrDefaultAsync();
        }

        public async Task&amp;lt;List&amp;lt;StudentDetails&amp;gt;&amp;gt; GetStudentListAsync()
        {
            return await _dbContext.Students.ToListAsync();
        }

        public async Task&amp;lt;int&amp;gt; UpdateStudentAsync(StudentDetails studentDetails)
        {
            _dbContext.Students.Update(studentDetails);
            return await _dbContext.SaveChangesAsync();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 9&lt;/p&gt;

&lt;p&gt;After that, add read queries&lt;/p&gt;

&lt;p&gt;GetStudentListQuery&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Models;
using MediatR;

namespace CQRSAndMediatRDemo.Queries
{
    public class GetStudentListQuery :  IRequest&amp;lt;List&amp;lt;StudentDetails&amp;gt;&amp;gt;
    {
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GetStudentByIdQuery&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Models;
using MediatR;

namespace CQRSAndMediatRDemo.Queries
{
    public class GetStudentByIdQuery : IRequest&amp;lt;StudentDetails&amp;gt;
    {
        public int Id { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 10&lt;/p&gt;

&lt;p&gt;Next, create different commands&lt;/p&gt;

&lt;p&gt;CreateStudentCommand&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Models;
using MediatR;

namespace CQRSAndMediatRDemo.Commands
{
    public class CreateStudentCommand : IRequest&amp;lt;StudentDetails&amp;gt;
    {
        public string StudentName { get; set; }
        public string StudentEmail { get; set; }
        public string StudentAddress { get; set; }
        public int StudentAge { get; set; }

        public CreateStudentCommand(string studentName, string studentEmail, string studentAddress, int studentAge)
        {
            StudentName = studentName;
            StudentEmail = studentEmail;
            StudentAddress = studentAddress;
            StudentAge = studentAge;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;UpdateStudentCommand&lt;br&gt;
&lt;/p&gt;

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

namespace CQRSAndMediatRDemo.Commands
{
    public class UpdateStudentCommand : IRequest&amp;lt;int&amp;gt;
    {
        public int Id { get; set; }
        public string StudentName { get; set; }
        public string StudentEmail { get; set; }
        public string StudentAddress { get; set; }
        public int StudentAge { get; set; }

        public UpdateStudentCommand(int id, string studentName, string studentEmail, string studentAddress, int studentAge)
        {
            Id = id;
            StudentName = studentName;
            StudentEmail = studentEmail;
            StudentAddress = studentAddress;
            StudentAge = studentAge;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DeleteStudentCommand&lt;br&gt;
&lt;/p&gt;

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

namespace CQRSAndMediatRDemo.Commands
{
    public class DeleteStudentCommand : IRequest&amp;lt;int&amp;gt;
    {
        public int Id { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 11&lt;/p&gt;

&lt;p&gt;Now, add Query and Command Handlers&lt;/p&gt;

&lt;p&gt;GetStudentListHandler&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Models;
using CQRSAndMediatRDemo.Queries;
using CQRSAndMediatRDemo.Repositories;
using MediatR;
using System.Numerics;

namespace CQRSAndMediatRDemo.Handlers
{
    public class GetStudentListHandler :  IRequestHandler&amp;lt;GetStudentListQuery, List&amp;lt;StudentDetails&amp;gt;&amp;gt;
    {
        private readonly IStudentRepository _studentRepository;

        public GetStudentListHandler(IStudentRepository studentRepository)
        {
            _studentRepository = studentRepository;
        }

        public async Task&amp;lt;List&amp;lt;StudentDetails&amp;gt;&amp;gt; Handle(GetStudentListQuery query, CancellationToken cancellationToken)
        {
            return await _studentRepository.GetStudentListAsync();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GetStudentByIdHandler&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Models;
using CQRSAndMediatRDemo.Queries;
using CQRSAndMediatRDemo.Repositories;
using MediatR;
using System.Numerics;

namespace CQRSAndMediatRDemo.Handlers
{
    public class GetStudentByIdHandler : IRequestHandler&amp;lt;GetStudentByIdQuery, StudentDetails&amp;gt;
    {
        private readonly IStudentRepository _studentRepository;

        public GetStudentByIdHandler(IStudentRepository studentRepository)
        {
            _studentRepository = studentRepository;
        }

        public async Task&amp;lt;StudentDetails&amp;gt; Handle(GetStudentByIdQuery query, CancellationToken cancellationToken)
        {
            return await _studentRepository.GetStudentByIdAsync(query.Id);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CreateStudentHandler&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Commands;
using CQRSAndMediatRDemo.Models;
using CQRSAndMediatRDemo.Repositories;
using MediatR;

namespace CQRSAndMediatRDemo.Handlers
{
    public class CreateStudentHandler: IRequestHandler&amp;lt;CreateStudentCommand, StudentDetails&amp;gt;
    {
        private readonly IStudentRepository _studentRepository;

        public CreateStudentHandler(IStudentRepository studentRepository)
        {
            _studentRepository = studentRepository;
        }
        public async Task&amp;lt;StudentDetails&amp;gt; Handle(CreateStudentCommand command, CancellationToken cancellationToken)
        {
            var studentDetails = new StudentDetails()
            {
                StudentName = command.StudentName,
                StudentEmail = command.StudentEmail,
                StudentAddress = command.StudentAddress,
                StudentAge = command.StudentAge
            };

            return await _studentRepository.AddStudentAsync(studentDetails);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;UpdateStudentHandler&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Commands;
using CQRSAndMediatRDemo.Repositories;
using MediatR;

namespace CQRSAndMediatRDemo.Handlers
{
    public class UpdateStudentHandler : IRequestHandler&amp;lt;UpdateStudentCommand, int&amp;gt;
    {
        private readonly IStudentRepository _studentRepository;

        public UpdateStudentHandler(IStudentRepository studentRepository)
        {
            _studentRepository = studentRepository;
        }
        public async Task&amp;lt;int&amp;gt; Handle(UpdateStudentCommand command, CancellationToken cancellationToken)
        {
            var studentDetails = await _studentRepository.GetStudentByIdAsync(command.Id);
            if (studentDetails == null)
                return default;

            studentDetails.StudentName = command.StudentName;
            studentDetails.StudentEmail = command.StudentEmail;
            studentDetails.StudentAddress = command.StudentAddress;
            studentDetails.StudentAge = command.StudentAge;

            return await _studentRepository.UpdateStudentAsync(studentDetails);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DeleteStudentHandler&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Commands;
using CQRSAndMediatRDemo.Repositories;
using MediatR;

namespace CQRSAndMediatRDemo.Handlers
{
    public class DeleteStudentHandler : IRequestHandler&amp;lt;DeleteStudentCommand, int&amp;gt;
    {
        private readonly IStudentRepository _studentRepository;

        public DeleteStudentHandler(IStudentRepository studentRepository)
        {
            _studentRepository = studentRepository;
        }

        public async Task&amp;lt;int&amp;gt; Handle(DeleteStudentCommand command, CancellationToken cancellationToken)
        {
            var studentDetails = await _studentRepository.GetStudentByIdAsync(command.Id);
            if (studentDetails == null)
                return default;

            return await _studentRepository.DeleteStudentAsync(studentDetails.Id);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 12&lt;/p&gt;

&lt;p&gt;Configure the database connection string inside the appsettings.json file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=DESKTOP-8RL8JOG;Initial Catalog=CQRSAndMediatRDemoDB;User Id=sa;Password=database@1;"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 13&lt;/p&gt;

&lt;p&gt;Register a few services inside the program class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Data;
using CQRSAndMediatRDemo.Repositories;
using MediatR;
using Microsoft.AspNetCore.Hosting;
using System.Reflection;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddMediatR(Assembly.GetExecutingAssembly());
builder.Services.AddDbContext&amp;lt;DbContextClass&amp;gt;();
builder.Services.AddScoped&amp;lt;IStudentRepository, StudentRepository&amp;gt;();

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 14&lt;/p&gt;

&lt;p&gt;Next, perform database migration and update commands&lt;/p&gt;

&lt;p&gt;add-migration “initial”&lt;br&gt;
update-database&lt;br&gt;
Step 15&lt;/p&gt;

&lt;p&gt;After that, create Students Controller and inject MediatR service inside that to send query and command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using CQRSAndMediatRDemo.Commands;
using CQRSAndMediatRDemo.Models;
using CQRSAndMediatRDemo.Queries;
using CQRSAndMediatRDemo.Repositories;
using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;

namespace CQRSAndMediatRDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class StudentsController : ControllerBase
    {
        private readonly IMediator mediator;

        public StudentsController(IMediator mediator)
        {
            this.mediator = mediator;
        }

        [HttpGet]
        public async Task&amp;lt;List&amp;lt;StudentDetails&amp;gt;&amp;gt; GetStudentListAsync()
        {
            var studentDetails = await mediator.Send(new GetStudentListQuery());

            return studentDetails;
        }

        [HttpGet("studentId")]
        public async Task&amp;lt;StudentDetails&amp;gt; GetStudentByIdAsync(int studentId)
        {
            var studentDetails = await mediator.Send(new GetStudentByIdQuery() { Id = studentId });

            return studentDetails;
        }

        [HttpPost]
        public async Task&amp;lt;StudentDetails&amp;gt; AddStudentAsync(StudentDetails studentDetails)
        {
            var studentDetail = await mediator.Send(new CreateStudentCommand(
                studentDetails.StudentName,
                studentDetails.StudentEmail,
                studentDetails.StudentAddress,
                studentDetails.StudentAge));
            return studentDetail;
        }

        [HttpPut]
        public async Task&amp;lt;int&amp;gt; UpdateStudentAsync(StudentDetails studentDetails)
        {
            var isStudentDetailUpdated = await mediator.Send(new UpdateStudentCommand(
               studentDetails.Id,
               studentDetails.StudentName,
               studentDetails.StudentEmail,
               studentDetails.StudentAddress,
               studentDetails.StudentAge));
            return isStudentDetailUpdated;
        }

        [HttpDelete]
        public async Task&amp;lt;int&amp;gt; DeleteStudentAsync(int Id)
        {
            return await mediator.Send(new DeleteStudentCommand() { Id = Id });
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 16&lt;/p&gt;

&lt;p&gt;Finally, run your application and access different endpoints using swagger UI.&lt;/p&gt;

&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%2F84s0ltv84ge926n5lov4.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%2F84s0ltv84ge926n5lov4.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub URL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Jaydeep-007/CQRSAndMediatRDemo.git" rel="noopener noreferrer"&gt;https://github.com/Jaydeep-007/CQRSAndMediatRDemo.git&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Here we discussed the CQRS and MediatR Design Patterns and their purpose and benefits in large-scale applications and step-by-step implementation using .NET Core Web API.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>dotnetcore</category>
      <category>designpatterns</category>
    </item>
    <item>
      <title>Minimal API using .NET Core 6 Web API</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Sat, 03 Dec 2022 06:00:00 +0000</pubDate>
      <link>https://dev.to/jaydeep007/minimal-api-using-net-core-6-web-api-18m9</link>
      <guid>https://dev.to/jaydeep007/minimal-api-using-net-core-6-web-api-18m9</guid>
      <description>&lt;p&gt;We will discuss minimal APIs in .NET Core 6, their purpose, and step-by-step implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;p&gt;Introduction&lt;br&gt;
Step-by-Step Implementation using .NET Core 6&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;.NET Core 6 SDK&lt;br&gt;
Visual Studio 2022&lt;br&gt;
SQL Server&lt;/p&gt;
&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Minimal APIs are used to create HTTP APIs with minimum dependencies and configuration.&lt;/li&gt;
&lt;li&gt;Mostly it is used in microservices that have fewer files and functionality within a single file&lt;/li&gt;
&lt;li&gt;But there are a few things that are not supported in minimal APIs like action filters, and built-in validation, also, a few more that are still in progress and will get in the future by .NET Team.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step-by-Step Implementation using .NET Core 6
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new .NET Core Web API&lt;/p&gt;

&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%2Fegvm73n1r3hgc3dp1wez.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%2Fegvm73n1r3hgc3dp1wez.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Configure your project&lt;/p&gt;

&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%2F753nazcb2kv3boxhjtx3.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%2F753nazcb2kv3boxhjtx3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Provide additional information as I showed below&lt;/p&gt;

&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%2F0pbpyjan2tax10nkuzgf.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%2F0pbpyjan2tax10nkuzgf.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install the following NuGet packages&lt;/p&gt;

&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%2F9elxfcnyvpflg48d7da5.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%2F9elxfcnyvpflg48d7da5.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project structure&lt;/strong&gt;&lt;/p&gt;

&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%2F04ymal4mzo5j99sxu5d6.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%2F04ymal4mzo5j99sxu5d6.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a Product class inside the entities folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace MinimalAPIsDemo.Entities
{
    public class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public string ProductDescription { get; set; }
        public int ProductPrice { get; set; }
        public int ProductStock { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, create DbContextClass inside the Data folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.EntityFrameworkCore;
using MinimalAPIsDemo.Entities;
namespace MinimalAPIsDemo.Data
{
    public class DbContextClass : DbContext
    {
        protected readonly IConfiguration Configuration;
        public DbContextClass(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
        }
        public DbSet&amp;lt;Product&amp;gt; Product { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 7&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Register the Db Context service in the DI container inside the Program class which is the entry point of our application&lt;/p&gt;

&lt;p&gt;&lt;code&gt;builder.Services.AddDbContext&amp;lt;DbContextClass&amp;gt;();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add database connection string inside the app settings file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=DESKTOP;Initial Catalog=MinimalAPIDemo;User Id=sa;Password=database;"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 9&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Later on, add different API endpoints inside the Program class with the help of Map and specified routing pattern as I showed below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.EntityFrameworkCore;
using MinimalAPIsDemo.Data;
using MinimalAPIsDemo.Entities;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddDbContext&amp;lt;DbContextClass&amp;gt;();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
//get the list of product
app.MapGet("/productlist", async (DbContextClass dbContext) =&amp;gt;
{
    var products = await dbContext.Product.ToListAsync();
    if (products == null)
    {
        return Results.NoContent();
    }
    return Results.Ok(products);
});
//get product by id
app.MapGet("/getproductbyid", async (int id, DbContextClass dbContext) =&amp;gt;
{
    var product = await dbContext.Product.FindAsync(id);
    if (product == null)
    {
        return Results.NotFound();
    }
    return Results.Ok(product);
});
//create a new product
app.MapPost("/createproduct", async (Product product, DbContextClass dbContext) =&amp;gt;
{
    var result = dbContext.Product.Add(product);
    await dbContext.SaveChangesAsync();
    return Results.Ok(result.Entity);
});
//update the product
app.MapPut("/updateproduct", async (Product product, DbContextClass dbContext) =&amp;gt;
{
    var productDetail = await dbContext.Product.FindAsync(product.ProductId);
    if (product == null)
    {
        return Results.NotFound();
    }
    productDetail.ProductName = product.ProductName;
    productDetail.ProductDescription = product.ProductDescription;
    productDetail.ProductPrice = product.ProductPrice;
    productDetail.ProductStock = product.ProductStock;
    await dbContext.SaveChangesAsync();
    return Results.Ok(productDetail);
});
//delete the product by id
app.MapDelete("/deleteproduct/{id}", async (int id, DbContextClass dbContext) =&amp;gt;
{
    var product = await dbContext.Product.FindAsync(id);
    if (product == null)
    {
        return Results.NoContent();
    }
    dbContext.Product.Remove(product);
    await dbContext.SaveChangesAsync();
    return Results.Ok();
});
app.Run();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 10&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following entity framework command to create migration and update the database&lt;/p&gt;

&lt;p&gt;&lt;code&gt;add-migration "initial"&lt;/code&gt;&lt;br&gt;
&lt;code&gt;update-database&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 11&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, run your application&lt;/p&gt;

&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%2F34fbtltdk8lzlvuu5c1f.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%2F34fbtltdk8lzlvuu5c1f.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub URL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Jaydeep-007/MinimalAPIsDemo" rel="noopener noreferrer"&gt;https://github.com/Jaydeep-007/MinimalAPIsDemo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Here we discussed the minimal APIs and things related to that using .NET Core 6 Web Application and Entity Framework with the help of SQL Server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Learning!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>webap</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Hosting .NET Core Web API image with Docker Compose over HTTPS</title>
      <dc:creator>Jaydeep Patil</dc:creator>
      <pubDate>Sat, 03 Dec 2022 05:40:20 +0000</pubDate>
      <link>https://dev.to/jaydeep007/hosting-net-core-web-api-image-with-docker-compose-over-https-dpb</link>
      <guid>https://dev.to/jaydeep007/hosting-net-core-web-api-image-with-docker-compose-over-https-dpb</guid>
      <description>&lt;p&gt;We are going to discuss here SSL Certificate configuration for secure communication over the HTTPS using .NET Core Web API and Docker after running our application inside the docker container using docker-compose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;p&gt;Introduction&lt;br&gt;
Implementation of .NET Core Web API Application&lt;br&gt;
Generate a certificate for secure communication&lt;br&gt;
Containerization of application&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Visual Studio 2022&lt;br&gt;
Docker Desktop&lt;br&gt;
.NET Core 6 SDK&lt;/p&gt;
&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;HTTPS is a standard internet protocol that makes the data to be encrypted and a more advanced and secure version of the HTTP protocol.&lt;/li&gt;
&lt;li&gt;SSL stands for Secure Sockets Layer and standard technology which keeps secure our application over the internet.&lt;/li&gt;
&lt;li&gt;SSL is the part of HTTPS protocol and it takes care of the encryption of data.&lt;/li&gt;
&lt;li&gt;It enables a secure connection and prevents hacker attacks because of its encryption algorithm and many security layers.&lt;/li&gt;
&lt;li&gt;Implementation of .NET Core Web API Application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new .NET Core Web API application&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UoKBP7En--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rlxz3jfz3lcrxzvj8uxa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UoKBP7En--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rlxz3jfz3lcrxzvj8uxa.png" alt="Image description" width="786" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Configure your application&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OeyVbjGB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2eo6an6i9md47mi12wu4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OeyVbjGB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2eo6an6i9md47mi12wu4.png" alt="Image description" width="669" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Provide additional information&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JXDhlXM---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4bbxkymkh2m9vtupvja7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JXDhlXM---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4bbxkymkh2m9vtupvja7.png" alt="Image description" width="667" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, we create a certificate for the local machine using the following command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\dockerdemo.pfx -p Pass@*****&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet dev-certs https --trust&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here as you can see, we pass the certificate name and password in the above command and it will create the certificate at %USERPROFILE%.aspnet\https this location&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hHsZ_rfL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dg23al4tcnfbov3bdnwk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hHsZ_rfL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dg23al4tcnfbov3bdnwk.png" alt="Image description" width="663" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a Docker file for our Weather Forecast application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /app
EXPOSE 443
EXPOSE 80
# copy project csproj file and restore it in docker directory
COPY ./*.csproj ./
RUN dotnet restore
# Copy everything into the docker directory and build
COPY . .
RUN dotnet publish -c Release -o out
# Build runtime final image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "HTTPSCertDemo.dll"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here using this command, you can create a docker image inside the docker desktop (Note: Make sure docker desktop is working fine on your machine)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build . -t ssldemo:v1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, we run our application after setting port and certificate details using docker volume.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -p 8081:80 -p 8082:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORT=7001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="Pass@*****" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/dockerdemo.pfx -v %USERPROFILE%\.aspnet\https:/https/ ssldemo:v1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here you can see we provide two ports one is for HTTPS and another one is for HTTPS, also some environmental variables like port, certificate path, and credentials along with docker volume (Note: docker volume is basically the shared directory which persists the data with docker container which is created by the user like in this case we create a certificate and it located at our local system)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Also, if we want to manage multiple docker images and their configuration efficiently, in that case, we can use the docker-compose file for managing all our application dynamic settings which we required when the application image is running inside the docker container for that we are going to create a docker-compose YAML file for the application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.5'
services:
  Weatherforecase.Service:
   image: ${DOCKER_REGISTRY-}ssldemo:v1
   build:
    context: ./HTTPSCertDemo
    dockerfile: Dockerfile
   environment:
    - ASPNETCORE_ENVIRONMENT=Development
    - ASPNETCORE_URLS=https://+:443;http://+:80
    - ASPNETCORE_Kestrel__Certificates__Default__Password=Pass@*****
    - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/dockerdemo.pfx
   ports:
    - "8081:80"
    - "8082:443"
   volumes:
    - ~/.aspnet/https:/https:ro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, you can see we provide different parameters with the help of environmental variables like docker image name, container name, certificate details, docker volume, and application port numbers&lt;br&gt;
To run your application using the docker-compose YAML file for that use the following commands&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose build&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here one command is going to build and create a docker image inside the docker desktop and another one runs your application image inside the docker container and configure all dynamic settings which you passed inside the YAML file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, in the docker desktop, you can see the application is running inside the docker container&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ws6kC85e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/037f75i0ivgaseh942r9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ws6kC85e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/037f75i0ivgaseh942r9.png" alt="Image description" width="786" height="263"&gt;&lt;/a&gt;&lt;br&gt;
Also, inside the visual studio, we can see the details of containers as shown in the below images&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OKZKdDAi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0s22pugfy1pdhu811z7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OKZKdDAi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0s22pugfy1pdhu811z7t.png" alt="Image description" width="758" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B4ndc1FE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s0361hhtw066z8xb8fjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B4ndc1FE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s0361hhtw066z8xb8fjl.png" alt="Image description" width="687" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ztaLh4ch--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a02cm0xjjf39i10dnj3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ztaLh4ch--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a02cm0xjjf39i10dnj3d.png" alt="Image description" width="759" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, open both application URLs and use the application&lt;/p&gt;

&lt;p&gt;&lt;a href="http://localhost:8081/swagger/index.html"&gt;http://localhost:8081/swagger/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EP1Le9ys--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/say7od2k2ah1dnyvc7uq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EP1Le9ys--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/say7od2k2ah1dnyvc7uq.png" alt="Image description" width="535" height="476"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://localhost:8082/swagger/index.html"&gt;https://localhost:8082/swagger/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ga0_-FE4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ot9vt7e9cg1mp6tkdt5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ga0_-FE4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ot9vt7e9cg1mp6tkdt5m.png" alt="Image description" width="603" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub URL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Jaydeep-007/HTTPSCertDemo.git"&gt;https://github.com/Jaydeep-007/HTTPSCertDemo.git&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In the article, we discussed HTTPS and how to enable that when we run applications inside the docker container using both ways, firstly using the docker command and secondly using the docker-compose file with the help of the .NET Core Weather forecast application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Learning!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>kubernetes</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
