<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ravindra Devrani</title><link>https://ravindradevrani.com/</link><description>Recent content on Ravindra Devrani</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 09 Mar 2026 16:08:51 +0530</lastBuildDate><atom:link href="https://ravindradevrani.com/index.xml" rel="self" type="application/rss+xml"/><item><title>How to Backup SQL Server Running in Docker on Linux</title><link>https://ravindradevrani.com/posts/sql_server_backup_in_docker_in_linux/</link><pubDate>Mon, 09 Mar 2026 16:08:51 +0530</pubDate><guid>https://ravindradevrani.com/posts/sql_server_backup_in_docker_in_linux/</guid><description>&lt;ul>
&lt;li>
&lt;p>I am using mssql server in docker container.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>I am using vscode extension named &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-mssql.mssql">SQL Server (mssql)&lt;/a> by &lt;strong>microsoft&lt;/strong>. This extension gives you the feature of creating and exporting the backup&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Connect to the database. It should look like this:
&lt;img src="https://ravindradevrani.com/images/mssql_vscode.jpg" alt="mssql vscode">&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Create a backup by using that extension.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://ravindradevrani.com/images/mssql_backup.jpg" alt="mssql backup">&lt;/p>
&lt;p>&lt;strong>Note:&lt;/strong> I have saved backup inside the folder &lt;code>/var/opt/mssql/data/&lt;/code>&lt;/p>
&lt;ul>
&lt;li>To find the exact name:&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>docker exec &amp;lt;container_name&amp;gt; ls /var/opt/mssql/data/*.bak
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>Copy backup from docker to host machine:&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>docker cp &amp;lt;container_name&amp;gt;:/var/opt/mssql/data/your_backup.bak ~/Documents/your_backup.bak
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Applying Project Level Vscode Settings with Angular</title><link>https://ravindradevrani.com/posts/applying-project-level-vscode-settings-in-angular/</link><pubDate>Wed, 18 Feb 2026 13:47:21 +0530</pubDate><guid>https://ravindradevrani.com/posts/applying-project-level-vscode-settings-in-angular/</guid><description>&lt;p>When you work with a team, everyone has their own preferences like double-quotes vs. single-quotes, trailing semicolon or not. If you want to decide a common code format that automatically applied. There are several ways which also comes with angular 21, like &lt;code>prettier&lt;/code>. But you need to run the command for that every time. It is a nice feature. But you can also format code on file save. For that you need to follow these two steps.&lt;/p></description></item><item><title>Various Learning Techniques</title><link>https://ravindradevrani.com/posts/various-learning-techniques/</link><pubDate>Tue, 17 Feb 2026 18:08:11 +0530</pubDate><guid>https://ravindradevrani.com/posts/various-learning-techniques/</guid><description>&lt;p>Today we are going explore some popular learning techniques briefly. Yes&amp;hellip; this post is not a regular technical blog post of this blog. But it might be helpful you are a &amp;ldquo;learner&amp;rdquo; (every programmer is a life long learner). I have described various techniques. Few of them fits very well in learning programming, deepen the concepts and research - while few are best suited for memorizing concepts for exams. Lets learn about each of them.&lt;/p></description></item><item><title>Dotnet Core Identity With .NET CLI</title><link>https://ravindradevrani.com/posts/dotnet-core-identity-with-dotnet-cli/</link><pubDate>Tue, 10 Feb 2026 16:05:18 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-core-identity-with-dotnet-cli/</guid><description>&lt;p>&lt;code>Aspnet core identity&lt;/code> provides an UI to registration, login, manage users, password, external authentication (google, twitter, facebook etc). In simple words, We can say it is an authentication and authorization feature in just few lines of commands and code. It is a nice feature, if you don&amp;rsquo;t want to use other managed authentication providers like Azure Entra Id / Okta Auth0 etc.&lt;/p>
&lt;p>Visual studio provides an UI way to enable identity. Which is very straightforward, but using CLI can be a little bit tricky. It is not always the case you are using visual studio (specially if you are using mac or linux). I use linux also. That is the whole reason to write this article.&lt;/p></description></item><item><title>Dotnet Core API Crud With Mysql and EF Core</title><link>https://ravindradevrani.com/posts/dotnet-core-api-crud-with-mysql-efcore/</link><pubDate>Mon, 29 Dec 2025 11:19:51 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-core-api-crud-with-mysql-efcore/</guid><description>&lt;p>In this tutorial, we are going to make dotnet core web api application and perform all the CRUD (create, read, update and delete). I have tried to keep it simple and avoided any complexities like repository pattern.&lt;/p>
&lt;p>&lt;a href="https://github.com/rd003/DotnetPracticeDemos/tree/master/BlogDemos/MySqlEfCore">💻Source code&lt;/a>&lt;/p>
&lt;h2 id="tech-and-tools-used">Tech and tools used&lt;/h2>
&lt;ul>
&lt;li>Dotnet 10&lt;/li>
&lt;li>MySql 8+ (in docker container. Click &lt;a href="https://ravindradevrani.com/posts/mysql-in-docker/">here&lt;/a>, if you want to create a MySql container in docker)&lt;/li>
&lt;li>Entity Framework Core (ORM)&lt;/li>
&lt;li>.NET CLI and VS Code (alternate Visual Studio 2025)&lt;/li>
&lt;/ul>
&lt;h2 id="creating-a-project">Creating a project&lt;/h2>
&lt;p>Execute these commands in a sequence.&lt;/p></description></item><item><title>Dotnet Core API Crud With Mysql and Dapper</title><link>https://ravindradevrani.com/posts/dotnet-crud-with-mysql-and-dapper/</link><pubDate>Thu, 25 Dec 2025 11:19:51 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-crud-with-mysql-and-dapper/</guid><description>&lt;p>In this tutorial, we are going to make dotnet core web api application and perform all the CRUD (create, read, update and delete). I have tried to keep it simple and avoided any complexities like repository pattern.&lt;/p>
&lt;p>&lt;a href="https://github.com/rd003/DotnetPracticeDemos/tree/master/BlogDemos/DapperMysql">💻Source code&lt;/a>&lt;/p>
&lt;h2 id="tech-and-tools-used">Tech and tools used&lt;/h2>
&lt;ul>
&lt;li>Dotnet 10&lt;/li>
&lt;li>MySql 8+ (in docker container. Click &lt;a href="https://ravindradevrani.com/posts/mysql-in-docker/">here&lt;/a>, if you want to create a MySql container in docker)&lt;/li>
&lt;li>Dapper (ORM)&lt;/li>
&lt;li>.NET CLI and VS Code (alternate Visual Studio 2025)&lt;/li>
&lt;/ul>
&lt;h2 id="create-database">Create database&lt;/h2>
&lt;p>Let&amp;rsquo;s start with creating a database and a table. You need to execute this script.&lt;/p></description></item><item><title>How to run Mysql in Docker?</title><link>https://ravindradevrani.com/posts/mysql-in-docker/</link><pubDate>Mon, 22 Dec 2025 18:31:32 +0530</pubDate><guid>https://ravindradevrani.com/posts/mysql-in-docker/</guid><description>&lt;p>Execute the command below.&lt;/p>
&lt;p>For bash:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>docker run -d &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --name mysql-dev &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> -p 3306:3306 &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> -e MYSQL_ROOT_PASSWORD&lt;span style="color:#f92672">=&lt;/span>p@55w0rd &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> -v mysql-data:/var/lib/mysql &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> mysql:8.0.44-debian
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For powershell:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-ps1" data-lang="ps1">&lt;span style="display:flex;">&lt;span>docker run -d `
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> --name mysql-dev `
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -p &lt;span style="color:#ae81ff">3306&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">:&lt;/span>&lt;span style="color:#ae81ff">3306&lt;/span> `
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -e MYSQL_ROOT_PASSWORD=p@55w0rd `
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> -v mysql-data&lt;span style="color:#960050;background-color:#1e0010">:&lt;/span>/var/lib/mysql `
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> mysql&lt;span style="color:#960050;background-color:#1e0010">:&lt;/span>&lt;span style="color:#ae81ff">8.0&lt;/span>.&lt;span style="color:#ae81ff">44&lt;/span>-debian
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>📢 For mac silicon specific:&lt;/p>
&lt;p>&lt;code>mysql:8.0.44-debian&lt;/code> does not support ARM architectureUse &amp;ndash; so use &lt;code>mysql:latest&lt;/code> instead of &lt;code>mysql:8.0.44-debian&lt;/code> or check &lt;a href="https://hub.docker.com/">official docker hub&lt;/a> for suitable image.&lt;/p></description></item><item><title>LeftJoin and RightJoin in Ef Core 10</title><link>https://ravindradevrani.com/posts/left-join-ef-core-10/</link><pubDate>Tue, 16 Dec 2025 09:40:05 +0530</pubDate><guid>https://ravindradevrani.com/posts/left-join-ef-core-10/</guid><description>&lt;p>Previously there was no simple solution for left or right join. We had to use &lt;code>DefaultIfEmpty&lt;/code> or &lt;code>GroupJoin&lt;/code> and &lt;code>SelectMany&lt;/code>.&lt;/p>
&lt;p>With &lt;code>DefaultIfEmpty()&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> customerOrders = &lt;span style="color:#66d9ef">await&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">from&lt;/span> c &lt;span style="color:#66d9ef">in&lt;/span> ctx.Customers
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">join&lt;/span> o &lt;span style="color:#66d9ef">in&lt;/span> ctx.Orders &lt;span style="color:#66d9ef">on&lt;/span> c.CustomerId &lt;span style="color:#66d9ef">equals&lt;/span> o.CustomerId &lt;span style="color:#66d9ef">into&lt;/span> orders
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">from&lt;/span> o &lt;span style="color:#66d9ef">in&lt;/span> orders.DefaultIfEmpty()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">select&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> c.CustomerId,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> c.CustomerName,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> OrderId = o == &lt;span style="color:#66d9ef">null&lt;/span> ? &lt;span style="color:#ae81ff">0&lt;/span> : o.OrderId
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>).ToListAsync();
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>I have used the way described above in most of my career. It was really hard to remember that syntax and I always struggled with that.&lt;/p></description></item><item><title>It is okay to learn code by mistakes</title><link>https://ravindradevrani.com/posts/learn-to-code-by-mistakes/</link><pubDate>Tue, 09 Dec 2025 09:00:00 +0530</pubDate><guid>https://ravindradevrani.com/posts/learn-to-code-by-mistakes/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>I am sharing an incident when I was building my first project. I had a cs degree, I knew c# and .net but I&amp;rsquo;ve never built anything with it except few console and very small windows app. I was writing a code of uploading images and I needed to write the same image upload code in multiple places. It was fine when I&amp;rsquo;ve copied it in 2 or 3 places, but I was getting annoyed when I had to copy it in multiple places. I did not bother to refactor it. Honestly, I didn&amp;rsquo;t even know about refactoring. But in future, I had to update the code and I had to update the code in multiple places. Then I got to know about utility or helper methods. Later I learned that it is a concept called &lt;code>DRY (Do not repeat yourself)&lt;/code>.&lt;/p></description></item><item><title>Cartesian Explosion and Split Query in Entity Framework Core</title><link>https://ravindradevrani.com/posts/cartesian-explosion-and-split-query-in-entity-framework-core/</link><pubDate>Sun, 07 Dec 2025 20:03:37 +0530</pubDate><guid>https://ravindradevrani.com/posts/cartesian-explosion-and-split-query-in-entity-framework-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this tutorial, we will understand what cartesian explosion is and how to solve that problem. Let&amp;rsquo;s look at this query:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> people = &lt;span style="color:#66d9ef">await&lt;/span> ctx.People
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .Include(p =&amp;gt; p.Emails)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .Include(p =&amp;gt; p.Addresses)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .ToListAsync();
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It translates to:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">SELECT&lt;/span> &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;FirstName&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;LastName&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonEmail&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonId&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;a&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;a&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonAddress&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;a&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonId&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">FROM&lt;/span> &lt;span style="color:#e6db74">&amp;#34;People&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">AS&lt;/span> &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">LEFT&lt;/span> &lt;span style="color:#66d9ef">JOIN&lt;/span> &lt;span style="color:#e6db74">&amp;#34;Emails&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">AS&lt;/span> &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">ON&lt;/span> &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonId&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">LEFT&lt;/span> &lt;span style="color:#66d9ef">JOIN&lt;/span> &lt;span style="color:#e6db74">&amp;#34;Addresses&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">AS&lt;/span> &lt;span style="color:#e6db74">&amp;#34;a&amp;#34;&lt;/span> &lt;span style="color:#66d9ef">ON&lt;/span> &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span> &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;a&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;PersonId&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">ORDER&lt;/span> &lt;span style="color:#66d9ef">BY&lt;/span> &lt;span style="color:#e6db74">&amp;#34;p&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;e&amp;#34;&lt;/span>.&lt;span style="color:#e6db74">&amp;#34;Id&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;code>Person&lt;/code> joins with &lt;code>Email&lt;/code> and &lt;code>Address&lt;/code>. Both joins are at the same level.&lt;/li>
&lt;li>A person can have multiple emails and adressess.&lt;/li>
&lt;/ul>
&lt;p>Let&amp;rsquo;s say a person with id = 1 have 10 emails and 10 addresses. The query returns 1x10x10 = 100 rows for 1 person. It is just for one person, how much they can be for 100 people. This problem is known as &lt;code>cartesian explosion&lt;/code>&lt;/p></description></item><item><title>How to run Sql Server 2025 in Docker</title><link>https://ravindradevrani.com/posts/sql-server-in-docker/</link><pubDate>Thu, 04 Dec 2025 11:00:49 +0530</pubDate><guid>https://ravindradevrani.com/posts/sql-server-in-docker/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>To be honest, since I have started using docker I have never installed any database in my machine. I use multiple databases and keeping each database up and running takes a toll on resources of your machine. And&amp;hellip; you can not install some database like &amp;ldquo;sql server&amp;rdquo; on &amp;ldquo;mac&amp;rdquo;, then docker is only option for you. Any way, I think it is enough introduction. Let&amp;rsquo;s get started.&lt;/p></description></item><item><title>How to run PostgreSql in Docker</title><link>https://ravindradevrani.com/posts/postgres-in-docker/</link><pubDate>Tue, 02 Dec 2025 11:02:49 +0530</pubDate><guid>https://ravindradevrani.com/posts/postgres-in-docker/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>To be honest, since I have started using docker I have never installed any database in my machine. I use multiple databases and keeping each database up and running takes a toll on resources of your machine. And&amp;hellip; you can not install some database like &amp;ldquo;sql server&amp;rdquo; on &amp;ldquo;mac&amp;rdquo;, then docker is only option for you. Any way, I think it is enough introduction. Let&amp;rsquo;s get started.&lt;/p></description></item><item><title>Setting Up Node Js With Typescript</title><link>https://ravindradevrani.com/posts/setting-up-node-js-with-typescript/</link><pubDate>Sun, 30 Nov 2025 13:02:07 +0530</pubDate><guid>https://ravindradevrani.com/posts/setting-up-node-js-with-typescript/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>(image credit: &lt;a href="https://gemini.google.com/">Gemini&lt;/a>)&lt;/p>
&lt;p>We are going to create folders and install packages in this step. I don&amp;rsquo;t have much to say for this tutorial. I have tried to explain necessary stuff through comments. In my opinion code is self-explanatory. So, let&amp;rsquo;s execute these commands in a sequence.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># create a directory&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mkdir backend
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># change directory&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cd backend
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># create the `src` directory inside the `backend`.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mkdir src
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># create file&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>touch src/index.ts 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># initialize node js project. &lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Please stay inside the `backend` directory. &lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>npm init -y 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># install these packages&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>npm install express cors
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># install the dev dependencies&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># these packages won&amp;#39;t be shipped to your production bundle&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>npm install -D typescript tsx @types/node @types/express @types/cors
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># generate tsconfig.json file&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>npx tsc --init
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Folder structure should look like this.&lt;/p></description></item><item><title>Lazy Loading and N+1 Query Problem in Entity framework Core</title><link>https://ravindradevrani.com/posts/lazy-loading-and-n-plus-one-query-problem-in-ef-core/</link><pubDate>Thu, 27 Nov 2025 15:34:26 +0530</pubDate><guid>https://ravindradevrani.com/posts/lazy-loading-and-n-plus-one-query-problem-in-ef-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;a href="https://github.com/rd003/DotnetPracticeDemos/tree/master/LazyLoadingExample">💻Source code&lt;/a>&lt;/p>
&lt;h2 id="lazy-loading">Lazy loading&lt;/h2>
&lt;p>You load related entities on demand rather loading at once. This approach is usually useful when you want to load related entities on a certain condition (otherwise always use eager loading).&lt;/p>
&lt;p>To enable lazy loading, you need to install this package: &lt;code>Microsoft.EntityFrameworkCore.Proxies&lt;/code>&lt;/p>
&lt;p>And do following changes in &lt;code>Program.cs&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>builder.Services.AddDbContext&amp;lt;AppDbContext&amp;gt;(o=&amp;gt;o.UseLazyLoadingProxies()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>.UseSqlite(&lt;span style="color:#e6db74">&amp;#34;Data Source = mydb.db&amp;#34;&lt;/span>));
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Look at the example below:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>app.MapGet(&lt;span style="color:#e6db74">&amp;#34;/&amp;#34;&lt;/span>, &lt;span style="color:#66d9ef">async&lt;/span> (AppDbContext context) =&amp;gt; {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">foreach&lt;/span> (&lt;span style="color:#66d9ef">var&lt;/span> genre &lt;span style="color:#66d9ef">in&lt;/span> &lt;span style="color:#66d9ef">await&lt;/span> context.Genres.ToListAsync()) 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">foreach&lt;/span> (&lt;span style="color:#66d9ef">var&lt;/span> book &lt;span style="color:#66d9ef">in&lt;/span> genre.Books)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Console.WriteLine(&lt;span style="color:#e6db74">$&amp;#34;===&amp;gt; genre: {genre.Name}, Book: {book.Title}, Price : {book.Author}&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> Results.Ok(&lt;span style="color:#e6db74">&amp;#34;Ok&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>});
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We are not loading &lt;code>books&lt;/code> with &lt;code>genres&lt;/code> at once. Rather we are loading books for each genres. Let&amp;rsquo;s take a look at &lt;code>logs of console&lt;/code>.&lt;/p></description></item><item><title>Content Negotiation in Dotnet Core Webapi</title><link>https://ravindradevrani.com/posts/content-negotiation-in-dotnetcore-webapi/</link><pubDate>Sat, 22 Nov 2025 16:23:29 +0530</pubDate><guid>https://ravindradevrani.com/posts/content-negotiation-in-dotnetcore-webapi/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>As defined in &lt;a href="https://datatracker.ietf.org/doc/html/rfc2616#section-12">rfc2616&lt;/a> - &lt;strong>&amp;ldquo;Content nagotiation is the process of selecting the best representation for a given response when there are multiple representations available.&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>Clients passes the header &lt;code>Accept&lt;/code> with values like &lt;code>application/json&lt;/code>,&lt;code>application/xml&lt;/code> etc and tells this format is acceptable. Then server gives the response according to that.&lt;/p>
&lt;p>In simpler terms, if your API supports xml, json and csv media type, then let clients decide which kind of media type they need as a response.&lt;/p></description></item><item><title>Containerizing Dotnet App With PostgreSql Using Docker Compose</title><link>https://ravindradevrani.com/posts/containerizing-dotnet-app-with-postgresql-using-docker-compose/</link><pubDate>Fri, 21 Nov 2025 13:33:14 +0530</pubDate><guid>https://ravindradevrani.com/posts/containerizing-dotnet-app-with-postgresql-using-docker-compose/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this tutorial, we are going to &lt;strong>containerize the .NET Web API application with docker and postgres&lt;/strong>. I am assuming you are familiar with docker. At least, you should have some understandings of how docker works. However, I have covered all the steps needed to create a docker container for your application, but I am not going to cover the &lt;a href="https://en.wikipedia.org/wiki/Docker_%28software%29">theoretical concepts&lt;/a> of docker.&lt;/p>
&lt;p>&lt;strong>📢Last updated : 21-Nov-2025&lt;/strong>&lt;/p></description></item><item><title>Containerizing Dotnet App With Sql Server Using Docker Compose</title><link>https://ravindradevrani.com/posts/containerizing-dotnet-app-with-sql-server-using-docker-compose/</link><pubDate>Thu, 20 Nov 2025 13:57:05 +0530</pubDate><guid>https://ravindradevrani.com/posts/containerizing-dotnet-app-with-sql-server-using-docker-compose/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this tutorial, we are going to containerize the .NET Web API application with docker. I am assuming you are familiar with docker. At least, you should have some understandings of how docker works. However, I have covered all the steps needed to create a docker container for your application, but I am not going to cover the &lt;a href="https://en.wikipedia.org/wiki/Docker_%28software%29">theoretical concepts&lt;/a> of docker.&lt;/p>
&lt;h2 id="last-updated-on">Last updated on:&lt;/h2>
&lt;ul>
&lt;li>20-November-2025&lt;/li>
&lt;/ul>
&lt;h3 id="tools-needed">🔨Tools needed&lt;/h3>
&lt;ul>
&lt;li>Visual Studio Code (Free)&lt;/li>
&lt;li>.Net 10.0 SDK (Free)&lt;/li>
&lt;li>Docker desktop (Free)&lt;/li>
&lt;/ul>
&lt;h3 id="tech-used">🧑‍💻Tech used&lt;/h3>
&lt;ul>
&lt;li>.Net 10.0 Web APIs (controller APIs)&lt;/li>
&lt;li>Ms SQL Server 2025 (within a container)&lt;/li>
&lt;li>Docker compose&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>🍵Note:&lt;/strong> I am using windows 11 operating system. However, I also have tested it in the Linux mint xia and it is working fine.&lt;/p></description></item><item><title>Fastapi CRUD With Postgres</title><link>https://ravindradevrani.com/posts/fastapi-crud-with-postgres/</link><pubDate>Sat, 18 Oct 2025 20:18:50 +0530</pubDate><guid>https://ravindradevrani.com/posts/fastapi-crud-with-postgres/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this tutorial we learn to create REST Apis with &lt;code>fastapi&lt;/code>. We are going to use:&lt;/p>
&lt;ul>
&lt;li>&lt;code>FastApi&lt;/code> for creating APIs&lt;/li>
&lt;li>&lt;code>PostgreSQL&lt;/code> as a database&lt;/li>
&lt;li>&lt;code>SQLAlchemy&lt;/code> as an ORM tool&lt;/li>
&lt;li>&lt;code>Alembic&lt;/code> as a migration tool&lt;/li>
&lt;/ul>
&lt;h2 id="tech-and-tools-used">Tech and tools used&lt;/h2>
&lt;ul>
&lt;li>Linux os (you can use window or mac also. But with windows your commands might be a little different. I suggest you to use &lt;code>GitBash&lt;/code> in windows)&lt;/li>
&lt;li>I am using &lt;code>uv&lt;/code> to create project, you can download it from &lt;a href="https://docs.astral.sh/uv/getting-started/installation/">here&lt;/a>&lt;/li>
&lt;li>Python 3.12&lt;/li>
&lt;li>VS Code (code editor) with extension &lt;code>Python&lt;/code> by microsoft&lt;/li>
&lt;li>PostgreSQL (I am using it in a docker container, you can use installed version too)&lt;/li>
&lt;/ul>
&lt;p>The reason I am using &lt;code>uv&lt;/code>, because it is pretty fast and I can easily manage dependencies with it.&lt;/p></description></item><item><title>Azure Key Vault With Dotnet</title><link>https://ravindradevrani.com/posts/azure-key-vault-with-dotnet/</link><pubDate>Mon, 22 Sep 2025 10:25:42 +0530</pubDate><guid>https://ravindradevrani.com/posts/azure-key-vault-with-dotnet/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>First of all, let&amp;rsquo;s see what are we going to achieve? Let&amp;rsquo;s say we have an dotnet 9 api application.&lt;/p>
&lt;p>Its &lt;code>appsettings.json&lt;/code> looks like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-js" data-lang="js">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;Color&amp;#34;&lt;/span>&lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;Color from appsettings&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;Person&amp;#34;&lt;/span>&lt;span style="color:#f92672">:&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;Name&amp;#34;&lt;/span>&lt;span style="color:#f92672">:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;Name from appsettings&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s try to retrieve these values:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>app.MapGet(&lt;span style="color:#e6db74">&amp;#34;/&amp;#34;&lt;/span>, (IConfiguration config) =&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">string&lt;/span> color = config.GetSection(&lt;span style="color:#e6db74">&amp;#34;Color&amp;#34;&lt;/span>).Value ?? &lt;span style="color:#e6db74">&amp;#34;No color&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">string&lt;/span> name = config.GetSection(&lt;span style="color:#e6db74">&amp;#34;Person:Name&amp;#34;&lt;/span>).Value ?? &lt;span style="color:#e6db74">&amp;#34;No name&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> Results.Ok(&lt;span style="color:#66d9ef">new&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> color,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> name,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> message = &lt;span style="color:#e6db74">&amp;#34;Hello there...&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> });
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>});
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If you visit this endpoint, you will see this output:&lt;/p></description></item><item><title>Azure App Configuration With Dotnet(C#)</title><link>https://ravindradevrani.com/posts/azure-app-configuration-with-dotnet-csharp/</link><pubDate>Sat, 20 Sep 2025 16:56:26 +0530</pubDate><guid>https://ravindradevrani.com/posts/azure-app-configuration-with-dotnet-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;ul>
&lt;li>Azure &lt;code>App Configuration&lt;/code> is a fully managed service, which provides you a way to store the configurations in a centralized store. You can store configurations of multiple apps in a single place.&lt;/li>
&lt;li>It is really helpful for cloud native application (eg. Microservices), which runs on multiple virtual machines and use multiple external services.&lt;/li>
&lt;li>It allows us to store Key-value pairs, manage feature flags, and organize configurations using labels and namespaces.&lt;/li>
&lt;li>The main benefit is, it supports &lt;a href="https://learn.microsoft.com/en-us/azure/azure-app-configuration/enable-dynamic-configuration-aspnet-core">dynamic refreshing&lt;/a>. Which means, you can change config values without restarting the app.&lt;/li>
&lt;li>You can also add reference of azure key vault secret here.&lt;/li>
&lt;/ul>
&lt;p>Let&amp;rsquo;s see these things in action.&lt;/p></description></item><item><title>Azure Blob Storage : CRUD With AspNetCore Mvc &amp; SQL Server</title><link>https://ravindradevrani.com/posts/blob-storage-with-dotnet-mvc/</link><pubDate>Mon, 08 Sep 2025 12:49:37 +0530</pubDate><guid>https://ravindradevrani.com/posts/blob-storage-with-dotnet-mvc/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;code>Azure blob storage&lt;/code> is a storage solution provided by microsoft. You can store data like images, audio, video, json files, zip files etc etc in the azure.&lt;/p>
&lt;h2 id="what-are-we-going-to-learn">What are we going to learn?&lt;/h2>
&lt;ul>
&lt;li>How to create a web application that stores and manipulate the images in the cloud.&lt;/li>
&lt;li>We will perform all the CRUD (create, read, update and delete) operations.&lt;/li>
&lt;/ul>
&lt;h2 id="tech-used">Tech used&lt;/h2>
&lt;ul>
&lt;li>.NET Core 9 (MVC app)&lt;/li>
&lt;li>SQL server 2022&lt;/li>
&lt;li>Azure storage account&lt;/li>
&lt;/ul>
&lt;h2 id="high-level-overview">High level overview&lt;/h2>
&lt;ul>
&lt;li>We will save &lt;code>image url&lt;/code> in the database and images in the &lt;code>storage account(blob container)&lt;/code>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="lets-create-an-storage-account-first">Let&amp;rsquo;s create an storage account first&lt;/h2>
&lt;p>Step 1:
&lt;img src="https://ravindradevrani.com/images/blobstorage/blob_1.png" alt="create azure storage account 1">&lt;/p></description></item><item><title>Cosmos DB For NoSQL - CRUD With Dotnet</title><link>https://ravindradevrani.com/posts/cosmos-db-crud-with-dotnet/</link><pubDate>Sun, 07 Sep 2025 21:37:42 +0530</pubDate><guid>https://ravindradevrani.com/posts/cosmos-db-crud-with-dotnet/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;code>Azure Cosmos DB for NoSQL&lt;/code> is a fully managed and serverless &lt;code>NoSQL&lt;/code> and &lt;code>vector database&lt;/code> for modern app development, including AI applications and agents. With its SLA-backed speed and availability as well as instant dynamic scalability, it is ideal for real-time NoSQL applications that require high performance and distributed computing over massive volumes of NoSQL and vector data.&lt;/p>
&lt;p>&lt;strong>Soruce:&lt;/strong> learn.microsoft.com, you can learn more about it from &lt;a href="https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/overview">here&lt;/a>&lt;/p></description></item><item><title>Asynchronous Programming in C# - Comparing it with multi-threading</title><link>https://ravindradevrani.com/posts/asynchronous-programming-in-csharp-and-how-is-it-different-from-multithreading/</link><pubDate>Tue, 29 Jul 2025 18:24:07 +0530</pubDate><guid>https://ravindradevrani.com/posts/asynchronous-programming-in-csharp-and-how-is-it-different-from-multithreading/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;code>Asynchronous task&lt;/code> is a &lt;strong>non-blocking&lt;/strong> task. Main thread goes back to the &lt;strong>thread pool&lt;/strong> (and free to do other tasks) when it reaches to await &amp;ndash; and new thread is assigned when wait is complete.&lt;/p>
&lt;p>It is different from the multi-threading. In multi-threding, task is divided between multiple threads. Cores of your CPU are utilized.&lt;/p>
&lt;h2 id="analogy">Analogy&lt;/h2>
&lt;p>Let&amp;rsquo;s say you have some chores like:&lt;/p>
&lt;ol>
&lt;li>Boiling eggs 🫕 (or sweet potatoes🍠🍠 if you dont eat eggs 🥚🥚)&lt;/li>
&lt;li>Clean 🧹🪣 the house&lt;/li>
&lt;/ol>
&lt;p>There are multiple ways to achieve this:&lt;/p></description></item><item><title>Inversion of Control - Dependency Injection - Dependency Inversion Principle</title><link>https://ravindradevrani.com/posts/inversion-of-control-and-dependency-injection/</link><pubDate>Sun, 20 Jul 2025 16:10:34 +0530</pubDate><guid>https://ravindradevrani.com/posts/inversion-of-control-and-dependency-injection/</guid><description>&lt;!-- raw HTML omitted -->
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Direct or traditional approach:&lt;/strong> Object creates its own dependencies.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Inverted approach (inversion of control):&lt;/strong> Dependencies are created outside the object. This responsibility is given to someone else.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Example 1 (Direct approach):&lt;/strong>&lt;/p>
&lt;p>We have a service named &lt;code>EmailService&lt;/code> which is an implementation of &lt;code>INotificationService&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span> &lt;span style="color:#a6e22e">INotificationService&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">void&lt;/span> SendNotification();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">EmailService&lt;/span> : INotificationService
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> SendNotification()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// code to send notification &lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>OrderService&lt;/code> need to use the &lt;code>INotificationService&lt;/code>.&lt;/p></description></item><item><title>Node Js: Jwt Authentication and refresh token</title><link>https://ravindradevrani.com/posts/node-js-jwt-authentication/</link><pubDate>Fri, 04 Jul 2025 00:00:00 +0530</pubDate><guid>https://ravindradevrani.com/posts/node-js-jwt-authentication/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>Please visit this &lt;a href="https://ravindradevrani.com/posts/node-js-crud-with-sql-server/">post&lt;/a> first, where I have made this project from scratch and wrote CRUD APIs.&lt;/p>
&lt;h2 id="source-code">Source code&lt;/h2>
&lt;ul>
&lt;li>Backend and specific only to this tutorial: &lt;a href="https://github.com/rd003/ng-node-fullstack/pull/new/jwt-refresh">https://github.com/rd003/ng-node-fullstack/pull/new/jwt-refresh&lt;/a>&lt;/li>
&lt;li>Complete project with angular : &lt;a href="https://github.com/rd003/ng-node-fullstack">https://github.com/rd003/ng-node-fullstack&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="json-web-token-jwt-and-why-it-is-needed">JSON web token (JWT) and why it is needed&lt;/h2>
&lt;p>REST Apis are session less. You can not maintain the authentication session for the whole application. For that purpose, &lt;code>JSON web token (JWT)&lt;/code> comes in play. How it works&lt;/p></description></item><item><title>Build a Node.js REST APIs with Express, Sequelize &amp; SQL Server (2025 Guide)</title><link>https://ravindradevrani.com/posts/node-js-crud-with-sql-server/</link><pubDate>Thu, 03 Jul 2025 19:17:23 +0530</pubDate><guid>https://ravindradevrani.com/posts/node-js-crud-with-sql-server/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this tutorial, you’ll learn how to build a simple &lt;strong>CRUD (Create, Read, Update, Delete) REST API&lt;/strong> using &lt;strong>Node.js&lt;/strong>, &lt;strong>Express.js&lt;/strong>, &lt;strong>Sequelize&lt;/strong>, and &lt;strong>SQL Server&lt;/strong>. I have tried to make it a less verbose. It is more like a technical documentation to create the rest apis in this tech stack. However, I have tried to explain all the essential things. This is ideal if you&amp;rsquo;re looking to integrate a SQL Server database with a Node.js backend using Sequelize as the ORM. We are using sql server in this tutorial but you can easily replace it with other sql databases.&lt;/p></description></item><item><title>Dotnet: All you need to know about middlewares</title><link>https://ravindradevrani.com/posts/middlewares-in-dotnet/</link><pubDate>Tue, 27 May 2025 12:49:04 +0530</pubDate><guid>https://ravindradevrani.com/posts/middlewares-in-dotnet/</guid><description>&lt;!-- raw HTML omitted -->
&lt;ul>
&lt;li>In dotnet, a &lt;code>Middleware&lt;/code> is a piece of code that runs in the request pipeline.&lt;/li>
&lt;li>Middlewares are put together in a sequence, and their order matters.&lt;/li>
&lt;li>When a request is made, it goes through each of the middleware.&lt;/li>
&lt;li>Response flow back in reverse order through the middleware.&lt;/li>
&lt;li>Each middleware has capability to modify the request or short circuits the pipeline.&lt;/li>
&lt;li>Each middleware can change the response before it&amp;rsquo;s sent to the client.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://ravindradevrani.com/images/middleware-in-dotnet.webp" alt="middleware pipeline in .net core">&lt;/p></description></item><item><title>Jwt Authention and role base authorization in Dotnet Core</title><link>https://ravindradevrani.com/posts/jwt-authention-in-dotnet-core/</link><pubDate>Sun, 18 May 2025 17:11:50 +0530</pubDate><guid>https://ravindradevrani.com/posts/jwt-authention-in-dotnet-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h2 id="create-a-new-web-api-project">Create a new web api project&lt;/h2>
&lt;p>Run these commands in a sequence to create a new project.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>dotnet new sln -o JwtDotnet9
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cd JwtDotnet9
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>dotnet sln add JwtDotnet9/JwtDotnet9.csproj
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Open the project in vs code.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>code .
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>=&amp;gt; &lt;a href="https://github.com/rd003/JwtDotnet9">Source Code&lt;/a>&lt;/p>
&lt;p>=&amp;gt; &lt;a href="https://ravindradevrani.com/posts/dotnet-core-jwt-refresh-token/">Securing The .NET 9 App: Signup, Login, JWT, Refresh Tokens, and Role Based Access with PostgreSQL&lt;/a>&lt;/p>
&lt;h2 id="install-the-required-nuget-packages">Install the required nuget packages&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="jwt-configuration-in-appsettings">Jwt configuration in appsettings&lt;/h2>
&lt;p>Open &lt;code>appsettings.json&lt;/code> and add these lines&lt;/p></description></item><item><title>C#: Byte and Its Use Cases</title><link>https://ravindradevrani.com/posts/byte-and-its-use-cases-in-csharp/</link><pubDate>Sat, 17 May 2025 17:32:06 +0530</pubDate><guid>https://ravindradevrani.com/posts/byte-and-its-use-cases-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;ul>
&lt;li>&lt;code>byte&lt;/code> is a value type in c#&lt;/li>
&lt;li>&lt;code>byte&lt;/code> is an unsigned integer which stores value from 0 to 255, which means it can not store negetive numbers.&lt;/li>
&lt;li>Size of &lt;code>byte&lt;/code> is 8-bit (1 byte)&lt;/li>
&lt;li>CTS equivalent of byte is &lt;code>System.Byte&lt;/code>&lt;/li>
&lt;li>It&amp;rsquo;s default value is 0&lt;/li>
&lt;li>It is great for memory optimization when dealing with small numbers.&lt;/li>
&lt;/ul>
&lt;p>Examples:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">byte&lt;/span> a = &lt;span style="color:#ae81ff">10&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Console.WriteLine(a);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="use-cases">Use cases&lt;/h2>
&lt;ol>
&lt;li>Working with ASCII value&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">byte&lt;/span> asciiValue = (&lt;span style="color:#66d9ef">byte&lt;/span>)&lt;span style="color:#e6db74">&amp;#39;R&amp;#39;&lt;/span>; &lt;span style="color:#75715e">// 82&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">byte&lt;/span> asciiValue2 = (&lt;span style="color:#66d9ef">byte&lt;/span>)&lt;span style="color:#e6db74">&amp;#39;r&amp;#39;&lt;/span>; &lt;span style="color:#75715e">// 114&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="2">
&lt;li>Encoding text into bytes&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">using&lt;/span> System.Text;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">string&lt;/span> message = &lt;span style="color:#e6db74">&amp;#34;Ravindra&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">byte&lt;/span>[] encoded = Encoding.UTF8.GetBytes(message);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Console.WriteLine(&lt;span style="color:#e6db74">$&amp;#34;{string.Join(&amp;#34;&lt;/span>,&lt;span style="color:#e6db74">&amp;#34;,encoded)}&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// op: 82,97,118,105,110,100,114,97&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Note: Each character is encoded using UTF-8. For standard letters, the byte values match their ASCII codes.. (R: 82, a:97, v:118 &amp;hellip;)&lt;/p></description></item><item><title>IEnumerable Vs IQueryable In C#</title><link>https://ravindradevrani.com/posts/ienumerable-vs-iqueryable/</link><pubDate>Tue, 13 May 2025 11:45:17 +0530</pubDate><guid>https://ravindradevrani.com/posts/ienumerable-vs-iqueryable/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>There has been a discussion around town about the difference between an &lt;code>IEnumerable&lt;/code> and an &lt;code>IQueryable&lt;/code>, especially in c# interviews. I won&amp;rsquo;t be diving into the fact that &lt;code>IEnumerable&lt;/code> is part of the &lt;code>System.Collections&lt;/code> namespace and &lt;code>IQueryable&lt;/code> belongs to &lt;code>System.Linq&lt;/code> namespace (or did I???). Rather, I’ll focus on the practical usage of both—how they work, and when to use each.&lt;/p>
&lt;h2 id="iqueryable">IQueryable&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> IActionResult GetPeople()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// It will retrieve 2 records from database &lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> IQueryable&amp;lt;Person&amp;gt; people = _context.People.Take(&lt;span style="color:#ae81ff">2&lt;/span>); 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Note: At the above line, no data will be retrieved from the database&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> Ok(people); &lt;span style="color:#75715e">// Data will be retrieved here&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="corresponding-sql">Corresponding sql&lt;/h3>
&lt;p>Note that, I am using &lt;code>Sqlite&lt;/code>, the above code is translated to this query:&lt;/p></description></item><item><title>Bulk insert in dapper with table valued parameter</title><link>https://ravindradevrani.com/posts/bulk-insert-in-dapper-with-table-valued-parameter/</link><pubDate>Sun, 04 May 2025 17:00:00 +0530</pubDate><guid>https://ravindradevrani.com/posts/bulk-insert-in-dapper-with-table-valued-parameter/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>There might be instances when you want to insert bulk data. For an instance, you want to create an order, where you need to add multiple items. Let&amp;rsquo;s see how can we insert bulk data in c# using dapper.&lt;/p>
&lt;p>Note: It is only good for adding bunch of rows. But if you are looking for adding hundreds of rows then better to use other approaches. There are many, if you look out.&lt;/p></description></item><item><title>EF Core under the hood: Count() vs Any()</title><link>https://ravindradevrani.com/posts/count-vs-any-in-entity-framework-core/</link><pubDate>Tue, 01 Apr 2025 11:03:07 +0530</pubDate><guid>https://ravindradevrani.com/posts/count-vs-any-in-entity-framework-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>Let&amp;rsquo;s say you want to execute a code block when &lt;code>Book&lt;/code> table is not empty. In Entity Framework Core, we can achieve this in two ways (there might be others but I am unaware of them):&lt;/p>
&lt;p>Option 1:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span>(context.Books.Count()&amp;gt;&lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// do something&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Option 2:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (context.Books.Any())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// do something&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Note 📢:&lt;/strong> I am testing these queries against a table containing 1 million rows.&lt;/p></description></item><item><title>Linux Basic Commands</title><link>https://ravindradevrani.com/posts/linux-basic-commands/</link><pubDate>Thu, 27 Mar 2025 19:52:00 +0530</pubDate><guid>https://ravindradevrani.com/posts/linux-basic-commands/</guid><description>&lt;ol>
&lt;li>Contents of a file: &lt;code>ls&lt;/code>&lt;/li>
&lt;li>Content list with long format: &lt;code>ls -l&lt;/code> or &lt;code>ls -l -h&lt;/code> human readable or concat the both &lt;code>ls -lh&lt;/code>.&lt;/li>
&lt;li>Change directory: &lt;code>cd DirectoryName&lt;/code>&lt;/li>
&lt;li>Move to the upper directory: &lt;code>cd ..&lt;/code>&lt;/li>
&lt;li>Switch to previous directory : &lt;code>cd -&lt;/code>&lt;/li>
&lt;li>Change to home directory: &lt;code>cd ~&lt;/code>&lt;/li>
&lt;li>Go to full path: &lt;code>cd /Home/Documents/Pitctures/MyPictures&lt;/code>&lt;/li>
&lt;li>Tilde (~) for home directory : &lt;code>MyPc:~/Documents$ cd ~/Videos&lt;/code>&lt;/li>
&lt;li>Clear screen: &lt;code>clear&lt;/code>&lt;/li>
&lt;li>Show different drives in the computer (List block devices): &lt;code>lsblk&lt;/code>&lt;/li>
&lt;li>Opening a file in the text editor :&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># open in nano&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>nano filename
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#open in xed editor&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>xed filename
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="12">
&lt;li>Root directory: &lt;code>cd /&lt;/code>&lt;/li>
&lt;li>Press &lt;code>Tab&lt;/code> to autocomlete.&lt;/li>
&lt;li>Create a directory : &lt;code>mkdir blah&lt;/code>&lt;/li>
&lt;li>Remove a directory : &lt;code>rmdir blah&lt;/code>&lt;/li>
&lt;li>Creating a blank file : &lt;code>touch something.txt&lt;/code>
14.1. Creating multiple files at once: &lt;code>touch f1.txt f2.txt f3.txt f4.md f5.md&lt;/code>&lt;/li>
&lt;li>Printing something in terminal : &lt;code>echo hello&lt;/code>&lt;/li>
&lt;li>Create a file with text: &lt;code>echo &amp;quot;blah blah&amp;quot; &amp;gt; blah.txt&lt;/code>&lt;/li>
&lt;li>Show contents of a file: &lt;code>cat blah.txt&lt;/code>&lt;/li>
&lt;li>Copy file : &lt;code>cp /source/filename.ext destination/filename.ext&lt;/code>&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># note: I am currently in the `Desktop` directory&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># copy `blah.txt` from `Desktop` to `Documents` directory&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cp blah.txt ~/Documents/blah2.txt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># copy `blah.txt` from `Desktop` to `Documents` directory with changed filename&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cp blah.txt ~/Documents/blah2.txt 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># it will copy `blah.txt from `Desktop` to `Documents` directory with changed file name `blah2.txt`&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="19">
&lt;li>
&lt;p>Copy all files (&lt;em>.&lt;/em> allfiles.allextensions): &lt;code>cp *.* ~/Documents&lt;/code>&lt;/p></description></item><item><title>How to Install DotNet SDK In Ubuntu Based Distros?</title><link>https://ravindradevrani.com/posts/how-to-install-dotnet-sdk-in-ubuntu-based-distros/</link><pubDate>Wed, 26 Mar 2025 19:59:22 +0530</pubDate><guid>https://ravindradevrani.com/posts/how-to-install-dotnet-sdk-in-ubuntu-based-distros/</guid><description>&lt;h2 id="my-distro">My Distro&lt;/h2>
&lt;p>I am using &lt;code>linux mint 22.1&lt;/code> which is based on &lt;code>Ubuntu 24.04&lt;/code>.&lt;/p>
&lt;h2 id="straightforeward-command">Straightforeward command&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>sudo apt-get update
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sudo apt-get install -y dotnet-sdk-10.0
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="but">But&amp;hellip;&lt;/h2>
&lt;p>I have tried to run this command &lt;code>sudo apt-get install -y dotnet-sdk-10.0&lt;/code> but unfortunately I got no success. I have found that, this command works only with &lt;code>Ubuntu 24.10&lt;/code>. For &lt;code>Ubuntu 24.04&lt;/code> I need to use different approach.&lt;/p>
&lt;h2 id="uninstall-prior-version-if-exists">Uninstall prior version if exists&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>sudo apt-get remove dotnet-sdk-9.0
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now, run these commands in a sequence:&lt;/p></description></item><item><title>Dapper: Output Parameter</title><link>https://ravindradevrani.com/posts/dapper-output-param/</link><pubDate>Sun, 23 Mar 2025 00:00:00 +0530</pubDate><guid>https://ravindradevrani.com/posts/dapper-output-param/</guid><description>&lt;h2 id="stored-procedure">Stored procedure&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">CREATE&lt;/span> &lt;span style="color:#66d9ef">OR&lt;/span> &lt;span style="color:#66d9ef">ALTER&lt;/span> &lt;span style="color:#66d9ef">PROCEDURE&lt;/span> [dbo].[CreateTrackEntry]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>EntryDate DATE,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>SleptAt DATETIME2,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>WokeUpAt DATETIME2,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>NapInMinutes SMALLINT,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>TotalWorkInMinutes SMALLINT,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>Remarks NVARCHAR(&lt;span style="color:#ae81ff">1000&lt;/span>) &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">NULL&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">@&lt;/span>TrackEntryId INT &lt;span style="color:#66d9ef">OUTPUT&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">AS&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">BEGIN&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">-- code removed for brevity
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">END&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We have a stored procedure that returns &lt;code>TrackEntryId&lt;/code> as an output parameter. Let&amp;rsquo;s see how can we execute it from the dapper?&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> IDbConnection connection = &lt;span style="color:#66d9ef">new&lt;/span> SqlConnection(_connectionString);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> parameters = &lt;span style="color:#66d9ef">new&lt;/span> DynamicParameters(trackEntryToCreate);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Input params&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@EntryDate&amp;#34;&lt;/span>, trackEntryToCreate.EntryDate);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@SleptAt&amp;#34;&lt;/span>, trackEntryToCreate.SleptAt);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@WokeUpAt&amp;#34;&lt;/span>, trackEntryToCreate.WokeUpAt);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@NapInMinutes&amp;#34;&lt;/span>, trackEntryToCreate.NapInMinutes);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@TotalWorkInMinutes&amp;#34;&lt;/span>, trackEntryToCreate.TotalWorkInMinutes);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@Remarks&amp;#34;&lt;/span>, trackEntryToCreate.Remarks);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// output params&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex; background-color:#3c3d38">&lt;span>parameters.Add(&lt;span style="color:#e6db74">&amp;#34;@TrackEntryId&amp;#34;&lt;/span>, dbType: DbType.Int32, direction: ParameterDirection.Output);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">await&lt;/span> connection.ExecuteAsync(&lt;span style="color:#e6db74">&amp;#34;CreateTrackEntry&amp;#34;&lt;/span>, parameters,commandType:CommandType.StoredProcedure);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex; background-color:#3c3d38">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> trackEntryId = parameters.Get&amp;lt;&lt;span style="color:#66d9ef">int&lt;/span>&amp;gt;(&lt;span style="color:#e6db74">&amp;#34;@TrackEntryId&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Configuring dotnet core apps for OpenApi with SwaggerUi or Scalar</title><link>https://ravindradevrani.com/posts/configuring-dotnet-core-app-for-swagger-ui-or-scalar/</link><pubDate>Fri, 21 Mar 2025 09:16:37 +0530</pubDate><guid>https://ravindradevrani.com/posts/configuring-dotnet-core-app-for-swagger-ui-or-scalar/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;code>SwaggerUI&lt;/code>, which was previously bundled with .NET Core APIs, has been dropped in .NET 9. However, .NET Core Web APIs still support generating &lt;code>OpenAPI&lt;/code> documents. .NET Core apps have built-in support for generating information about endpoints and it uses &lt;code>Microsoft.AspNetCore.OpenApi&lt;/code> package for that. To configure interactive UIs for these OpenAPI documents, we have several options. We are going to explore these two:&lt;/p>
&lt;ol>
&lt;li>Swashbuckle SwaggerUI&lt;/li>
&lt;li>Scalar&lt;/li>
&lt;/ol>
&lt;h3 id="create-a-new-project-if-does-not-have-an-existing">Create a new project, if does not have an existing&lt;/h3>
&lt;p>Execute these commands in a sequence&lt;/p></description></item><item><title>Transactions in Dapper</title><link>https://ravindradevrani.com/posts/transactions-in-dapper/</link><pubDate>Thu, 20 Mar 2025 09:39:47 +0530</pubDate><guid>https://ravindradevrani.com/posts/transactions-in-dapper/</guid><description>&lt;p>Isn&amp;rsquo;t it already described in Dapper docs? Sure it is. Why do I bother to write this? Am I just wtiting it for the sake of &amp;ldquo;posting&amp;rdquo;? No, I am not. Actually, I was trying to write the code by using Dapper&amp;rsquo;s docs. Unfortunately, I ran into a few bugs. I am using .NET 9, by the way and this is not even a blog post; it&amp;rsquo;s just a code snippet. I thought I should share it, may be someone else is facing the same problem as me.&lt;/p></description></item><item><title>Inserting bulk records (1 million) in SQL Server</title><link>https://ravindradevrani.com/posts/bulk-insert-in-sql-server-with-recursive-cte/</link><pubDate>Wed, 19 Mar 2025 17:25:31 +0530</pubDate><guid>https://ravindradevrani.com/posts/bulk-insert-in-sql-server-with-recursive-cte/</guid><description>&lt;h2 id="creating-a-database">Creating a database&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>USE master
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">GO&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">DROP&lt;/span> &lt;span style="color:#66d9ef">DATABASE&lt;/span> &lt;span style="color:#66d9ef">IF&lt;/span> &lt;span style="color:#66d9ef">EXISTS&lt;/span> BookMillion
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">GO&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">CREATE&lt;/span> &lt;span style="color:#66d9ef">DATABASE&lt;/span> BookMillion
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">GO&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>USE [BookMillion]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">GO&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">CREATE&lt;/span> &lt;span style="color:#66d9ef">TABLE&lt;/span> [dbo].[Book](
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	[Id] [int] &lt;span style="color:#66d9ef">IDENTITY&lt;/span>(&lt;span style="color:#ae81ff">1&lt;/span>,&lt;span style="color:#ae81ff">1&lt;/span>) &lt;span style="color:#66d9ef">NOT&lt;/span> &lt;span style="color:#66d9ef">NULL&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	[Title] [nvarchar](&lt;span style="color:#ae81ff">100&lt;/span>) &lt;span style="color:#66d9ef">NULL&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	[Author] [nvarchar](&lt;span style="color:#ae81ff">100&lt;/span>) &lt;span style="color:#66d9ef">NOT&lt;/span> &lt;span style="color:#66d9ef">NULL&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	[Country] [nvarchar](&lt;span style="color:#ae81ff">100&lt;/span>) &lt;span style="color:#66d9ef">NULL&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	[ImageLink] [nvarchar](&lt;span style="color:#ae81ff">100&lt;/span>) &lt;span style="color:#66d9ef">NULL&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	[&lt;span style="color:#66d9ef">Language&lt;/span>] [nvarchar](&lt;span style="color:#ae81ff">20&lt;/span>) &lt;span style="color:#66d9ef">NULL&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	[Link] [nvarchar](&lt;span style="color:#ae81ff">200&lt;/span>) &lt;span style="color:#66d9ef">NULL&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	[Pages] [int] &lt;span style="color:#66d9ef">NULL&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	[&lt;span style="color:#66d9ef">Year&lt;/span>] [int] &lt;span style="color:#66d9ef">NULL&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	[Price] [int] &lt;span style="color:#66d9ef">NULL&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#66d9ef">CONSTRAINT&lt;/span> PK_Book_Id &lt;span style="color:#66d9ef">PRIMARY&lt;/span> &lt;span style="color:#66d9ef">KEY&lt;/span> (Id)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">GO&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="bulk-insert-using-recursive-cte">Bulk insert using recursive cte&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>USE [BookMillion]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">GO&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">WITH&lt;/span> Numbers &lt;span style="color:#66d9ef">AS&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SELECT&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#66d9ef">AS&lt;/span> N
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">UNION&lt;/span> &lt;span style="color:#66d9ef">ALL&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SELECT&lt;/span> N &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FROM&lt;/span> Numbers
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">WHERE&lt;/span> N &lt;span style="color:#f92672">&amp;lt;&lt;/span> &lt;span style="color:#ae81ff">1000000&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">insert&lt;/span> &lt;span style="color:#66d9ef">into&lt;/span> Book (Title,Author,Country,[&lt;span style="color:#66d9ef">Language&lt;/span>],ImageLink,Link,Pages,Price,[&lt;span style="color:#66d9ef">Year&lt;/span>])
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">select&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#39;Book&amp;#39;&lt;/span>&lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#66d9ef">cast&lt;/span>(N &lt;span style="color:#66d9ef">as&lt;/span> varchar),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#39;Author&amp;#39;&lt;/span>&lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#66d9ef">cast&lt;/span>(N &lt;span style="color:#66d9ef">as&lt;/span> varchar),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#39;Country&amp;#39;&lt;/span>&lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#66d9ef">cast&lt;/span>(N &lt;span style="color:#66d9ef">as&lt;/span> varchar),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#39;Language&amp;#39;&lt;/span>&lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#66d9ef">cast&lt;/span>(N &lt;span style="color:#66d9ef">as&lt;/span> varchar),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#39;ImageLink&amp;#39;&lt;/span>&lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#66d9ef">cast&lt;/span>(N &lt;span style="color:#66d9ef">as&lt;/span> varchar),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">&amp;#39;Link&amp;#39;&lt;/span>&lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#66d9ef">cast&lt;/span>(N &lt;span style="color:#66d9ef">as&lt;/span> varchar),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ABS&lt;/span>(CHECKSUM(NEWID())) &lt;span style="color:#f92672">%&lt;/span> &lt;span style="color:#ae81ff">901&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#ae81ff">100&lt;/span>, &lt;span style="color:#75715e">-- Pages between 100-1000
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">ABS&lt;/span>(CHECKSUM(NEWID())) &lt;span style="color:#f92672">%&lt;/span> &lt;span style="color:#ae81ff">901&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#ae81ff">100&lt;/span>, &lt;span style="color:#75715e">-- Price between 100-1000
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">ABS&lt;/span>(CHECKSUM(NEWID())) &lt;span style="color:#f92672">%&lt;/span> &lt;span style="color:#ae81ff">825&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#ae81ff">1200&lt;/span> &lt;span style="color:#75715e">-- Year between 1200-2024
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">from&lt;/span> Numbers
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">option&lt;/span> (maxrecursion &lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">GO&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Keyset Pagination In Entity Framework Core</title><link>https://ravindradevrani.com/posts/keyset-pagination-in-ef-core/</link><pubDate>Sat, 15 Mar 2025 09:50:37 +0530</pubDate><guid>https://ravindradevrani.com/posts/keyset-pagination-in-ef-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>First we need to know about the traditional offset based pagination and the problems it introduces.&lt;/p>
&lt;h3 id="offset-pagination">Offset pagination&lt;/h3>
&lt;p>In the code below we are using the offset pagination.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">[HttpGet(&amp;#34;offset&amp;#34;)]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">async&lt;/span> Task&amp;lt;IActionResult&amp;gt; GetBooks(&lt;span style="color:#66d9ef">int&lt;/span> limit=&lt;span style="color:#ae81ff">10&lt;/span>, &lt;span style="color:#66d9ef">int&lt;/span> page=&lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> books = &lt;span style="color:#66d9ef">await&lt;/span> _context.Books
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .AsNoTracking()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .OrderBy(a =&amp;gt; a.Id)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .Skip(limit * (page - &lt;span style="color:#ae81ff">1&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .Take(limit)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .ToListAsync();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> Ok(books);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Which translates to the following sql:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SELECT&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Id],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Author],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Country],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[ImageLink],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[&lt;span style="color:#66d9ef">Language&lt;/span>],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Link],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Pages],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Price],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[Title],
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [b].[&lt;span style="color:#66d9ef">Year&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FROM&lt;/span> [Book] &lt;span style="color:#66d9ef">AS&lt;/span> [b]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ORDER&lt;/span> &lt;span style="color:#66d9ef">BY&lt;/span> [b].[Id]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">OFFSET&lt;/span> &lt;span style="color:#f92672">@&lt;/span>__p_0 &lt;span style="color:#66d9ef">ROWS&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FETCH&lt;/span> &lt;span style="color:#66d9ef">NEXT&lt;/span> &lt;span style="color:#f92672">@&lt;/span>__p_1 &lt;span style="color:#66d9ef">ROWS&lt;/span> &lt;span style="color:#66d9ef">ONLY&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Note:&lt;/strong> In every pagination logic, ordering must be unique. In our case we are using &lt;code>Id&lt;/code> which is unique.&lt;/p></description></item><item><title>Rest Api Designing Best Practices</title><link>https://ravindradevrani.com/posts/rest-api-best-practices-design/</link><pubDate>Fri, 07 Mar 2025 10:41:02 +0530</pubDate><guid>https://ravindradevrani.com/posts/rest-api-best-practices-design/</guid><description>&lt;p>There are some common practices one should take care of while designing REST APIs.&lt;/p>
&lt;blockquote>
&lt;p>There is also a &lt;a href="https://youtu.be/6vWdSQ3iZ2E?si=V3CBjc_ZHLz_4AKS">video version&lt;/a> of this post.&lt;/p>
&lt;/blockquote>
&lt;!-- raw HTML omitted -->
&lt;h3 id="1-use-descriptive-names-for-resources">1. Use descriptive names for resources&lt;/h3>
&lt;ul>
&lt;li>❌ /api/getAllBooks&lt;/li>
&lt;li>❌ /api/retrieveBooks&lt;/li>
&lt;li>❌ /api/manageBooks&lt;/li>
&lt;li>❌ /api/process&lt;/li>
&lt;li>✅ /api/books&lt;/li>
&lt;/ul>
&lt;h3 id="2-use-nouns-not-verbs">2. Use nouns not verbs&lt;/h3>
&lt;ul>
&lt;li>❌ /api/mangage-books&lt;/li>
&lt;li>✅ /api/books&lt;/li>
&lt;/ul>
&lt;h3 id="3-use-plural-nouns">3. Use plural nouns&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>❌ Singular Nouns&lt;/th>
 &lt;th>✅ Plural Nouns&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>/api/book&lt;/td>
 &lt;td>/api/books&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>/api/movie&lt;/td>
 &lt;td>/api/movies&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>/api/person&lt;/td>
 &lt;td>/api/people&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>/api/customer&lt;/td>
 &lt;td>/api/customers&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="4-use-hyphens---in-url-for-better-readabilty">4. Use hyphens (-) in url for better readabilty&lt;/h3>
&lt;ul>
&lt;li>❌ /api/useraccounts&lt;/li>
&lt;li>✅ /api/user-accounts&lt;/li>
&lt;/ul>
&lt;h3 id="5-never-use-crud-method-names-in-url">5. Never use crud method names in url&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>HttpMethod&lt;/th>
 &lt;th>❌❌❌&lt;/th>
 &lt;th>✅✅✅&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>GET&lt;/td>
 &lt;td>/api/books/GetAllBooks&lt;/td>
 &lt;td>/api/books&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GET&lt;/td>
 &lt;td>/api/books/GetBookById/{id}&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>POST&lt;/td>
 &lt;td>/api/books/CreateBook&lt;/td>
 &lt;td>/api/books&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>PUT&lt;/td>
 &lt;td>/api/books/UpdateBook/{id}&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DELETE&lt;/td>
 &lt;td>/api/books/DeleteBook/{id}&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="6-use-http-method-properly">6. Use http method properly&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>HttpMethod&lt;/th>
 &lt;th>Endpoint&lt;/th>
 &lt;th>Description&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>GET&lt;/td>
 &lt;td>/api/books&lt;/td>
 &lt;td>Indicates a get resources&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>GET&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;td>Indicates a get resource with id&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>POST&lt;/td>
 &lt;td>/api/books&lt;/td>
 &lt;td>Indicates creating a resource&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>PUT&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;td>Indicates updating a resource&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DELETE&lt;/td>
 &lt;td>/api/books/{id}&lt;/td>
 &lt;td>Indicates deleting a resource&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="7-use-http-statuscodes-correctly">7. Use Http StatusCodes Correctly&lt;/h3>
&lt;p>These are the most commonly used status codes.&lt;/p></description></item><item><title>Covering Indexes In Sql Server</title><link>https://ravindradevrani.com/posts/covering-indexes/</link><pubDate>Sat, 01 Mar 2025 15:20:01 +0530</pubDate><guid>https://ravindradevrani.com/posts/covering-indexes/</guid><description>&lt;h2 id="table-structure-and-total-records">Table structure and total records&lt;/h2>
&lt;p>Let&amp;rsquo;s look at our table structure as shown in the left panel of the picture&lt;/p>
&lt;!-- raw HTML omitted -->
&lt;p>&lt;strong>Note:&lt;/strong> There is a &lt;code>non-clustered index&lt;/code> on the &lt;code>Title&lt;/code> column of the &lt;code>Book&lt;/code> table, which has a total of 1 million records.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">select&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Id,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Title,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Author,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Price
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">from&lt;/span> Book &lt;span style="color:#66d9ef">where&lt;/span> title&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39;The Divine Comedy&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;img src="https://ravindradevrani.com/images/need_for_covering_index.jpg" alt="query_execution_plan">&lt;/p>
&lt;p>As you have noticed in the execution plan, there is a key lookup. Since index is only available for the &lt;code>Title&lt;/code> column, &lt;code>Title&lt;/code> is retrieved from the non-clustered index. However, other columns like &lt;code>Id&lt;/code>, &lt;code>Author&lt;/code> and &lt;code>Price&lt;/code> are not present in the non-clustered index, so they will be retrieved from the clustered index (the &lt;code>Book&lt;/code> table). This results in an additional &lt;code>key lookup&lt;/code> step and may decrease the performance. It&amp;rsquo;s like, you are looking for records in two places (non clustered index and clustered index).&lt;/p></description></item><item><title>Dotnet Service Lifetime : AddTransient(), AddScoped(), AddSingleton()</title><link>https://ravindradevrani.com/posts/dotnet-service-lifetime/</link><pubDate>Wed, 26 Feb 2025 07:29:14 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-service-lifetime/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h2 id="example-setup">Example Setup&lt;/h2>
&lt;p>I am using a &lt;code>MinimalApi&lt;/code> application. Create a new one if you need.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>dotnet new webapi -n DITest
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Open it in a IDE or editor of your choice.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span> &lt;span style="color:#a6e22e">IMyService&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Guid InstanceId { &lt;span style="color:#66d9ef">get&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">MyService&lt;/span> : IMyService
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> Guid InstanceId { &lt;span style="color:#66d9ef">get&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> MyService()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> InstanceId = Guid.NewGuid();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// We are logging in the constructor, so that we get notified whenever the instance is created&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Console.WriteLine(&lt;span style="color:#e6db74">$&amp;#34;==&amp;gt; Service created with InstanceId: {InstanceId}&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>IMyService&lt;/code> have a read-only property named &lt;code>InstanceId&lt;/code> of type &lt;code>Guid&lt;/code>, which is set from the constructor.
We are logging inside the constructor, so that we can get notified whenever the new instance is created.&lt;/p></description></item><item><title>LINQ: Zip() operator</title><link>https://ravindradevrani.com/posts/linq-zip-method/</link><pubDate>Tue, 25 Feb 2025 10:10:41 +0530</pubDate><guid>https://ravindradevrani.com/posts/linq-zip-method/</guid><description>&lt;!-- raw HTML omitted -->
&lt;blockquote>
&lt;p>There is also a &lt;a href="https://youtu.be/p1SXSMe0wk8?si=8p2ZptMcPrI_fodS">video version&lt;/a> of this tutorial.&lt;/p>
&lt;/blockquote>
&lt;p>Let&amp;rsquo;s understand it with example.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span>[] nums1 = [&lt;span style="color:#ae81ff">1&lt;/span>, &lt;span style="color:#ae81ff">2&lt;/span>, &lt;span style="color:#ae81ff">3&lt;/span>, &lt;span style="color:#ae81ff">4&lt;/span>];
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span>[] nums2 = [&lt;span style="color:#ae81ff">3&lt;/span>, &lt;span style="color:#ae81ff">4&lt;/span>, &lt;span style="color:#ae81ff">5&lt;/span>, &lt;span style="color:#ae81ff">6&lt;/span>];
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>IEnumerable&amp;lt;&lt;span style="color:#66d9ef">int&lt;/span>&amp;gt;? product = nums1.Zip(nums2, (n1, n2) =&amp;gt; n1 * n2);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Console.WriteLine(&lt;span style="color:#66d9ef">string&lt;/span>.Join(&lt;span style="color:#e6db74">&amp;#34;, &amp;#34;&lt;/span>, product)); &lt;span style="color:#75715e">// 3, 8, 15, 24&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s break it down:&lt;/p>
&lt;p>&lt;code>IEnumerable&amp;lt;int&amp;gt;? product = nums1.Zip(nums2, (n1, n2) =&amp;gt; n1 * n2);&lt;/code>&lt;/p>
&lt;p>It takes &lt;code>nums1[i]&lt;/code> and &lt;code>nums2[i]&lt;/code>, evaluates it (nums1[0]*nums2[0]) and returns it. Here &lt;code>i&lt;/code> is the index of the array. For example.&lt;/p></description></item><item><title>SingleAsync vs SingleOrDefaultAync vs FirstAsync vs FirstOrDefaultAsync vs FindAync</title><link>https://ravindradevrani.com/posts/singleasync-vs-singleordefaultaync-vs-firstasync-vs-firstordefaultasync-vs-findaync/</link><pubDate>Mon, 24 Feb 2025 18:07:04 +0530</pubDate><guid>https://ravindradevrani.com/posts/singleasync-vs-singleordefaultaync-vs-firstasync-vs-firstordefaultasync-vs-findaync/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>I don’t think there is any need of introduction. Let’s jump to the code section. We coders understand with code more. Let’s understand the concept then you don’t need to remember any definition.&lt;/p>
&lt;p>This is the recordset against which I am running queries.&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Id&lt;/th>
 &lt;th>FirstName&lt;/th>
 &lt;th>LastName&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>1&lt;/td>
 &lt;td>John&lt;/td>
 &lt;td>Doe&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>2&lt;/td>
 &lt;td>Ravindra&lt;/td>
 &lt;td>Devrani&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3&lt;/td>
 &lt;td>Mohan&lt;/td>
 &lt;td>Singh&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>20&lt;/td>
 &lt;td>Mahesh&lt;/td>
 &lt;td>Soni&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>21&lt;/td>
 &lt;td>John&lt;/td>
 &lt;td>Snow&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>First and foremost let’s say we need a record with LastName=”Doe”.&lt;/p></description></item><item><title>Database Firsts Approach In EF Core</title><link>https://ravindradevrani.com/posts/db-first-approach-ef-core/</link><pubDate>Mon, 24 Feb 2025 17:49:15 +0530</pubDate><guid>https://ravindradevrani.com/posts/db-first-approach-ef-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>I have used &lt;code>database first&lt;/code> approach in the .NET Framework 4.X. But It is the first time I am trying to use Db First approach in the .NET Core (I am using .net 9). Microsoft refers it &lt;a href="https://learn.microsoft.com/en-us/ef/core/managing-schemas/scaffolding/?tabs=dotnet-core-cli">&amp;lsquo;Scaffolding (Reverse Engineering)&amp;rsquo;&lt;/a>. Personally I prefer &lt;code>Dapper&lt;/code> for DB First approach. May be you have an existing database and you want to use it with ENTITY FRAMEWORK, then this approach might be helpful. I am playing around it and documenting it and sharing that journey with you. Let&amp;rsquo;s see what it offers.&lt;/p></description></item><item><title>Curious Case of LINQ Group By</title><link>https://ravindradevrani.com/posts/curious-case-of-linq-group-by/</link><pubDate>Mon, 24 Feb 2025 16:17:33 +0530</pubDate><guid>https://ravindradevrani.com/posts/curious-case-of-linq-group-by/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h3 id="schema">Schema&lt;/h3>
&lt;ul>
&lt;li>Department (DepartmentId, Name)&lt;/li>
&lt;li>Employee (EmployeeId, Name, DepartmentId)&lt;/li>
&lt;/ul>
&lt;h3 id="result-set-ineed">Result set I need&lt;/h3>
&lt;p>Show all departments with total number of employees. Do not skip the departments which have 0 employees. As shown below:&lt;/p>
&lt;p>DepartmentIdNameTotalEmployees1Engineering22Marketing13HR0&lt;/p>
&lt;p>I have applied various queries and checked their equivalent sql.&lt;/p>
&lt;h3 id="1-straightforward-but-skips-the-department-which-has-no-employees">1. Straightforward but skips the department which has no employees&lt;/h3>
&lt;p>This query does not meet my requirement. It would be a good choice if I don’t need departments without any employees.&lt;/p></description></item><item><title>LINQ: SelectMany()</title><link>https://ravindradevrani.com/posts/select-many-linq/</link><pubDate>Mon, 24 Feb 2025 16:09:29 +0530</pubDate><guid>https://ravindradevrani.com/posts/select-many-linq/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>NOTE: You can find the source code &lt;a href="https://github.com/rd003/DotnetPracticeDemos/tree/master/SelectManyDemo/SelectManyDemo" title="https://github.com/rd003/DotnetPracticeDemos/tree/master/SelectManyDemo/SelectManyDemo">here&lt;/a>.&lt;/p>
&lt;h3 id="schema-overview">Schema Overview&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Department&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">Department&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> DepartmentId { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> Name { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; } = &lt;span style="color:#66d9ef">string&lt;/span>.Empty;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> ICollection&amp;lt;Employee&amp;gt; Employees { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; } = [];
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Employee&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">Employee&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> EmployeeId { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> Name { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; } = &lt;span style="color:#66d9ef">string&lt;/span>.Empty;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> DepartmentId { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> Department Department { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; } = &lt;span style="color:#66d9ef">null&lt;/span>!;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> ICollection&amp;lt;EmployeeSkill&amp;gt; EmployeeSkills { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; } = [];
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Skills&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">Skill&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> SkillId { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> Name { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; } = &lt;span style="color:#66d9ef">string&lt;/span>.Empty;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> ICollection&amp;lt;EmployeeSkill&amp;gt; EmployeeSkills { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; } = [];
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// EmployeeSkills (Junction table)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">EmployeeSkill&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> EmployeeId { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> SkillId { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> Employee Employee { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; } = &lt;span style="color:#66d9ef">null&lt;/span>!;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> Skill Skill { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>; } = &lt;span style="color:#66d9ef">null&lt;/span>!;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In simpler terms:&lt;/p></description></item><item><title>What Makes My Query Non Sargable?</title><link>https://ravindradevrani.com/posts/what-makes-your-query-non-sargable/</link><pubDate>Mon, 24 Feb 2025 15:51:23 +0530</pubDate><guid>https://ravindradevrani.com/posts/what-makes-your-query-non-sargable/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>A query is &lt;strong>SARGable (Search ARGument able)&lt;/strong> if a database engine can take advantage of index.&lt;/p>
&lt;h2 id="what-makes-a-query-non-sargable">What makes a query non SARGable?&lt;/h2>
&lt;p>These are the few factors that makes a query non sargable.&lt;/p>
&lt;h3 id="1-put-a-column-inside-a-function-in-the-whereclause">1. Put a column inside a function in the where clause.&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">select&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> s.SalesOrderID,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> s.SalesPersonID,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> s.OrderDate,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> s.SalesOrderNumber
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">from&lt;/span> Sales.SalesOrderHeader s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">where&lt;/span> &lt;span style="color:#66d9ef">YEAR&lt;/span>(s.OrderDate) &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">2011&lt;/span>; &lt;span style="color:#75715e">-- Row Retrieved: 1607 and Row read : 31465
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Note:&lt;/strong> I have created covering index on the &lt;code>OrderDate&lt;/code>:&lt;/p></description></item><item><title>SQL Server: Table Scan, Clustured Index Scan, Index Seek, RID Lookup, Key Lookup</title><link>https://ravindradevrani.com/posts/table-scan-index-scan-index-seek-rid-lookup-key-lookup/</link><pubDate>Mon, 24 Feb 2025 13:40:51 +0530</pubDate><guid>https://ravindradevrani.com/posts/table-scan-index-scan-index-seek-rid-lookup-key-lookup/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>Initially, it was not intended to be an article. I was tinkering around sql and documenting few things, then I thought, it could turnout to a nice article. I have wrote lots of article and created lots of videos on c#, .net core and angular. But it is my first article on the SQL.&lt;/p>
&lt;p>In this blog post, we are going to explore few terms of execution plan, like table scan, clustered index scan, index seek, RID lookup and key lookup.&lt;/p></description></item><item><title>Creating and Installing Dotnet CLI Tool</title><link>https://ravindradevrani.com/posts/creating-and-installing-dotnet-cli-tool/</link><pubDate>Mon, 24 Feb 2025 13:28:51 +0530</pubDate><guid>https://ravindradevrani.com/posts/creating-and-installing-dotnet-cli-tool/</guid><description>&lt;p>In this tutorial we are going to learn:&lt;/p>
&lt;ul>
&lt;li>How to create a cli tool?&lt;/li>
&lt;li>How to create a nuget package?&lt;/li>
&lt;li>How to install it in our machine.&lt;/li>
&lt;/ul>
&lt;p>CLI tools are very useful, they are very easy to use. We are already using it in our every day.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>dotnet new console -o CliToolDemo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It is the example of dotnet cli tool, simple way to create a .net console application. You can also create your own cli tools. We are going to use a package created by Microsoft named &lt;code>System.CommandLine&lt;/code> , which is a pre-released version as of I am writing this blog post. It is a pre-released version for so long, I wonder what are the plans about this package. You can also use a library named &lt;a href="https://github.com/mayuki/Cocona">Cocona&lt;/a> to create cli tools, which is pretty simple and widely popular. But I am going to stick with &lt;code>System.CommandLine&lt;/code> . You should definitely checkout the cocona.&lt;/p></description></item><item><title>Securing The .NET 9 App: Signup, Login, JWT, Refresh Tokens, and Role Based Access with PostgreSQL</title><link>https://ravindradevrani.com/posts/dotnet-core-jwt-refresh-token/</link><pubDate>Mon, 24 Feb 2025 11:35:17 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-core-jwt-refresh-token/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>REST APIs are stateless, so server does not store any information about the client. So we can not authorize the rest application in a traditional way. How does a server knows if the user is authenticated user or not? In this situation the &lt;strong>Json Web Token (JWT)&lt;/strong> saves the day.&lt;/p>
&lt;blockquote>
&lt;p>JSON Web Tokens are an open, industry standard &lt;a href="https://tools.ietf.org/html/rfc7519">&lt;strong>RFC 7519&lt;/strong>&lt;/a> method for representing claims securely between two parties. &lt;a href="https://jwt.io/">Source: jwt.io&lt;/a>&lt;/p></description></item><item><title>Handle Exceptions Globally in .NET Core With IExceptionHandler And IProblemDetailService</title><link>https://ravindradevrani.com/posts/handle-exception-globally-with-iexceptionhandler/</link><pubDate>Sun, 23 Feb 2025 18:16:31 +0530</pubDate><guid>https://ravindradevrani.com/posts/handle-exception-globally-with-iexceptionhandler/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;strong>Problem details&lt;/strong> is a standard way to communicate error details in &lt;strong>HttpResponse,&lt;/strong> defined in &lt;a href="https://datatracker.ietf.org/doc/html/rfc7807">rfc 7807&lt;/a>. Standard &lt;strong>ProblemDetails&lt;/strong> Properties:&lt;/p>
&lt;ul>
&lt;li>&lt;code>Type&lt;/code>: URI identifying problem type&lt;/li>
&lt;li>&lt;code>Title&lt;/code>: Short error description&lt;/li>
&lt;li>&lt;code>Status&lt;/code>: HTTP status code&lt;/li>
&lt;li>&lt;code>Detail&lt;/code>: Specific error explanation&lt;/li>
&lt;li>&lt;code>Instance&lt;/code>: URI identifying specific error occurrence&lt;/li>
&lt;/ul>
&lt;p>Problem details is automatically integrated with .net core APIs. When we return the &lt;strong>BadRequest&lt;/strong> we generally get response with problem details.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// controller method&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">return&lt;/span> BadRequest();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// response&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;type&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;https://tools.ietf.org/html/rfc9110#section-15.5.1&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;title&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;Bad Request&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;status&amp;#34;&lt;/span>: &lt;span style="color:#ae81ff">400&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;traceId&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;00-2d4948694b0f223f7f5dff215b42481b-0288bb95d7604783-00&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The same thing happens when we return the &lt;strong>NotFoundException.&lt;/strong>&lt;/p></description></item><item><title>Dotnet Core Api CRUD With Dapper and PostgreSql</title><link>https://ravindradevrani.com/posts/dotnet-core-api-crud-with-dapper-and-postgresql/</link><pubDate>Sun, 23 Feb 2025 18:00:17 +0530</pubDate><guid>https://ravindradevrani.com/posts/dotnet-core-api-crud-with-dapper-and-postgresql/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h4 id="source-code-httpsgithubcomrd003postgressdapperdemohttpsgithubcomrd003postgressdapperdemo">💻Source Code: &lt;a href="https://github.com/rd003/PostgressDapperDemo">https://github.com/rd003/PostgressDapperDemo&lt;/a>&lt;/h4>
&lt;h3 id="tools-and-technology-used">Tools and technology used&lt;/h3>
&lt;ul>
&lt;li>VS Code (editor)&lt;/li>
&lt;li>.Net 8&lt;/li>
&lt;li>Postgres&lt;/li>
&lt;li>Dapper&lt;/li>
&lt;/ul>
&lt;p>Let’s get started with creating the database first.&lt;/p>
&lt;p>create database PersonDb;&lt;/p>
&lt;p>Now, create a table within the database.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">create&lt;/span> &lt;span style="color:#66d9ef">table&lt;/span> Person
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Id serial &lt;span style="color:#66d9ef">primary&lt;/span> &lt;span style="color:#66d9ef">key&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Name varchar(&lt;span style="color:#ae81ff">30&lt;/span>) &lt;span style="color:#66d9ef">not&lt;/span> &lt;span style="color:#66d9ef">null&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Email varchar(&lt;span style="color:#ae81ff">30&lt;/span>) &lt;span style="color:#66d9ef">not&lt;/span> &lt;span style="color:#66d9ef">null&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To create a new project you need to run these commands in a sequence.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sh" data-lang="sh">&lt;span style="display:flex;">&lt;span>&amp;gt; dotnet new sln -o PostgressDapperDemo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; cd PostgressDapperDemo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; dotnet sln add .&lt;span style="color:#ae81ff">\P&lt;/span>ostgressDapperDemo&lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&amp;gt; code . &lt;span style="color:#75715e">#this command will open this project in the vs code&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="nuget-packages">Nuget packages&lt;/h3>
&lt;p>Install the following nuget packages.&lt;/p></description></item><item><title>Unit of Work With Generic Repository in DotNet Core</title><link>https://ravindradevrani.com/posts/unit-of-work-with-generic-repository-in-dotnet-core/</link><pubDate>Sun, 23 Feb 2025 17:38:31 +0530</pubDate><guid>https://ravindradevrani.com/posts/unit-of-work-with-generic-repository-in-dotnet-core/</guid><description>&lt;p>The &lt;strong>Unit of Work&lt;/strong> Pattern is all about coordinated changes to the database. It groups multiple operations, such as inserts, updates, and deletes, into one transaction. This simply means that all the changes are done together as a complete action, or they all don’t happen at all. In case something goes wrong in one of the operations, the whole transaction rolls back and keeps the database consistent by not allowing partial updates. This makes it easy to handle errors and ensures reliable data.&lt;/p></description></item><item><title>Integration Testing in Dotnet With InMemory Db</title><link>https://ravindradevrani.com/posts/integration-testing-in-dotnet-with-in-memory-db/</link><pubDate>Sun, 23 Feb 2025 17:04:04 +0530</pubDate><guid>https://ravindradevrani.com/posts/integration-testing-in-dotnet-with-in-memory-db/</guid><description>&lt;p>&lt;strong>Integration testing&lt;/strong> is a software testing technique, where individual units of a program are integrated together and tested as a group for interacting harmoniously with each other. It concerns the testing of interactions and interfaces between modules, components, or systems to see if they behave as expected once integrated.&lt;/p>
&lt;blockquote>
&lt;p>📢 Always use real database for integration testing instead of InMemory Db.&lt;/p>
&lt;/blockquote>
&lt;h3 id="purpose">Purpose&lt;/h3>
&lt;ul>
&lt;li>This is to ensure that various components or modules behave according to expectation.&lt;/li>
&lt;li>In the case of integration, to find out whether there are problems concerning interfaces or inconsistencies in data.&lt;/li>
&lt;li>Verifying whether it meets the set specifications and functionality of an integrated system.&lt;/li>
&lt;/ul>
&lt;h3 id="tech-used-in-thisproject">Tech Used in this project&lt;/h3>
&lt;ul>
&lt;li>.Net 8 web APIs (controller)&lt;/li>
&lt;li>Sqlite&lt;/li>
&lt;li>EntityFrameworkCore&lt;/li>
&lt;li>xUnit&lt;/li>
&lt;li>In Memory Database (for testing)&lt;/li>
&lt;/ul>
&lt;h3 id="lets-getstarted">Let’s get started&lt;/h3>
&lt;p>Create a &lt;strong>sln&lt;/strong> file (I have named it &lt;strong>PersonGithubActionsDemo&lt;/strong>) with two projects&lt;/p></description></item><item><title>Unit Testing in Dotnet Core With Nsubstitute</title><link>https://ravindradevrani.com/posts/unit-testing-in-dotnet-core-with-nsubstitute/</link><pubDate>Sun, 23 Feb 2025 16:14:13 +0530</pubDate><guid>https://ravindradevrani.com/posts/unit-testing-in-dotnet-core-with-nsubstitute/</guid><description>&lt;p>As the name suggesting , Unit testing is a software testing where smallest units of the application such as methods are tested in the isolation, so that we can ensure our software is working as expected.&lt;/p>
&lt;h3 id="commonly-used-testing-frameworks">Commonly used testing frameworks&lt;/h3>
&lt;ul>
&lt;li>MSTest&lt;/li>
&lt;li>nUnit&lt;/li>
&lt;li>xUnit&lt;/li>
&lt;/ul>
&lt;h3 id="mocking-frameworks">Mocking frameworks&lt;/h3>
&lt;p>Mocking framework is a library which allows us to mock the objects. For example, a &lt;strong>PeopleController&lt;/strong> is injected with the &lt;strong>IPersonRepository.&lt;/strong> While testing the PeopleController, we need the IPersonRepository. Mock frameworks comes to rescue in that situation. With the help of mock frameworks we can mock the IPersonRepository and mimic it’s behavior. Some popular mocking libraries are:&lt;/p></description></item><item><title>Set Bearer Token to Each Request Automatically in Postman</title><link>https://ravindradevrani.com/posts/set-bearer-token-to-each-request-automatically-in-postman/</link><pubDate>Sun, 23 Feb 2025 13:42:38 +0530</pubDate><guid>https://ravindradevrani.com/posts/set-bearer-token-to-each-request-automatically-in-postman/</guid><description>&lt;p>When we work with postman to test the endpoints, and those endpoints are authorized, each time (until it expires) we need to pass the token in the authorization header. To get the token, we need to call the login or authentication API . This process feels quite irritating , because we programmers hates this manual working. We always want an easy and automatic workflow. Let’s see how can we achieve this with postman.&lt;/p></description></item><item><title>.Net Core API CRUD With PostgreSql</title><link>https://ravindradevrani.com/posts/aspnet-core-apis-with-postgres-sql/</link><pubDate>Sun, 23 Feb 2025 13:21:42 +0530</pubDate><guid>https://ravindradevrani.com/posts/aspnet-core-apis-with-postgres-sql/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>When we create an application with .NET, we tend to use the Microsoft tech stack like Visual Studio IDE, Microsoft SQL Server, Windows Operating System, and Azure. However, things have changed since the introduction of .NET Core. We are no longer bound to a specific operating system and database.&lt;/p>
&lt;p>In this blog post, we will learn how to create a Web API CRUD (Create, Read, Update, Delete) application using .NET Core and a Postgres database.&lt;/p></description></item><item><title>Higher Order Functions in C#</title><link>https://ravindradevrani.com/posts/higher-order-functions-in-csharp/</link><pubDate>Sun, 23 Feb 2025 13:07:13 +0530</pubDate><guid>https://ravindradevrani.com/posts/higher-order-functions-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;strong>Higher-order functions (HOF)&lt;/strong> are functions that can take a function as an argument or return a function or both. In C#, higher-order functions are achieved using delegates, lambda expressions and expression trees.&lt;/p>
&lt;h2 id="example-1-using-adelegate">Example 1: Using a Delegate&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Declare a delegate that takes an int and returns an int&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">delegate&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> IntOperation(&lt;span style="color:#66d9ef">int&lt;/span> x);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">Program&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Higher-order function that takes a delegate as an argument&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> PerformOperation(&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#66d9ef">value&lt;/span>, IntOperation operation)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> operation(&lt;span style="color:#66d9ef">value&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> Main()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Create a delegate instance that points to the Square method&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> IntOperation square = x =&amp;gt; x &lt;span style="color:#960050;background-color:#1e0010">\&lt;/span>* x;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Pass the delegate to the higher-order function&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">int&lt;/span> result = PerformOperation(&lt;span style="color:#ae81ff">5&lt;/span>, square);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Console.WriteLine(result); &lt;span style="color:#75715e">// Output: 25&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="example-2-using-lambda-expression">Example 2 : Using lambda expression&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Higher-order function that takes a lambda expression as an argument&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> PerformOperation(&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#66d9ef">value&lt;/span>, Func&amp;lt;&lt;span style="color:#66d9ef">int&lt;/span>, &lt;span style="color:#66d9ef">int&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">\&lt;/span>&amp;gt; operation)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> operation(&lt;span style="color:#66d9ef">value&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// main method&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Define a lambda expression that squares a number&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Func&amp;lt;&lt;span style="color:#66d9ef">int&lt;/span>, &lt;span style="color:#66d9ef">int&lt;/span>&amp;gt; square = x =&amp;gt; x * x;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Pass the lambda expression to the higher-order function&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> result = PerformOperation(&lt;span style="color:#ae81ff">5&lt;/span>, square);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="example-3-function-as-a-returnvalue">Example 3: Function as a Return Value&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">Program&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Higher-order function that returns a function&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> Func&amp;lt;&lt;span style="color:#66d9ef">int&lt;/span>, &lt;span style="color:#66d9ef">int&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">\&lt;/span>&amp;gt; GetOperation(&lt;span style="color:#66d9ef">bool&lt;/span> isSquare)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (isSquare)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> x =&amp;gt; x &lt;span style="color:#960050;background-color:#1e0010">\&lt;/span>* x;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">else&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> x =&amp;gt; x + x;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> Main()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Get a function that squares a number&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Func&amp;lt;&lt;span style="color:#66d9ef">int&lt;/span>, &lt;span style="color:#66d9ef">int&lt;/span>&amp;gt; operation = GetOperation(&lt;span style="color:#66d9ef">true&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Use the returned function&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">int&lt;/span> result = operation(&lt;span style="color:#ae81ff">5&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Console.WriteLine(result); &lt;span style="color:#75715e">// Output: 25&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In c#, higher order functions are everywhere. If one have used LINQ, must have used HO functions. Collection’s Where() is the good example.&lt;/p></description></item><item><title>Let's dive into various types of properties in c#</title><link>https://ravindradevrani.com/posts/various-types-of-properties-in-csharp/</link><pubDate>Sun, 23 Feb 2025 12:48:39 +0530</pubDate><guid>https://ravindradevrani.com/posts/various-types-of-properties-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>I assume you have some knowledge of C# properties. If not, here’s a quick definition: &lt;strong>A property is a class member that provides a flexible way to read, write, or compute the value of a private field.&lt;/strong> Don’t worry if you’re new to properties; we’ll be using them in this blog, and I’ll explain them as we go along.&lt;/p>
&lt;h3 id="1-properties-with-getter-andsetter">1. Properties with getter and setter&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">Person&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> Name { &lt;span style="color:#66d9ef">get&lt;/span>;&lt;span style="color:#66d9ef">set&lt;/span>; }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> Age { &lt;span style="color:#66d9ef">get&lt;/span>; &lt;span style="color:#66d9ef">set&lt;/span>;}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Generally, we define properties like this. The Person class has two properties &lt;strong>Name&lt;/strong> and &lt;strong>Age,&lt;/strong> each with getters and setters. This enables you to set and read their values.&lt;/p></description></item><item><title>Understanding The Pure And Impure Functions in C#</title><link>https://ravindradevrani.com/posts/pure-impure-functions-in-csharp/</link><pubDate>Sun, 23 Feb 2025 11:38:07 +0530</pubDate><guid>https://ravindradevrani.com/posts/pure-impure-functions-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h2 id="pure-functions">Pure functions&lt;/h2>
&lt;p>Pure function is that:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Always returns the same output&lt;/strong> given the same inputs.&lt;/li>
&lt;li>&lt;strong>Does not modify the state of object&lt;/strong> or any external state.&lt;/li>
&lt;li>&lt;strong>Does not have any side effects&lt;/strong> such as I/O operations, exceptions or modifying external variables.&lt;/li>
&lt;/ol>
&lt;ul>
&lt;li>In other words, a pure function takes input, process it and returns the output without modifying anything else.&lt;/li>
&lt;li>Pure functions are easy to test and debug.&lt;/li>
&lt;/ul>
&lt;h2 id="examples">Examples&lt;/h2>
&lt;ol>
&lt;li>Mathematical calculations&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> Add(&lt;span style="color:#66d9ef">int&lt;/span> a, &lt;span style="color:#66d9ef">int&lt;/span> b)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> a + b;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="2">
&lt;li>String manipulation&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> Concatenate(&lt;span style="color:#66d9ef">string&lt;/span> a, &lt;span style="color:#66d9ef">string&lt;/span> b)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> a + b;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="3">
&lt;li>Array operations&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span>[] SortArray(&lt;span style="color:#66d9ef">int&lt;/span>[] array)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> array.OrderBy(x =&amp;gt; x).ToArray();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="4">
&lt;li>Data transformations&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> ConvertToString(&lt;span style="color:#66d9ef">int&lt;/span> &lt;span style="color:#66d9ef">value&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#66d9ef">value&lt;/span>.ToString();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="5">
&lt;li>Validation&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">bool&lt;/span> IsValidEmail(&lt;span style="color:#66d9ef">string&lt;/span> email)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> email.Contains(&lt;span style="color:#e6db74">&amp;#34;@&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="impure-functions">Impure Functions&lt;/h2>
&lt;p>Impure function is that&lt;/p></description></item><item><title>Command Pattern With C#</title><link>https://ravindradevrani.com/posts/command-pattern/</link><pubDate>Sun, 23 Feb 2025 11:30:44 +0530</pubDate><guid>https://ravindradevrani.com/posts/command-pattern/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;strong>The Command Pattern&lt;/strong> is a behavioral design pattern that turns a request into a stand-alone object containing all the information about the request. This conversion allows you to parameterize methods with different requests, queue requests, and support undoable operations.&lt;/p>
&lt;p>In simpler terms, the Command Pattern encapsulates a request as an object, thereby allowing users to decouple the sender (invoker) from the object that performs the action (receiver).&lt;/p></description></item><item><title>Adapter Pattern: Bridging the gap between incompatible interfaces</title><link>https://ravindradevrani.com/posts/adapter-pattern/</link><pubDate>Sun, 23 Feb 2025 11:23:31 +0530</pubDate><guid>https://ravindradevrani.com/posts/adapter-pattern/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;strong>The Adapter pattern&lt;/strong> is a structural design pattern that allows two incompatible interfaces to work together by converting the interface of one class into an interface expected by the clients. In other words, it acts as a bridge between two incompatible interfaces, enabling them to communicate with each other.&lt;/p>
&lt;h2 id="adapters-in-realworld">Adapters in real world?&lt;/h2>
&lt;p>For a phone that does not support a 3.5 mm audio jack, you can use a &lt;strong>USB-C to 3.5 mm audio adapter&lt;/strong>. The phone has only a USB-C port, so the adapter converts the USB-C connection into a 3.5 mm audio jack, allowing you to use traditional wired headphones with your phone. The adapter bridges the gap between the old headphone interface and the new phone design.&lt;/p></description></item><item><title>Facade Pattern With C#</title><link>https://ravindradevrani.com/posts/facade-pattern/</link><pubDate>Sun, 23 Feb 2025 11:07:40 +0530</pubDate><guid>https://ravindradevrani.com/posts/facade-pattern/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>The &lt;strong>Facade pattern&lt;/strong> is a &lt;strong>structural design pattern&lt;/strong> that provides a simplified interface to a complex system of classes or interfaces.&lt;/p>
&lt;p>Let’s understand it with example. Imagine a &lt;strong>home automation system&lt;/strong>.&lt;/p>
&lt;p>&lt;img src="https://ravindradevrani.com/images/1_JllHeIOXl6B2flbICm7jdg.png" alt="home automation system">&lt;/p>
&lt;p>Let’s implement it programmatically.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">FacadePatternTestDrive&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> Main(&lt;span style="color:#66d9ef">string&lt;/span>[] args)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ILights lights = &lt;span style="color:#66d9ef">new&lt;/span> Lights();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> IAirConditioner airConditioner = &lt;span style="color:#66d9ef">new&lt;/span> AirConditioner();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ISecuritySystem securitySystem = &lt;span style="color:#66d9ef">new&lt;/span> SecuritySystem();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// When leaving home&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> lights.TurnOff();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> airConditioner.TurnOff();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> securitySystem.Arm();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Console.WriteLine(&lt;span style="color:#e6db74">&amp;#34;You have left home.&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// When entering home&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> lights.TurnOn();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> airConditioner.TurnOn();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> securitySystem.Disarm();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Console.WriteLine(&lt;span style="color:#e6db74">&amp;#34;Welcome home!&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Note:&lt;/strong> AirConditioner, SecuritySystem and Lights class is not present in the above example for the sake of simplicity. We will write those classes when we implement the facade pattern.&lt;/p></description></item><item><title>Decorator Pattern With C#</title><link>https://ravindradevrani.com/posts/decorator-pattern/</link><pubDate>Sun, 23 Feb 2025 10:57:26 +0530</pubDate><guid>https://ravindradevrani.com/posts/decorator-pattern/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>The Decorator pattern is a structural pattern that enables you to wrap an object with additional behaviors or responsibilities without changing its external interface. It’s like adding layers of decorations to a gift — you can add or remove decorations without altering the gift itself.&lt;/p>
&lt;p>&lt;strong>Example:&lt;/strong>&lt;/p>
&lt;p>Let’s say, we have a book whose base price is 500 INR. Some buyers need a hard cover book which costs some extra money, some need a signed copy which also add some additional cost, some needs the both hard cover and a signed copy which adds more cost. May be in future we want to remove the option of hard cover book or may be we want to add some extra features to it. How do we make our system more flexible, that is the big question.&lt;/p></description></item><item><title>Observer Pattern</title><link>https://ravindradevrani.com/posts/observer-pattern/</link><pubDate>Sun, 23 Feb 2025 10:44:51 +0530</pubDate><guid>https://ravindradevrani.com/posts/observer-pattern/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>The &lt;strong>Observer pattern&lt;/strong> is a &lt;strong>behavioral design pattern&lt;/strong> that defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.&lt;/p>
&lt;p>In a simple words, it is like a publisher and subscriber pattern. When publisher publishes something, all it’s subscriber gets notified.&lt;/p>
&lt;p>One Example could be, when we subscribe someone’s mailing list we get notified whenever the publisher publishes something.&lt;/p></description></item><item><title>Abstract Factory Pattern With C#</title><link>https://ravindradevrani.com/posts/abstract-factory-pattern/</link><pubDate>Sun, 23 Feb 2025 10:29:26 +0530</pubDate><guid>https://ravindradevrani.com/posts/abstract-factory-pattern/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>The &lt;strong>Abstract Factory pattern&lt;/strong> is a creational design pattern that &lt;strong>provides an interface for creating families of related or dependent objects without specifying their concrete classes&lt;/strong>. It allows a client to create objects from a variety of related classes without needing to know the specifics of their implementations.&lt;/p>
&lt;h2 id="gui-factoryexample">GUI Factory Example&lt;/h2>
&lt;p>Let’s say, we need to create GUI components for different themes in our application. Each theme includes a consistent set of components such as buttons and checkboxes. We want to ensure that the creation of these components is consistent and interchangeable.&lt;/p></description></item><item><title>Factory Method Pattern with c#</title><link>https://ravindradevrani.com/posts/factory-method-pattern/</link><pubDate>Sun, 23 Feb 2025 10:19:59 +0530</pubDate><guid>https://ravindradevrani.com/posts/factory-method-pattern/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>The &lt;strong>Factory Method Pattern&lt;/strong> is a creational design pattern that provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created.&lt;/p>
&lt;p>This pattern is useful when a class cannot anticipate the class of objects it needs to create or when subclasses want to specify the objects to be created.&lt;/p>
&lt;h2 id="a-notification-system">A Notification System&lt;/h2>
&lt;p>Imagine we need to develop a notification system that can send different types of notifications such as Email, SMS, and Push Notifications. Each type of notification has a distinct implementation but shares a common interface. Instead of creating each notification type directly in our main logic, we can use the &lt;strong>Factory Method Pattern&lt;/strong> to encapsulate the instantiation process, making our code more modular and extensible.&lt;/p></description></item><item><title>Understanding Aggregation: How It Differs from Composition</title><link>https://ravindradevrani.com/posts/aggregation-in-oops/</link><pubDate>Sun, 23 Feb 2025 08:37:49 +0530</pubDate><guid>https://ravindradevrani.com/posts/aggregation-in-oops/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;strong>Aggregation&lt;/strong> is when an object is made up of one or more objects, but those objects can live outside the main object. It defines the &lt;strong>has-a&lt;/strong> relationship.&lt;/p>
&lt;p>&lt;strong>Note&lt;/strong>: In the aggregation, if main object is destroyed, its aggregated objects may still live.&lt;/p>
&lt;p>&lt;strong>Example #1:&lt;/strong> A &lt;code>Library&lt;/code> is an aggregation of &lt;code>Books&lt;/code>. Books can live without the library.&lt;/p>
&lt;p>&lt;strong>Example #2:&lt;/strong> A &lt;code>Department&lt;/code> is an aggregation of &lt;code>Employees&lt;/code>. If department closes, the Employees can exist on their own.&lt;/p></description></item><item><title>Composition: What, Why And When?</title><link>https://ravindradevrani.com/posts/composition-what-why-and-when/</link><pubDate>Sun, 23 Feb 2025 08:19:49 +0530</pubDate><guid>https://ravindradevrani.com/posts/composition-what-why-and-when/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;strong>Composition&lt;/strong> is when your class is composed of one or more objects from other classes. A simple example is a &lt;code>Car&lt;/code> composed of &lt;code>Engine&lt;/code> and &lt;code>Wheel&lt;/code> objects. &lt;strong>Inheritance&lt;/strong> defines an &lt;strong>&amp;ldquo;is-a&amp;rdquo;&lt;/strong> relationship, while &lt;strong>composition&lt;/strong> defines a &lt;strong>&amp;ldquo;has-a&amp;rdquo;&lt;/strong> relationship.&lt;/p>
&lt;p>For example, &lt;code>Dog&lt;/code> &lt;strong>is-a&lt;/strong> &lt;code>Animal&lt;/code>, and &lt;code>Circle&lt;/code> &lt;strong>is-a&lt;/strong> &lt;em>Shape&lt;/em>. It defines inheritance.&lt;/p>
&lt;p>This makes sense because you want to reuse all the features of &lt;code>Animal&lt;/code> (eat, sleep, walk, makeNoise) in the &lt;code>Dog&lt;/code> class. &lt;code>Cow&lt;/code> is-a Animal too, so &lt;code>Cow&lt;/code> can also inherit the &lt;code>Animal&lt;/code> class. Since &lt;strong>cows&lt;/strong> and &lt;strong>dogs&lt;/strong> make different noises and eat different things, we have to redefine or override the &lt;code>makeNoise()&lt;/code> and &lt;code>eat()&lt;/code> methods in the &lt;code>Dog&lt;/code> and &lt;code>Cow&lt;/code> classes. The point is when we want to reuse the functionality of a class and also want subtype polymorphism (&lt;code>Dog&lt;/code> and &lt;code>Cow&lt;/code> are subtypes of &lt;code>Animal&lt;/code>), then we must use &lt;strong>inheritance&lt;/strong>.&lt;/p></description></item><item><title>The Dependency Inversion Principle (DIP)</title><link>https://ravindradevrani.com/posts/dependency-inversion-principle/</link><pubDate>Sat, 22 Feb 2025 21:50:00 +0530</pubDate><guid>https://ravindradevrani.com/posts/dependency-inversion-principle/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>The &lt;strong>Dependency Inversion Principle&lt;/strong> states that:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>High-level modules&lt;/strong> should not depend on &lt;strong>low-level modules&lt;/strong>. Both should depend on &lt;strong>abstractions&lt;/strong> (e.g., interfaces).&lt;/li>
&lt;li>&lt;strong>Abstractions&lt;/strong> should not depend on &lt;strong>details&lt;/strong>. &lt;strong>Details&lt;/strong> (concrete implementations) should depend on &lt;strong>abstractions&lt;/strong>.&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>Source:&lt;/strong> &lt;a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle" title="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Wikipedia&lt;/a>&lt;/p>
&lt;p>Other SOLID Principles&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/single-responsibility-principle/">Single Responsibility Principle&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/open-closed-principle/">Open Closed Principle&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/liskov-substitution-principle/">Liskov Substitution Problem&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/interface-segregation-principle/">Interface Segregation Principle&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="example-withoutdip">Example without DIP&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">UserRepository&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> GetUserById(&lt;span style="color:#66d9ef">int&lt;/span> id)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Code to fetch user from the database&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#e6db74">&amp;#34;User&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">UserService&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> &lt;span style="color:#66d9ef">readonly&lt;/span> UserRepository _userRepository;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> UserService()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> _userRepository = &lt;span style="color:#66d9ef">new&lt;/span> UserRepository();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> GetUser(&lt;span style="color:#66d9ef">int&lt;/span> id)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> _userRepository.GetUserById(id);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>One problem with this code is , the&lt;code>UserService&lt;/code> is tightly coupled with the &lt;code>UserRepository&lt;/code>. Another problem is, if you want to use different implementation of &lt;code>UserReposoitory&lt;/code>, you can not easily do it. For instance you want to swap your &lt;code>UserRepsoitory&lt;/code> to &lt;code>UserRepositoryWithDifferentDatabase&lt;/code>.&lt;/p></description></item><item><title>The Interface Segregation Principle (ISP)</title><link>https://ravindradevrani.com/posts/interface-segregation-principle/</link><pubDate>Sat, 22 Feb 2025 21:35:42 +0530</pubDate><guid>https://ravindradevrani.com/posts/interface-segregation-principle/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>📢 Clients should not be forced to depend on interfaces they do not use.&lt;/p>
&lt;p>In simpler terms, this principle suggests that an interface should not include methods that implementing classes don’t need. It Encourages us to create smaller interfaces over the big fat interface.&lt;/p>
&lt;p>Other SOLID principles&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/single-responsibility-principle/">Single Responsibility Principle&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/open-closed-principle/">Open Closed Principle&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/liskov-substitution-principle/">Liskov Substitution Problem&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/dependency-inversion-principle/">Dependency Inversion Principle&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="violating-example">Violating example&lt;/h2>
&lt;p>Imagine you have an interface for workers in a company:&lt;/p></description></item><item><title>The Liskov Substitution Principle (LSP)</title><link>https://ravindradevrani.com/posts/liskov-substitution-principle/</link><pubDate>Sat, 22 Feb 2025 20:58:52 +0530</pubDate><guid>https://ravindradevrani.com/posts/liskov-substitution-principle/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>The &lt;strong>Liskov Substitution Principle&lt;/strong> states that a derived type should be completely replaceable for its base type.&lt;/p>
&lt;p>In simpler terms, a child class should do at least what the parent class can do. The child class can have additional behaviors, but it must have all the behaviors that the parent class has.&lt;/p>
&lt;p>For instance, an &lt;strong>Animal&lt;/strong> has behaviors (eat, sleep, makeSound). A &lt;strong>Dog&lt;/strong>, which is a subtype of &lt;strong>Animal&lt;/strong>, must have all the behaviors (eat, sleep, makeSound).&lt;/p></description></item><item><title>Open Closed Principle (OCP)</title><link>https://ravindradevrani.com/posts/open-closed-principle/</link><pubDate>Sat, 22 Feb 2025 19:24:26 +0530</pubDate><guid>https://ravindradevrani.com/posts/open-closed-principle/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>The &lt;strong>Open-Closed Principle&lt;/strong> is one of the five &lt;strong>SOLID&lt;/strong> principles. It states that a class should be open for extension but closed for modification. In other words, you should be able to add new functionality without changing existing code.&lt;/p>
&lt;p>Once you have written your class, it should not be modified in the future. However, this doesn’t mean you cannot modify your class during early development stages. It means that once your application or software is in production and you want to introduce the new functionality, you should extend that class rather than modifying it.&lt;/p></description></item><item><title>Single Responsibility Principle (SRP)</title><link>https://ravindradevrani.com/posts/single-responsibility-principle/</link><pubDate>Sat, 22 Feb 2025 19:03:39 +0530</pubDate><guid>https://ravindradevrani.com/posts/single-responsibility-principle/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>The &lt;code>Single Responsibility Principle (SRP)&lt;/code> is a cornerstone of object-oriented design, closely associated with the &lt;code>SOLID principles&lt;/code>. It emphasizes that &lt;strong>a class should have only one reason to change&lt;/strong>, meaning it should have a single responsibility or purpose.&lt;/p>
&lt;h3 id="what-issrp">What is SRP?&lt;/h3>
&lt;p>The principle asserts that &lt;strong>a class should do only one thing and do it very well&lt;/strong>. This doesn’t imply that a class should have only one method or behavior, but rather that it should contain a cohesive set of behaviors related to a single responsibility.&lt;/p></description></item><item><title>Image Upload CRUD Operations in .NET Core WebAPIs</title><link>https://ravindradevrani.com/posts/image-upload-crud-operations-in-dotnet-core-apis/</link><pubDate>Sat, 22 Feb 2025 18:28:32 +0530</pubDate><guid>https://ravindradevrani.com/posts/image-upload-crud-operations-in-dotnet-core-apis/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>Upload images in .net core apis&lt;/p>
&lt;p>In this article, we will learn how to upload/update/delete/read images in .net core APIs. I hate to give long and unnecessary intros, So let’s come to the point’s.&lt;/p>
&lt;p>💻 You can get the code from this &lt;a href="https://github.com/rd003/ImageManipulation_APIs_DotNetCore">github repo&lt;/a>.&lt;/p>
&lt;h2 id="what-is-the-logic-behind-it-">What is the logic behind it? 🤔&lt;/h2>
&lt;p>When you upload the image (or any file), we will generate the unique image name with it’s extension (eg. uniquename.png). Save the image name in the database and save the file with the same name inside the project. In production apps, you can not simply upload files to the server, you have to give permission to that folder. Or you can use other file storage service, where you will save your files.&lt;/p></description></item><item><title>Separating the DI Setup From Program.cs file</title><link>https://ravindradevrani.com/posts/separating-di-setup-from-program-cs-file/</link><pubDate>Sat, 22 Feb 2025 18:18:10 +0530</pubDate><guid>https://ravindradevrani.com/posts/separating-di-setup-from-program-cs-file/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>Let’s take a look at the &lt;strong>program.cs&lt;/strong> file below.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> InventoryMgt.Api.Middlewares;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> InventoryMgt.Data.Repositories;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> builder = WebApplication.CreateBuilder(args);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Add services to the container.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddControllers();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddEndpointsApiExplorer();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddSwaggerGen();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;ICategoryRepository, CategoryRepository&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;IProductRepository, ProductRepository&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;IPurchaseRepository, PurchaseRepository&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;IStockRepository, StockRepository&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;ISaleRepository, SaleRepository&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddTransient&amp;lt;ExceptionMiddleware&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>builder.Services.AddCors(options =&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> options.AddDefaultPolicy(policy =&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> policy.WithOrigins(&lt;span style="color:#e6db74">&amp;#34;*&amp;#34;&lt;/span>).AllowAnyHeader().AllowAnyMethod().WithExposedHeaders(&lt;span style="color:#e6db74">&amp;#34;X-Pagination&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> });
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>});
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> app = builder.Build();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Configure the HTTP request pipeline.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> (app.Environment.IsDevelopment())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> app.UseSwagger();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> app.UseSwaggerUI();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.UseHttpsRedirection();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.UseCors();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.UseAuthorization();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.ConfigureExceptionMiddleware();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.MapControllers();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>app.Run();
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It is a regular &lt;strong>program.cs&lt;/strong> file. Since we use the dependency injection in our application, we have to register lots of service in our &lt;strong>program.cs&lt;/strong> file. For example:&lt;/p></description></item><item><title>Private Constructor in C#</title><link>https://ravindradevrani.com/posts/private-constructor-in-csharp/</link><pubDate>Fri, 21 Feb 2025 10:20:08 +0530</pubDate><guid>https://ravindradevrani.com/posts/private-constructor-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In C#, a private constructor is a constructor method declared with the &lt;code>private&lt;/code> access modifier (or without mentioning any modifier). If a class have only a private constructor and does not have any public constructor, then you are not able to create the instance of a class. Example 👇&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">Student&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Student() { } &lt;span style="color:#75715e">// private constructor&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">Program&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> Main()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Student stu = &lt;span style="color:#66d9ef">new&lt;/span>(); &lt;span style="color:#75715e">//Error CS0122 &amp;#39;Student.Student()&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// is inaccessible due to its protection level&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>When you try to create the instance of stu, you will the following error.&lt;/p></description></item><item><title>Generic Delegates (Action, Func &amp; Predicates) in C#</title><link>https://ravindradevrani.com/posts/generic-delegates-action-func-predicate-in-csharp/</link><pubDate>Fri, 21 Feb 2025 09:54:50 +0530</pubDate><guid>https://ravindradevrani.com/posts/generic-delegates-action-func-predicate-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In C#, &lt;a href="https://ravindradevrani.com/posts/delegates-anonymous-method-and-lambda-expression/">&lt;strong>delegates&lt;/strong>&lt;/a> are used to refer to methods with a specific signature. &lt;code>Generic delegates&lt;/code> extend this concept by allowing you to create delegates that can work with any method signature, rather than being tied to a specific signature.&lt;/p>
&lt;p>Here’s a basic example of a generic delegate:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">delegate&lt;/span> T MyGenericDelegate&amp;lt;T&amp;gt;(T arg);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can use this generic delegate as follows.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>MyGenericDelegate&amp;lt;&lt;span style="color:#66d9ef">int&lt;/span>&amp;gt; handler1 = CustomSquare;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> square=handler1(&lt;span style="color:#ae81ff">4&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Console.WriteLine(square); &lt;span style="color:#75715e">//16&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>MyGenericDelegate&amp;lt;&lt;span style="color:#66d9ef">string&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">\&lt;/span>&amp;gt; handler2 = CustomToUpper;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Console.WriteLine(CustomToUpper(&lt;span style="color:#e6db74">&amp;#34;helLo&amp;#34;&lt;/span>)); &lt;span style="color:#75715e">//HELLO&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="in-built-generic-delegates">In-built Generic delegates&lt;/h2>
&lt;p>C# comes with inbuilt generic delegates like &lt;code>Action&lt;/code>, &lt;code>Func&lt;/code> and &lt;code>Predicate&lt;/code>.&lt;/p></description></item><item><title>Delegates, Anonymous Method and Lambda Expression</title><link>https://ravindradevrani.com/posts/delegates-anonymous-method-and-lambda-expression/</link><pubDate>Fri, 21 Feb 2025 09:31:26 +0530</pubDate><guid>https://ravindradevrani.com/posts/delegates-anonymous-method-and-lambda-expression/</guid><description>&lt;!-- raw HTML omitted -->
&lt;ul>
&lt;li>Delegates in C# are essentially type-safe function pointers.&lt;/li>
&lt;li>They allow you to treat methods as objects, enabling you to pass methods as parameters, store them in variables, and invoke them dynamically.&lt;/li>
&lt;li>Delegates are particularly useful for implementing callback mechanisms and event handling in C#.&lt;/li>
&lt;/ul>
&lt;p>delegate void MyDelegate(string message);&lt;/p>
&lt;p>You can point this delegate to any method with similar signature.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">namespace&lt;/span> BasicsOfCSharp;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Declare a delegate type&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">delegate&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> MyDelegate(&lt;span style="color:#66d9ef">string&lt;/span> message);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">Program&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Method that matches the delegate signature&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> DisplayMessage(&lt;span style="color:#66d9ef">string&lt;/span> message)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Console.WriteLine(&lt;span style="color:#e6db74">&amp;#34;Message: &amp;#34;&lt;/span> + message);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> Main()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Instantiate the delegate.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> MyDelegate handler = DisplayMessage;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// calling the handler&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> handler(&lt;span style="color:#e6db74">&amp;#34;Hello..&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>👉Multicast Delegate:&lt;/strong>&lt;/p></description></item><item><title>Abstract Class in C#</title><link>https://ravindradevrani.com/posts/abstract-class-in-csharp/</link><pubDate>Fri, 21 Feb 2025 09:20:13 +0530</pubDate><guid>https://ravindradevrani.com/posts/abstract-class-in-csharp/</guid><description>&lt;p>In c#, Abstract class is a class that can not be instantiated on its own&lt;/p>
&lt;!-- raw HTML omitted -->
&lt;ul>
&lt;li>In c#, &lt;code>Abstract class&lt;/code> is a class that can not be instantiated on its own&lt;/li>
&lt;li>It is typically used as a &lt;code>base class&lt;/code> for other class.&lt;/li>
&lt;li>&lt;code>Abstract class&lt;/code> provides a way to achieve &lt;a href="https://medium.com/@ravindradevrani/abstraction-in-c-c3d4c832942a">&lt;code>abstraction&lt;/code>&lt;/a>, because there you can just declare the methods (abstract methods) and implement them later.&lt;/li>
&lt;li>It can contain both &lt;code>abstract methods&lt;/code> (methods without implementation details) and &lt;code>non-abstract methods&lt;/code> (method with implementation details).&lt;/li>
&lt;li>Similar goal can be achieved with &lt;code>interface&lt;/code>, but in abstract class you can also define non-abstract method. These methods are needed when you need to share some common functionality.&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">abstract&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">Shape&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// it is the basic syntax of abstract class&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Example:&lt;/p></description></item><item><title>Polymorphism in depth with C#</title><link>https://ravindradevrani.com/posts/polymorphism-in-csharp/</link><pubDate>Thu, 20 Feb 2025 19:49:29 +0530</pubDate><guid>https://ravindradevrani.com/posts/polymorphism-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>Polymorphism is one of the core concept of object oriented programming. Word &lt;strong>polymorphism = poly (many) + morphism (forms)&lt;/strong>. As its name suggesting polymorphism means, an entity can have multiple forms.&lt;/p>
&lt;p>📢 Updated and refinded at : 21-feb-2025&lt;/p>
&lt;p>&lt;strong>Other oops core concepts :&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/abstraction-in-csharp/">Abstraction in C#&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/encapsulation-in-csharp/">Encapsulation in C#&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/inheritance-in-csharp/">Inheritance in c#&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Let’s learn polymorphism through mistakes.&lt;/p>
&lt;p>Jim requires an entry system for his pet shop, which exclusively houses various breeds of dogs. This system will manage the entry and records of all dogs entering and exiting the premises.&lt;/p></description></item><item><title>Inheritance in C#</title><link>https://ravindradevrani.com/posts/inheritance-in-csharp/</link><pubDate>Thu, 20 Feb 2025 19:49:18 +0530</pubDate><guid>https://ravindradevrani.com/posts/inheritance-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>📢 Updated and refinded at : 21-feb-2025&lt;/p>
&lt;p>Inheritance is a fundamental concept in OOPs that allows a class to inherit properties and behaviors of another class. We have two key terms are here &lt;strong>base class/superclass&lt;/strong> and &lt;strong>derived class/subclass.&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Base class / super-class:&lt;/strong> Whose members and functionality are inherited (Giver).&lt;/li>
&lt;li>&lt;strong>Derived class / sub-class:&lt;/strong> Who is inheriting the members (Taker)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>📺Other oops concepts:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/abstraction-in-csharp/">Abstraction in C#&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/encapsulation-in-csharp/">Encapsulation in C#&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://ravindradevrani.com/posts/polymorphism-in-csharp/">Polymorphism in C#&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Syntax of inheritance:&lt;/strong>&lt;/p></description></item><item><title>Encapsulation in C#</title><link>https://ravindradevrani.com/posts/encapsulation-in-csharp/</link><pubDate>Thu, 20 Feb 2025 19:41:25 +0530</pubDate><guid>https://ravindradevrani.com/posts/encapsulation-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>📢 Updated and refinded at : 21-feb-2025&lt;/p>
&lt;p>&lt;strong>Bundling the data member and member function into a single unit&lt;/strong> is called &lt;strong>encapsulation&lt;/strong>. Remember the term &lt;strong>“capsule”&lt;/strong>. We put all the medicine inside a wrapper and call it capsule. Similarly, wrap the data members and member functions together is called encapsulation.&lt;/p>
&lt;p>Now we need to understand few terms.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Data members&lt;/strong> : Attributes or properties (eg. name, age)&lt;/li>
&lt;li>&lt;strong>Member functions&lt;/strong>: Methods (PrintDetails)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>👉 We wrap up the data members (&lt;em>attributes or properties&lt;/em>) and member functions (&lt;em>methods&lt;/em>) into a single unit (&lt;em>class&lt;/em>).&lt;/strong>&lt;/p></description></item><item><title>Abstraction in C#</title><link>https://ravindradevrani.com/posts/abstraction-in-csharp/</link><pubDate>Thu, 20 Feb 2025 19:09:36 +0530</pubDate><guid>https://ravindradevrani.com/posts/abstraction-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>📢 Updated and refinded at : 21-feb-2025&lt;/p>
&lt;p>&lt;strong>Abstraction&lt;/strong> allows you to focus on the relevant details of an object while ignoring unnecessary complexities.&lt;br>
This is achieved by defining a simplified representation of an object that &lt;strong>hides the implementation details and exposes only the necessary features&lt;/strong>.&lt;br>
In practical terms, &lt;strong>abstraction is implemented through abstract classes and interfaces in languages like C#&lt;/strong>.&lt;/p>
&lt;p>&lt;strong>📺Other OOPs related articles :&lt;/strong>&lt;/p></description></item><item><title>Fluent Validation in Dotnet Core</title><link>https://ravindradevrani.com/posts/fluent-validation-in-dotnet-core/</link><pubDate>Thu, 20 Feb 2025 18:39:45 +0530</pubDate><guid>https://ravindradevrani.com/posts/fluent-validation-in-dotnet-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h2 id="fluent-validation">Fluent validation&lt;/h2>
&lt;p>Fluent validation is an open source library for validating the models, which is free as of I am writing this article.&lt;/p>
&lt;p>📢 📝 &lt;strong>Last Updated:&lt;/strong> 25-March-2025&lt;/p>
&lt;h2 id="why-fluent-validation">Why fluent validation?&lt;/h2>
&lt;p>If you already have used data annotation for validation, then you must be aware of the validation in .NET. So you might be thinking why do we need a &lt;code>fluent validation&lt;/code> then.&lt;/p>
&lt;p>&lt;code>Fluent validation&lt;/code> helps you to separate validation logic from your models. That makes your code clean. If you have complex validation logic, then you want to define it separately rather than making your model unreadable.&lt;/p></description></item><item><title>Uploading Images in Blazor Server</title><link>https://ravindradevrani.com/posts/uploading-images-in-blazor-server/</link><pubDate>Thu, 20 Feb 2025 18:25:51 +0530</pubDate><guid>https://ravindradevrani.com/posts/uploading-images-in-blazor-server/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this blog post we are going to learn how to upload files in the blazor server application. I am going to upload &lt;strong>images&lt;/strong> in this tutorial but you can upload &lt;strong>any file&lt;/strong> (i have created &lt;strong>reusable code&lt;/strong>).&lt;/p>
&lt;p>💻Source Code: &lt;a href="https://github.com/rd003/BlazorFile/">https://github.com/rd003/BlazorFile/&lt;/a>&lt;/p>
&lt;h2 id="high-leveloverview">High level overview&lt;/h2>
&lt;p>We will upload images to a &lt;strong>folder of a local machine&lt;/strong> ( on a production you have to use cloud storage) with a unique name (e.g. &lt;code>sd$3abccc3$1.png&lt;/code> ), that name is going to save in database.&lt;/p></description></item><item><title>Easiest Way to Handle Csv Files in Csharp</title><link>https://ravindradevrani.com/posts/easiest-way-to-handle-csv-files-in-csharp/</link><pubDate>Thu, 20 Feb 2025 17:58:49 +0530</pubDate><guid>https://ravindradevrani.com/posts/easiest-way-to-handle-csv-files-in-csharp/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this tutorial we will se how to read and write data to &lt;strong>csv&lt;/strong> file. It is pretty much easy if you have some external library for that. We are definitely going to use a library and that will be &lt;strong>CsvHelper&lt;/strong>.&lt;/p>
&lt;p>You can also check the video version of this tutorial.&lt;/p>
&lt;p>First and foremost, create a &lt;strong>c# console application&lt;/strong> in .net core. After that we need to install a nuget package, which is&lt;code>**CsvHelper**&lt;/code>&lt;/p></description></item><item><title>Multiple Ways to Find Duplicates in Csharp Array</title><link>https://ravindradevrani.com/posts/multiple-ways-to-find-duplicates-in-csharp-array/</link><pubDate>Thu, 20 Feb 2025 17:49:19 +0530</pubDate><guid>https://ravindradevrani.com/posts/multiple-ways-to-find-duplicates-in-csharp-array/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In C#, we can use various approaches to find duplicate elements in array. Each have pros and cons. We will use 3 approaches in this article.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Using a HashSet&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Using a Dictionary&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Using LINQ&lt;/strong>&lt;/li>
&lt;/ol>
&lt;p>Lets take this array as an example, from this array we will extract &lt;strong>distinct numbers&lt;/strong> and &lt;strong>duplicate numbers.&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-cs" data-lang="cs">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span>[] numbers = { &lt;span style="color:#ae81ff">4&lt;/span>,&lt;span style="color:#ae81ff">7&lt;/span>, &lt;span style="color:#ae81ff">2&lt;/span>, &lt;span style="color:#ae81ff">3&lt;/span>, &lt;span style="color:#ae81ff">4&lt;/span>, &lt;span style="color:#ae81ff">5&lt;/span>, &lt;span style="color:#ae81ff">3&lt;/span>, &lt;span style="color:#ae81ff">6&lt;/span>, &lt;span style="color:#ae81ff">7&lt;/span>, &lt;span style="color:#ae81ff">8&lt;/span>,&lt;span style="color:#ae81ff">1&lt;/span>, &lt;span style="color:#ae81ff">8&lt;/span> };
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We will use this array in all three approaches. So let’s understand one by one.&lt;/p></description></item><item><title>C# Dictionary and Its Use Cases</title><link>https://ravindradevrani.com/posts/csharp-dictionary-and-its-use-cases/</link><pubDate>Thu, 20 Feb 2025 17:40:42 +0530</pubDate><guid>https://ravindradevrani.com/posts/csharp-dictionary-and-its-use-cases/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h2 id="what-is-dictionary">What is dictionary?&lt;/h2>
&lt;p>Dictionary is a collection, that store the value in the form of key value pair. It allows you to quick access of value using the key. This data structure is widely used in programming because of its fast look-up time, which makes it ideal for applications that require quick data retrieval&lt;/p>
&lt;p>👉 You can not add duplicate key in dictionary&lt;/p>
&lt;p>&lt;strong>Creating a dictionary:&lt;/strong>&lt;/p></description></item><item><title>Catch Exception Globally in Dotnet Core Apis</title><link>https://ravindradevrani.com/posts/catch-exception-globally-in-dotnet-core-apis/</link><pubDate>Thu, 20 Feb 2025 17:28:02 +0530</pubDate><guid>https://ravindradevrani.com/posts/catch-exception-globally-in-dotnet-core-apis/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>There are to ways of catching exception in .net core, one is using try/catch and other one is catching them globally. Although there is nothing wrong with &lt;strong>try/catch&lt;/strong> blog, it is an elegant way of exception handling. Although you can also catch exceptions globally, If you want to log errors in one place. There are various approaches to achieve this, but we will create the custom middleware to achieve it.&lt;/p></description></item><item><title>Output Caching With Dotnet 7</title><link>https://ravindradevrani.com/posts/output-caching-with-dotnet-7/</link><pubDate>Thu, 20 Feb 2025 16:20:16 +0530</pubDate><guid>https://ravindradevrani.com/posts/output-caching-with-dotnet-7/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h3 id="what-iscaching">What is Caching?&lt;/h3>
&lt;p>Caching is a process of temporarily storing frequently accessed data or
resources in a faster and closer location to the user or application,
with the goal of reducing the time and resources needed to retrieve that
data from its original source. By keeping a copy of the data nearby,
caching enables quicker access and improves the overall performance and
responsiveness of applications.&lt;/p></description></item><item><title>JWT Authentication and Role Based Authorization in Dotnet Core</title><link>https://ravindradevrani.com/posts/jwt-authentication-and-role-based-authorization-in-dotnet-core/</link><pubDate>Thu, 20 Feb 2025 10:31:52 +0530</pubDate><guid>https://ravindradevrani.com/posts/jwt-authentication-and-role-based-authorization-in-dotnet-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;h2 id="jwt">JWT&lt;/h2>
&lt;p>According to &lt;a href="https://jwt.io/">jwt.io&lt;/a> JSON Web Tokens are an open, industry standard &lt;a href="https://tools.ietf.org/html/rfc7519">&lt;strong>RFC7519&lt;/strong>&lt;/a> method for representing claims securely between two parties.&lt;/p>
&lt;p>When we create REST APIs, then we don&amp;rsquo;t want that any one can access
those apis. REST APIs, will only be accessed by the authenticated user.
We authenticate our user with the help of jwt.&lt;/p>
&lt;p>&lt;strong>How jwt works?&lt;/strong>&lt;/p>
&lt;p>First, we give an authentication endpoint to user, where he/she puts
credential, in return we give a jwt token to user which have an expiry
date. To consume any protected resource, user need to pass jwt token on
authorization header.&lt;/p></description></item><item><title>Create Sln File With Multiple Projects</title><link>https://ravindradevrani.com/posts/create-sln-file-with-multiple-projects/</link><pubDate>Wed, 19 Feb 2025 22:55:02 +0530</pubDate><guid>https://ravindradevrani.com/posts/create-sln-file-with-multiple-projects/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In this article we will learn how to create a .net core
project with a Solution (sln file) that contains multiple projects. I
know most you guys use visual studio for c# related stuff, but it would
be benificial for person who likes to switch with vs code ocassionally,
like me or who use linux and forced to use .net cli. Although if you are
a new developer and have windows operating system, I will recommend
visual studio, because it is the best possible IDE for c# development.&lt;/p></description></item><item><title>Ngrx Entity and Effects</title><link>https://ravindradevrani.com/posts/ngrx-entity-and-effects/</link><pubDate>Wed, 19 Feb 2025 22:29:18 +0530</pubDate><guid>https://ravindradevrani.com/posts/ngrx-entity-and-effects/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;code>NGRX Entity&lt;/code> gives you an efficient and quick way to
deal with ngrx store related operations, such as
read, write, update, delete. You can focus on productivity, rather than
creating and modifeng complex state everytime. It can be very helpful
when you are dealing with complex state and handling with http services
at the same time.&lt;/p>
&lt;h2 id="what-is-ngrx">What is ngrx ?&lt;/h2>
&lt;p>Ngrx is a state management library, that stores the state globally. Lets
understand some of its components.&lt;/p></description></item><item><title>Api Versioning in Dotnet Core</title><link>https://ravindradevrani.com/posts/api-versioning-in-dotnet-core/</link><pubDate>Wed, 19 Feb 2025 22:07:03 +0530</pubDate><guid>https://ravindradevrani.com/posts/api-versioning-in-dotnet-core/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;a href="https://unsplash.com/@thekidph?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText">Photo by Jan Loyde Cabrera at medium.com&lt;/a>&lt;/p>
&lt;p>When you are going to do some breaking changes in your apis, it is better to create a new version for that, so that user don&amp;rsquo;t freaked out. They still can use the older APIs and get ready for new
changes. There are various way to create a versions of your APIs like&lt;/p>
&lt;ol>
&lt;li>Query string&lt;/li>
&lt;li>URL&lt;/li>
&lt;li>HTTP header&lt;/li>
&lt;/ol>
&lt;blockquote>
&lt;p>If you prefer video version then you can checkout this video with same content.&lt;/p></description></item><item><title>Angular Autocomlete With Ng Select</title><link>https://ravindradevrani.com/posts/angular-autocomlete-with-ng-select/</link><pubDate>Wed, 19 Feb 2025 21:52:46 +0530</pubDate><guid>https://ravindradevrani.com/posts/angular-autocomlete-with-ng-select/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>There are various packages available for implementing autocomplete in
angular and we are going to use the simplest one (ng-select).&lt;/p>

 &lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/BysbysXMEro?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="Angular Autocomlete With Ng Select">&lt;/iframe>
 &lt;/div>

&lt;p>Let&amp;rsquo;s finish talking and need to start write code. Let&amp;rsquo;s install ng-select package from command line&lt;/p>
&lt;p>&lt;code>npm install --save @ng-select/ng-select&lt;/code>&lt;/p></description></item><item><title>Angular pagination with infinite scroll (using ngx-infite-scroll)</title><link>https://ravindradevrani.com/posts/angular-pagination-with-infinite-scroll/</link><pubDate>Wed, 19 Feb 2025 21:24:41 +0530</pubDate><guid>https://ravindradevrani.com/posts/angular-pagination-with-infinite-scroll/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;strong>Photo by&lt;/strong> &lt;a href="https://unsplash.com/ko/@azinber?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText">&lt;strong>&lt;em>Ajda ATZ&lt;/em>&lt;/strong>&lt;/a> &lt;strong>on&lt;/strong> &lt;a href="https://unsplash.com/photos/Dz4iJ3v4-X4?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText">&lt;strong>&lt;em>Unsplash&lt;/em>&lt;/strong>&lt;/a>&lt;/p>
&lt;p>Sometimes we get a condition where you don’t want to display all the data at once. Initially we display some data, and when we scroll down ,we loads more data. This kind of behaviour you can see in youtube, instagram or facebook. You might even spend much time of your day on just scrolling down. So we are gonna learn how to do that.&lt;/p></description></item><item><title>Write dapper effectively with generic methods</title><link>https://ravindradevrani.com/posts/write-dapper-effectively-with-generic-methods/</link><pubDate>Wed, 19 Feb 2025 17:40:41 +0530</pubDate><guid>https://ravindradevrani.com/posts/write-dapper-effectively-with-generic-methods/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>&lt;strong>Dapper&lt;/strong> is a micro ORM for database connectivity in
dotnet and it&amp;rsquo;s been around for quite a while. It is loved by most of
the developers because of its simplicity and performance.&lt;/p>
&lt;h3 id="why-dapper">&lt;strong>Why dapper?&lt;/strong>&lt;/h3>
&lt;p>With the help of dapper you can quickly access the data without writing
too much code. It performs very well because we directly write queries
and executes them. Developers who loves to work with queries and for the
projects, where performance really matters where you wants to write very
optimized queries, dapper can be the good choice.&lt;/p></description></item><item><title>Serilog in .NET</title><link>https://ravindradevrani.com/posts/serilog-in-dotnet/</link><pubDate>Wed, 19 Feb 2025 15:40:41 +0530</pubDate><guid>https://ravindradevrani.com/posts/serilog-in-dotnet/</guid><description>&lt;!-- raw HTML omitted -->
&lt;p>In your development journey you have faced so many runtime exceptions. You have handled that with try catch block. But in the runtime you never know where that error has happened and you have to
trace that whole section with putting breakpoints. Sometime you have thought that I wish.. I would get notified whenever that exception occur. Then the logging frameworks comes in the play.&lt;/p></description></item><item><title>About</title><link>https://ravindradevrani.com/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ravindradevrani.com/about/</guid><description>&lt;p>&lt;strong>Ravindra Devrani&lt;/strong> is fullstack developer, works with .NET and Angular. He has been professionally writing code since 2015. His prefered tech stack is .NET, angular, sql server azure. He also love to explore other tech stack like nodejs, postgres and react. He is more passionate in backend development. In is spare time, he writes blog posts and make technical videos on &lt;a href="https://www.youtube.com/@ravindradevrani">youtube&lt;/a>.&lt;/p>
&lt;p>His handles:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://twitter.com/ravi_devrani">Twitter&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/rd003">GitHub&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtube.com/@ravindradevrani">YouTube&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Free Courses On My Youtube Channel</title><link>https://ravindradevrani.com/free-courses/free-courses/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ravindradevrani.com/free-courses/free-courses/</guid><description>&lt;h2 id="courses">Courses&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://youtu.be/0T8CAdx3sFs?si=FTMAsb1o-SlXwzG7">.NET Core Web APIs&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://youtu.be/QmoCAjYDYSI?si=HDxifyqRcrhffSIk">Razor Pages in ASP.NET Core&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://youtu.be/e2I7EzuCt1g?si=QvDu3SZzMysy4iUx">.NET Core MVC&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://youtube.com/playlist?list=PLP8UhDwXI7f_1lze_yKyG-51rS9WNAgMG&amp;amp;si=hfk5wQM45_FRI1Pd">C# Course for beginners&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="authentication">Authentication&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://youtu.be/EnHrfJO0gyE?si=j1l2eGO0YglkYtLw">.Net Core API: JWT and refresh tokens using Identity&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/xhCstGA9WVI">.NET Core identity | Role based authorization in ASP.NET Core MVC&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/JxIhMgJKqqQ">.Net Core MVC Authentication &amp;amp; Role Based Authorization With Auth0&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/gq1zNiKWCP4">Google authentication in asp.net core mvc&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/Y6EbAPiN7gs">Jwt based Authentication &amp;amp; Role based authorization in blazor webassembly&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="image-manipulation">Image manipulation&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://youtu.be/i7dQZiiANKA">Image upload CRUD in razor pages&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/tkk_HxtaqsE">Upload image in asp.net core mvc&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/zADLald4nUw">Upload image in asp.net core APIs&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/ns9-7EffTuU">File upload in blazor server&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="crud-apps-create-read-update-delete">CRUD Apps (Create, Read, Update, Delete)&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://youtu.be/qcczkv-Hz5c?si=OIAmKJsnAT39Bo6m">Fullstack app with dotnet9 and react 19&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/YblleP-QzEs?si=fpod9WovJ0CzoqnK">Fullstack app with dotnet9 and angular 20&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/YfcispTgQYU?si=UvBx51N8GL9gPWrS">Fullstack dotnet mvc app with azure deployment&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/w-cicwms-es">Creating RESTful APIs with dotnet 9, Dapper and PostgreSQL&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/VZ9aoSeuVT8?si=4Dp4NeZdkFdAWAb7">Minimal API CRUD&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/JDHaeDlNqOI">.Net core Web Api CRUD With SQLite &amp;amp; Dapper&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/iceJBFcWuM4">.net core web api crud with mysql &amp;amp; Dapper&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/zJ4SZNKLAog">.Net core web api crud with mysql &amp;amp; EF Core&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/-JDuV5d05Qc">DotNet Core MVC CRUD With Dapper &amp;amp; sql server&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://youtu.be/Y6EbAPiN7gs">.Net core api crud with dapper &amp;amp; sql server&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Project based tutorials on my youtube channel</title><link>https://ravindradevrani.com/free-courses/project-tutorials/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ravindradevrani.com/free-courses/project-tutorials/</guid><description>&lt;h2 id="either-you-can-checkout-the-videos-or-directly-use-the-project-links-are-available-in-their-description-box">Either you can checkout the videos or directly use the project, links are available in their description box&lt;/h2>
&lt;h3 id="1-ecommerce-app-for-bookshttpsyoutube_nzpjsofid8">1. &lt;a href="https://youtu.be/_NzPJSofid8">Ecommerce app for books&lt;/a>&lt;/h3>
&lt;p>This is a basic ecommerse app for selling books. I consider this video as one of my best, in the terms of what it offers. It is 5 hrs 47 min long video, divided in good amount of chapters(timestamps). It offers a lot, except payment gateway. It will be good learning experience for a Beginner. I refined and re-uploaded this video at 5-march-2025. Previously it was built on .NET 7 but now it is upgraded to .NET 9.&lt;/p></description></item></channel></rss>