<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: WireFuture</title>
    <description>The latest articles on DEV Community by WireFuture (@wirefuture).</description>
    <link>https://dev.to/wirefuture</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F9081%2Fda17dddb-20d7-4bb1-8ebd-4f6682e3251f.png</url>
      <title>DEV Community: WireFuture</title>
      <link>https://dev.to/wirefuture</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wirefuture"/>
    <language>en</language>
    <item>
      <title>Asynchronous Programming in C#: Async/Await Patterns</title>
      <dc:creator>Tapesh Mehta</dc:creator>
      <pubDate>Wed, 03 Jul 2024 09:15:20 +0000</pubDate>
      <link>https://dev.to/wirefuture/asynchronous-programming-in-c-asyncawait-patterns-47nk</link>
      <guid>https://dev.to/wirefuture/asynchronous-programming-in-c-asyncawait-patterns-47nk</guid>
      <description>&lt;p&gt;Asynchronous programming is nowadays common in modern software development and allows applications to do work without stalling the main thread. The async and await keywords in C# provide a much cleaner method for creating asynchronous code. This article explores the internals of asynchronous programming in C# including error handling and &lt;a href="https://wirefuture.com/post/how-to-improve-performance-of-asp-net-core-web-applications"&gt;performance optimization&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Async and Await
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Basics of Async and Await
&lt;/h3&gt;

&lt;p&gt;The async keyword is used to declare a method as asynchronous. This means the method can perform its work asynchronously without blocking the calling thread. The await keyword is used to pause the execution of an async method until the awaited task completes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task&amp;lt;int&amp;gt; FetchDataAsync()
{
    await Task.Delay(1000); // Simulate an asynchronous operation
    return 42;
}

public async Task MainAsync()
{
    int result = await FetchDataAsync();
    Console.WriteLine(result);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, FetchDataAsync is an asynchronous method that simulates a delay before returning a result. The await keyword in MainAsync ensures that the method waits for FetchDataAsync to complete before proceeding.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Async and Await Work Under the Hood
&lt;/h2&gt;

&lt;p&gt;When the compiler encounters the await keyword, it breaks the method into two parts: the part before the await and the part after it. The part before the await runs synchronously. When the awaited task completes, the part after the await resumes execution.&lt;/p&gt;

&lt;p&gt;The compiler generates a state machine to handle this &lt;a href="https://wirefuture.com/post/mastering-net-a-deep-dive-into-task-parallel-library"&gt;asynchronous behavior&lt;/a&gt;. This state machine maintains the state of the method and the context in which it runs. This allows the method to pause and resume without blocking the main thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  Task vs. ValueTask
&lt;/h2&gt;

&lt;p&gt;In addition to Task, C# 7.0 introduced ValueTask. While Task is a reference type, ValueTask is a value type that can reduce heap allocations, making it more efficient for scenarios where performance is critical, and the operation completes synchronously most of the time.&lt;/p&gt;

&lt;p&gt;Here’s an example using ValueTask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async ValueTask&amp;lt;int&amp;gt; FetchDataValueTaskAsync()
{
    await Task.Delay(1000);
    return 42;
}

public async Task MainValueTaskAsync()
{
    int result = await FetchDataValueTaskAsync();
    Console.WriteLine(result);
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices for Error Handling
&lt;/h2&gt;

&lt;p&gt;Error handling in asynchronous methods can be challenging. Here are some best practices to ensure robust error handling in your async code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Try-Catch Blocks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Wrap your await statements in try-catch blocks to handle exceptions gracefully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task MainWithErrorHandlingAsync()
{
    try
    {
        int result = await FetchDataAsync();
        Console.WriteLine(result);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"An error occurred: {ex.Message}");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use Cancellation Tokens&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cancellation tokens allow you to cancel asynchronous operations gracefully. This is particularly useful for long-running tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task&amp;lt;int&amp;gt; FetchDataWithCancellationAsync(CancellationToken cancellationToken)
{
    await Task.Delay(1000, cancellationToken);
    return 42;
}

public async Task MainWithCancellationAsync(CancellationToken cancellationToken)
{
    try
    {
        int result = await FetchDataWithCancellationAsync(cancellationToken);
        Console.WriteLine(result);
    }
    catch (OperationCanceledException)
    {
        Console.WriteLine("Operation was canceled.");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Handle AggregateException&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When multiple tasks are awaited using Task.WhenAll, exceptions are wrapped in an AggregateException. Use a try-catch block to handle these exceptions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task MainWithAggregateExceptionHandlingAsync()
{
    var tasks = new List&amp;lt;Task&amp;lt;int&amp;gt;&amp;gt;
    {
        FetchDataAsync(),
        FetchDataAsync()
    };

    try
    {
        int[] results = await Task.WhenAll(tasks);
        Console.WriteLine($"Results: {string.Join(", ", results)}");
    }
    catch (AggregateException ex)
    {
        foreach (var innerException in ex.InnerExceptions)
        {
            Console.WriteLine($"An error occurred: {innerException.Message}");
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Performance Optimization Techniques
&lt;/h2&gt;

&lt;p&gt;Optimizing the performance of asynchronous code involves understanding how the runtime handles async/await and employing best practices to minimize overhead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid Unnecessary Async&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a method does not perform any asynchronous operations, avoid marking it as async. This can save the overhead of the state machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public Task&amp;lt;int&amp;gt; FetchDataWithoutAsync()
{
    return Task.FromResult(42);
}

public async Task MainWithoutUnnecessaryAsync()
{
    int result = await FetchDataWithoutAsync();
    Console.WriteLine(result);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use ConfigureAwait(False)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By default, await captures the current synchronization context and uses it to resume execution. This can lead to performance issues, especially in UI applications. Using ConfigureAwait(false) avoids capturing the context, improving performance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task&amp;lt;int&amp;gt; FetchDataWithConfigureAwaitAsync()
{
    await Task.Delay(1000).ConfigureAwait(false);
    return 42;
}

public async Task MainWithConfigureAwaitAsync()
{
    int result = await FetchDataWithConfigureAwaitAsync();
    Console.WriteLine(result);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Parallelize Independent Tasks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have multiple independent tasks, you can run them in parallel to improve performance using Task.WhenAll.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task MainWithParallelTasksAsync()
{
    var tasks = new List&amp;lt;Task&amp;lt;int&amp;gt;&amp;gt;
    {
        FetchDataAsync(),
        FetchDataAsync()
    };

    int[] results = await Task.WhenAll(tasks);
    Console.WriteLine($"Results: {string.Join(", ", results)}");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use ValueTask for Performance-Critical Paths&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As mentioned earlier, ValueTask can be more efficient than Task for performance-critical paths where most operations complete synchronously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public ValueTask&amp;lt;int&amp;gt; FetchDataWithValueTask()
{
    return new ValueTask&amp;lt;int&amp;gt;(42);
}

public async Task MainWithValueTaskAsync()
{
    int result = await FetchDataWithValueTask();
    Console.WriteLine(result);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Debugging Asynchronous Code
&lt;/h2&gt;

&lt;p&gt;Debugging asynchronous code can be challenging due to the state machine and context switching. Here are some tips to make debugging easier:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Task.Exception Property&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check the Exception property of a task to inspect the exception without causing the application to crash.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task MainWithTaskExceptionAsync()
{
    Task&amp;lt;int&amp;gt; task = FetchDataAsync();

    try
    {
        int result = await task;
        Console.WriteLine(result);
    }
    catch
    {
        if (task.Exception != null)
        {
            Console.WriteLine($"Task failed: {task.Exception.Message}");
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use Debugger Attributes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the DebuggerStepThrough and DebuggerHidden attributes to control how the debugger steps through async methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[DebuggerStepThrough]
public async Task&amp;lt;int&amp;gt; FetchDataWithDebuggerStepThroughAsync()
{
    await Task.Delay(1000);
    return 42;
}

[DebuggerHidden]
public async Task&amp;lt;int&amp;gt; FetchDataWithDebuggerHiddenAsync()
{
    await Task.Delay(1000);
    return 42;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use Logging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Implement logging to track the flow of asynchronous operations and capture exceptions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task&amp;lt;int&amp;gt; FetchDataWithLoggingAsync(ILogger logger)
{
    logger.LogInformation("Fetching data...");
    try
    {
        await Task.Delay(1000);
        logger.LogInformation("Data fetched successfully.");
        return 42;
    }
    catch (Exception ex)
    {
        logger.LogError($"An error occurred: {ex.Message}");
        throw;
    }
}

public async Task MainWithLoggingAsync(ILogger logger)
{
    int result = await FetchDataWithLoggingAsync(logger);
    Console.WriteLine(result);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Asynchronous programming with async and await in C# is a powerful tool to write responsive, scalable applications. Asynchronous programming requires knowing async/await internals, following best practices for error handling and optimizing performance. Using techniques like using ValueTask, avoiding unnecessary async and running tasks in parallel can improve the performance and reliability of your applications. Also, debugging and logging practices are important to maintain and troubleshoot asynchronous code.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>aspdotnet</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Boost Your Angular App's Speed: Code Splitting Strategies</title>
      <dc:creator>Tapesh Mehta</dc:creator>
      <pubDate>Sun, 30 Jun 2024 02:39:57 +0000</pubDate>
      <link>https://dev.to/wirefuture/boost-your-angular-apps-speed-code-splitting-strategies-5e5a</link>
      <guid>https://dev.to/wirefuture/boost-your-angular-apps-speed-code-splitting-strategies-5e5a</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In today's blog post we'll learn how can you boost your Angular app's speed. In Angular, performance optimization is a crucial factor for a great user experience. The most powerful technique in your toolkit is code splitting. This strategy involves breaking your application into smaller, much more manageable chunks that load only as and when required. By implementing code splitting based on routes, modules and lazy loading you can reduce initial loading times and improve performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Code Splitting?
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://wirefuture.com/angular-development"&gt;Angular development&lt;/a&gt;, code splitting is about loading parts of your application on demand rather than all at once. This not only speeds up the initial load but also conserves resources by loading only what's necessary for the current view or feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip 1: Route-Based Code Splitting
&lt;/h2&gt;

&lt;p&gt;Angular's routing mechanism supports lazy loading of modules based on routes. This means modules are loaded only when the user navigates to a corresponding route. Here's how you can set it up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const routes: Routes = [
  { 
    path: 'dashboard',
    loadChildren: () =&amp;gt; import('./dashboard/dashboard.module').then(m =&amp;gt; m.DashboardModule)
  },
  { 
    path: 'profile',
    loadChildren: () =&amp;gt; import('./profile/profile.module').then(m =&amp;gt; m.ProfileModule)
  },
  { 
    path: 'settings',
    loadChildren: () =&amp;gt; import('./settings/settings.module').then(m =&amp;gt; m.SettingsModule)
  }
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, each route (dashboard, profile, settings) loads its module (DashboardModule, ProfileModule, SettingsModule) only when the user navigates to that specific route, keeping initial bundle size small.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip 2: Component-Based Code Splitting
&lt;/h2&gt;

&lt;p&gt;For more granular control, you can implement component-based code splitting using Angular's ComponentFactoryResolver. This approach allows you to dynamically load components when they are needed, rather than loading them upfront. Here's a simplified example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, ComponentFactoryResolver, ViewContainerRef } from '@angular/core';

@Component({
  selector: 'app-dynamic-component',
  template: '&amp;lt;ng-template #dynamicComponentContainer&amp;gt;&amp;lt;/ng-template&amp;gt;'
})
export class DynamicComponentComponent {
  constructor(private resolver: ComponentFactoryResolver, private container: ViewContainerRef) {}

  loadComponent() {
    import('./path/to/your/dynamic-component').then(({ DynamicComponent }) =&amp;gt; {
      const factory = this.resolver.resolveComponentFactory(DynamicComponent);
      this.container.createComponent(factory);
    });
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method loads components dynamically, enhancing performance by loading only the necessary components at runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip 3: Preloading Strategies
&lt;/h2&gt;

&lt;p&gt;To strike a balance between immediate and deferred loading, Angular offers preloading strategies. These strategies allow you to load critical modules in the background after the initial content has loaded, ensuring a seamless user experience during navigation. Here's how you can configure it in your routing module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NgModule, PreloadAllModules } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  // your routes here
];

@NgModule({
  imports: [RouterModule.forRoot(routes, {
    preloadingStrategy: PreloadAllModules
  })],
  exports: [RouterModule]
})
export class AppRoutingModule { }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By specifying PreloadAllModules, Angular preloads all lazy-loaded modules in the background after the main content has loaded, optimizing subsequent navigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip 4: Bundle Analysis and Optimization
&lt;/h2&gt;

&lt;p&gt;To make sure your code splitting efforts deliver maximum performance benefits, use tools like Angular CLI's bundle analyzer. These tools analyze your application's bundle size, identify areas for further optimization, and recommend effective code splitting strategies.&lt;/p&gt;

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

&lt;p&gt;Code splitting in Angular is a game changer for optimizing your application performance. Whether through route-based lazy loading, component-based splitting, preloading strategies or bundle optimization, these techniques let you build faster, more responsive Angular applications. Try out these strategies, track performance metrics and refine your approach to stay ahead of the curve in Angular development.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Exploring the Internals of Dictionary in C#</title>
      <dc:creator>Tapesh Mehta</dc:creator>
      <pubDate>Sat, 29 Jun 2024 04:16:06 +0000</pubDate>
      <link>https://dev.to/wirefuture/exploring-the-internals-of-dictionary-in-c-1i5p</link>
      <guid>https://dev.to/wirefuture/exploring-the-internals-of-dictionary-in-c-1i5p</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Dictionaries in C# are a fundamental data structure that stores key-value pairs. They support lookup, insertion and deletion operations which are required by many applications. But learning how dictionaries work internally may help you use them better and write more efficient software. This article will demonstrate how dictionaries work in C#, including hashing, collision resolution, and bucket management.&lt;/p&gt;

&lt;p&gt;A dictionary is a collection of distinct key-value pairs. The benefit of a dictionary is the ability to quickly find values by key. This is done by hashing, which transforms keys into indices in an array called buckets. Knowing the internal workings of exactly how this works will help you optimize your usage of dictionaries and stay away from common pitfalls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Understanding Internals Matters
&lt;/h2&gt;

&lt;p&gt;Knowing how dictionaries work internally can help you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Optimize Performance:&lt;/strong&gt; By understanding how hashing and buckets work, you can choose appropriate keys and manage dictionary size more effectively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debug Issues:&lt;/strong&gt; When things go wrong, a deeper understanding can help you identify and fix issues related to dictionary usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write Efficient Code:&lt;/strong&gt; Leveraging internal mechanisms can lead to more efficient and scalable applications.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How Dictionaries Work
&lt;/h2&gt;

&lt;p&gt;A dictionary in C# uses an array of buckets to store entries. Each bucket can hold multiple entries in case of collisions. Let's explore how keys are converted to indices, how collisions are handled, and how entries are stored in buckets.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hashing
&lt;/h3&gt;

&lt;p&gt;Hashing is the process of converting a key into an integer, which can then be used as an index in the array of buckets. In C#, the GetHashCode method is used to generate a hash code for a key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Basic Hashing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's a simple example to illustrate hashing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class HashingExample
{
    public static void Main(string[] args)
    {
        string key = "exampleKey";
        int hashCode = key.GetHashCode();
        Console.WriteLine($"Hash Code for '{key}': {hashCode}");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run this code, it will generate a hash code for the string exampleKey. This hash code is then used to determine the bucket index.&lt;/p&gt;

&lt;h3&gt;
  
  
  Buckets
&lt;/h3&gt;

&lt;p&gt;Buckets are an array of linked lists where each list contains entries that have the same hash code (i.e., collisions). The index in the bucket array is calculated using the modulus operation on the hash code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Bucket Index Calculation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class BucketExample
{
    private const int BucketCount = 16;

    public static void Main(string[] args)
    {
        string key = "exampleKey";
        int hashCode = key.GetHashCode();
        int bucketIndex = hashCode % BucketCount;
        Console.WriteLine($"Bucket Index for '{key}': {bucketIndex}");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the bucket index is calculated by taking the modulus of the hash code with the bucket count (16 in this case).&lt;/p&gt;

&lt;h2&gt;
  
  
  Collision Resolution
&lt;/h2&gt;

&lt;p&gt;Collisions occur when multiple keys produce the same bucket index. C# dictionaries handle collisions using linked lists within each bucket. When a collision occurs, the new entry is added to the linked list at the corresponding bucket index.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Collision Handling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider the following example where multiple keys result in the same bucket index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class CollisionExample
{
    private const int BucketCount = 16;
    private static List&amp;lt;KeyValuePair&amp;lt;string, int&amp;gt;&amp;gt;[] buckets;

    public static void Main(string[] args)
    {
        buckets = new List&amp;lt;KeyValuePair&amp;lt;string, int&amp;gt;&amp;gt;[BucketCount];
        AddToDictionary("key1", 1);
        AddToDictionary("key2", 2);
        AddToDictionary("key1", 3); // Collision

        PrintBuckets();
    }

    private static void AddToDictionary(string key, int value)
    {
        int hashCode = key.GetHashCode();
        int bucketIndex = hashCode % BucketCount;

        if (buckets[bucketIndex] == null)
        {
            buckets[bucketIndex] = new List&amp;lt;KeyValuePair&amp;lt;string, int&amp;gt;&amp;gt;();
        }

        buckets[bucketIndex].Add(new KeyValuePair&amp;lt;string, int&amp;gt;(key, value));
    }

    private static void PrintBuckets()
    {
        for (int i = 0; i &amp;lt; buckets.Length; i++)
        {
            Console.WriteLine($"Bucket {i}:");
            if (buckets[i] != null)
            {
                foreach (var kvp in buckets[i])
                {
                    Console.WriteLine($"  {kvp.Key}: {kvp.Value}");
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, when a collision occurs (i.e., key1 is added twice), both entries are stored in the same bucket's linked list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimizing Collisions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To minimize collisions, it's important to choose a good hash function and an appropriate number of buckets. C# uses a default hash function, but you can implement custom hash functions if needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing Buckets
&lt;/h2&gt;

&lt;p&gt;Managing buckets effectively is crucial for the performance of a dictionary. The number of buckets can dynamically grow as the dictionary size increases to maintain efficient lookups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resizing Buckets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the number of entries exceeds a certain threshold, the dictionary resizes its buckets array to reduce the load factor. This involves rehashing all existing keys and redistributing them into the new buckets array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Resizing Buckets&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ResizingExample
{
    private const int InitialBucketCount = 4;
    private List&amp;lt;KeyValuePair&amp;lt;string, int&amp;gt;&amp;gt;[] buckets;
    private int count;
    private int bucketCount;

    public ResizingExample()
    {
        bucketCount = InitialBucketCount;
        buckets = new List&amp;lt;KeyValuePair&amp;lt;string, int&amp;gt;&amp;gt;[bucketCount];
        count = 0;
    }

    public void Add(string key, int value)
    {
        if (count &amp;gt;= bucketCount * 0.75)
        {
            ResizeBuckets();
        }

        int hashCode = key.GetHashCode();
        int bucketIndex = hashCode % bucketCount;

        if (buckets[bucketIndex] == null)
        {
            buckets[bucketIndex] = new List&amp;lt;KeyValuePair&amp;lt;string, int&amp;gt;&amp;gt;();
        }

        buckets[bucketIndex].Add(new KeyValuePair&amp;lt;string, int&amp;gt;(key, value));
        count++;
    }

    private void ResizeBuckets()
    {
        bucketCount *= 2;
        var newBuckets = new List&amp;lt;KeyValuePair&amp;lt;string, int&amp;gt;&amp;gt;[bucketCount];

        foreach (var bucket in buckets)
        {
            if (bucket != null)
            {
                foreach (var kvp in bucket)
                {
                    int newBucketIndex = kvp.Key.GetHashCode() % bucketCount;
                    if (newBuckets[newBucketIndex] == null)
                    {
                        newBuckets[newBucketIndex] = new List&amp;lt;KeyValuePair&amp;lt;string, int&amp;gt;&amp;gt;();
                    }
                    newBuckets[newBucketIndex].Add(kvp);
                }
            }
        }

        buckets = newBuckets;
    }

    public void PrintBuckets()
    {
        for (int i = 0; i &amp;lt; buckets.Length; i++)
        {
            Console.WriteLine($"Bucket {i}:");
            if (buckets[i] != null)
            {
                foreach (var kvp in buckets[i])
                {
                    Console.WriteLine($"  {kvp.Key}: {kvp.Value}");
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the Add method checks if the load factor exceeds 75% and triggers resizing if necessary. The ResizeBuckets method doubles the number of buckets and rehashes all existing entries.&lt;/p&gt;

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

&lt;p&gt;Understanding the internals of how dictionaries work in C# (hashing, collision resolution, bucket management) can help you write robust code. Optimizing hashing functions, handling collisions efficiently, and managing buckets dynamically improves the performance of your applications. In the context of &lt;a href="https://wirefuture.com/dot-net-development"&gt;.NET development&lt;/a&gt;, this knowledge becomes even more valuable as it allows you to leverage the full power of the framework for building high-performance, scalable applications.&lt;/p&gt;

&lt;p&gt;Next time you use a dictionary, take a moment to consider how these internal mechanisms are working to provide you with fast and efficient data access. This knowledge can help you enhance your code and solve complex problems confidently.&lt;/p&gt;

&lt;p&gt;What challenges have you had using dictionaries in your applications? Share your experiences and learn together!&lt;/p&gt;

&lt;p&gt;Reach out in case you have questions or require further help. Your feedback and experiences help make this journey a much better one for everybody. Have fun coding!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>microsoft</category>
      <category>dotnet</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>How To Build RESTful APIs With ASP.NET Core 8</title>
      <dc:creator>Tapesh Mehta</dc:creator>
      <pubDate>Fri, 28 Jun 2024 14:57:10 +0000</pubDate>
      <link>https://dev.to/wirefuture/how-to-build-restful-apis-with-aspnet-core-8-j5</link>
      <guid>https://dev.to/wirefuture/how-to-build-restful-apis-with-aspnet-core-8-j5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Modern software development often requires building RESTful APIs. With the release of ASP.NET Core 8, building robust scalable APIs has never been easier. In this blog post, we'll explore how to build RESTful APIs using ASP.NET Core 8, including in-depth points, code samples, and personal insights. Whether you are a veteran developer or just starting out, you will find valuable information here to enhance your development experience.&lt;/p&gt;

&lt;p&gt;RESTful APIs (Representational State Transfer) have become the standard for web services. They provide a simple, scalable way to expose data and functionality over HTTP. ASP.NET Core, a cross-platform, high-performance framework, is an excellent choice for building these APIs. With the release of ASP.NET Core 8, we get even more features and improvements to enhance our development experience.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For those interested in learning more about .NET development, check out our &lt;a href="https://wirefuture.com/blog/dot-net-development"&gt;.NET Development&lt;/a&gt; blogs. Stay updated with the latest insights and best practices!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why RESTful APIs?
&lt;/h2&gt;

&lt;p&gt;Before diving into the technical details, let's take a moment to understand why RESTful APIs are so popular. RESTful APIs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Are easy to understand and use:&lt;/strong&gt; They use standard HTTP methods and status codes, making them accessible to developers of all levels.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Support a wide range of clients:&lt;/strong&gt; From web applications to mobile apps and IoT devices, RESTful APIs can be consumed by virtually any client that can make HTTP requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Promote stateless communication:&lt;/strong&gt; Each request from a client contains all the information needed to process it, allowing for scalable and resilient systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Encourage good design practices:&lt;/strong&gt; Using REST principles, you can design clean, intuitive APIs that are easy to maintain and evolve.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Getting Started with ASP.NET Core 8
&lt;/h2&gt;

&lt;p&gt;To start building a RESTful API with ASP.NET Core 8, you'll need to set up your development environment. Make sure you have the following installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;.NET 8 SDK&lt;/li&gt;
&lt;li&gt;Visual Studio or Visual Studio Code&lt;/li&gt;
&lt;li&gt;A modern web browser for testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating a New ASP.NET Core Project
&lt;/h2&gt;

&lt;p&gt;Open your terminal or command prompt and run the following command to create a new ASP.NET Core project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet new webapi -n MyApi
cd MyApi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command creates a new ASP.NET Core Web API project named MyApi and navigates into the project directory. Open the project in your preferred IDE.&lt;/p&gt;

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

&lt;p&gt;Your project will have the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MyApi
├── Controllers
│   └── WeatherForecastController.cs
├── Program.cs
├── Startup.cs
└── MyApi.csproj
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Controllers folder contains the default WeatherForecastController. We'll create our own controllers shortly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Your First API Endpoint
&lt;/h2&gt;

&lt;p&gt;Let's create a simple API endpoint that returns a list of products. Start by defining a Product model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Defining the Product Model&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new folder named Models and add a Product.cs file with the following content:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Creating the Products Controller&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, create a Controllers folder if it doesn't exist and add a ProductsController.cs file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Mvc;
using MyApi.Models;
using System.Collections.Generic;
using System.Linq;

namespace MyApi.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ProductsController : ControllerBase
    {
        private static readonly List&amp;lt;Product&amp;gt; Products = new List&amp;lt;Product&amp;gt;
        {
            new Product { Id = 1, Name = "Laptop", Price = 999.99M },
            new Product { Id = 2, Name = "Smartphone", Price = 499.99M }
        };

        [HttpGet]
        public ActionResult&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt; GetProducts()
        {
            return Ok(Products);
        }

        [HttpGet("{id}")]
        public ActionResult&amp;lt;Product&amp;gt; GetProduct(int id)
        {
            var product = Products.FirstOrDefault(p =&amp;gt; p.Id == id);
            if (product == null)
            {
                return NotFound();
            }
            return Ok(product);
        }

        [HttpPost]
        public ActionResult&amp;lt;Product&amp;gt; CreateProduct(Product product)
        {
            product.Id = Products.Count + 1;
            Products.Add(product);
            return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
        }

        [HttpPut("{id}")]
        public IActionResult UpdateProduct(int id, Product updatedProduct)
        {
            var product = Products.FirstOrDefault(p =&amp;gt; p.Id == id);
            if (product == null)
            {
                return NotFound();
            }

            product.Name = updatedProduct.Name;
            product.Price = updatedProduct.Price;
            return NoContent();
        }

        [HttpDelete("{id}")]
        public IActionResult DeleteProduct(int id)
        {
            var product = Products.FirstOrDefault(p =&amp;gt; p.Id == id);
            if (product == null)
            {
                return NotFound();
            }

            Products.Remove(product);
            return NoContent();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;[ApiController] and [Route] Attributes:&lt;/strong&gt; These attributes specify that this class is an API controller and define the base route for all actions in the controller.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GET /api/products:&lt;/strong&gt; Returns a list of all products.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GET /api/products/{id}:&lt;/strong&gt; Returns a single product by ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;POST /api/products:&lt;/strong&gt; Creates a new product.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PUT /api/products/{id}:&lt;/strong&gt; Updates an existing product.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DELETE /api/products/{id}:&lt;/strong&gt; Deletes a product by ID.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Running the API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To run your API, use the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Open your browser and navigate to &lt;a href="https://localhost:5001/api/products"&gt;https://localhost:5001/api/products&lt;/a&gt; to see the list of products.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Features and Best Practices
&lt;/h2&gt;

&lt;p&gt;Now that we have a basic API, let's explore some advanced features and best practices to make it more robust and maintainable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Entity Framework Core
&lt;/h3&gt;

&lt;p&gt;For real-world applications, you'll typically use a database to store data. Entity Framework Core (EF Core) is an excellent ORM (Object-Relational Mapper) for working with databases in .NET.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting Up EF Core&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, add EF Core packages to your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configuring the DbContext&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a Data folder and add an AppDbContext.cs file:&lt;br&gt;
&lt;/p&gt;

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

namespace MyApi.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions&amp;lt;AppDbContext&amp;gt; options) : base(options) { }

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Update Program.cs to configure the DbContext:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddDbContext&amp;lt;AppDbContext&amp;gt;(options =&amp;gt;
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

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

&lt;/div&gt;



&lt;p&gt;Add a connection string to appsettings.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=MyApiDb;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Updating the Products Controller&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Update the ProductsController to use EF Core:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MyApi.Data;
using MyApi.Models;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyApi.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ProductsController : ControllerBase
    {
        private readonly AppDbContext _context;

        public ProductsController(AppDbContext context)
        {
            _context = context;
        }

        [HttpGet]
        public async Task&amp;lt;ActionResult&amp;lt;IEnumerable&amp;lt;Product&amp;gt;&amp;gt;&amp;gt; GetProducts()
        {
            return await _context.Products.ToListAsync();
        }

        [HttpGet("{id}")]
        public async Task&amp;lt;ActionResult&amp;lt;Product&amp;gt;&amp;gt; GetProduct(int id)
        {
            var product = await _context.Products.FindAsync(id);
            if (product == null)
            {
                return NotFound();
            }
            return product;
        }

        [HttpPost]
        public async Task&amp;lt;ActionResult&amp;lt;Product&amp;gt;&amp;gt; CreateProduct(Product product)
        {
            _context.Products.Add(product);
            await _context.SaveChangesAsync();

            return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
        }

        [HttpPut("{id}")]
        public async Task&amp;lt;IActionResult&amp;gt; UpdateProduct(int id, Product updatedProduct)
        {
            if (id != updatedProduct.Id)
            {
                return BadRequest();
            }

            _context.Entry(updatedProduct).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!_context.Products.Any(e =&amp;gt; e.Id == id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }

        [HttpDelete("{id}")]
        public async Task&amp;lt;IActionResult&amp;gt; DeleteProduct(int id)
        {
            var product = await _context.Products.FindAsync(id);
            if (product == null)
            {
                return NotFound();
            }

            _context.Products.Remove(product);
            await _context.SaveChangesAsync();

            return NoContent();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Implementing Validation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To ensure data integrity, it's important to validate input. ASP.NET Core provides built-in validation mechanisms.&lt;/p&gt;

&lt;p&gt;Add data annotations to the Product model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.ComponentModel.DataAnnotations;

namespace MyApi.Models
{
    public class Product
    {
        public int Id { get; set; }

        [Required]
        [StringLength(100)]
        public string Name { get; set; }

        [Range(0.01, 10000.00)]
        public decimal Price { get; set; }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validation errors are automatically handled by ASP.NET Core and returned to the client.&lt;/p&gt;

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

&lt;p&gt;Building RESTful APIs with ASP.NET Core 8 is a rewarding experience. With all the latest features and improvements, you can make powerful and scalable APIs for todays applications. From setting up your project and defining endpoints to leveraging Entity Framework Core and implementing validation, we've covered the basics to get you started.&lt;/p&gt;

&lt;p&gt;And remember, the journey doesn't end here. Continue to learn and enhance your skills and ask questions or even get assistance from the community. Have fun coding!&lt;/p&gt;

&lt;p&gt;What challenges have you faced while building APIs? Share your experiences and learn together!&lt;/p&gt;

&lt;p&gt;Reach out in case you have questions or require further help. Your feedback and experiences help make this journey a much better one for everybody.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For those interested in learning more about .NET development, check out our &lt;a href="https://wirefuture.com/blog/dot-net-development"&gt;.NET Development&lt;/a&gt; blogs. Stay updated with the latest insights and best practices!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>aspnet</category>
      <category>csharp</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Make React Applications SEO Friendly?</title>
      <dc:creator>Tapesh Mehta</dc:creator>
      <pubDate>Fri, 28 Jun 2024 08:47:30 +0000</pubDate>
      <link>https://dev.to/wirefuture/how-to-make-react-applications-seo-friendly-23lo</link>
      <guid>https://dev.to/wirefuture/how-to-make-react-applications-seo-friendly-23lo</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Search Engine Optimization (SEO) is a necessity for the visibility and success of any web application. SEO friendliness is a challenge for React applications due to the single-page application nature of the app. However with the proper tools and techniques, you can make your React app perform better on SEO. In this article, we will explore various strategies to make your React applications SEO friendly, ensuring better search engine rankings and improved user experience.&lt;/p&gt;

&lt;p&gt;React, developed by Facebook, is a JavaScript library used to create web pages. It is ideally suited to developing dynamic and interactive web applications, but its default configuration can be problematic for SEO. This is because React applications often use client-side rendering, which makes crawling and indexing content difficult for search engines. Techniques include server-side rendering (SSR), static site generation (SSG), meta tag management, URL structure optimization, etc. By the end of this guide, you will have a comprehensive understanding of how to optimize your React application for better SEO performance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Recommended Read on SSR: &lt;a href="https://wirefuture.com/post/how-to-implement-server-side-rendering-in-react"&gt;How to Implement Server Side Rendering in React&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Server-Side Rendering (SSR)
&lt;/h2&gt;

&lt;p&gt;Server-side rendering (SSR) is a powerful technique to improve the SEO of React applications. With SSR, the server renders the initial HTML content before sending it to the client's browser. This approach allows search engines to crawl the pre-rendered HTML, improving the chances of indexing your content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing SSR with Next.js
&lt;/h2&gt;

&lt;p&gt;Next.js is a popular React framework that supports SSR out of the box. To get started with Next.js:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install Next.js:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app my-seo-friendly-app
cd my-seo-friendly-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create Pages:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next.js uses a file-based routing system. Create pages by adding files to the pages directory.&lt;/p&gt;

&lt;p&gt;For example, create an index.js file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/index.js
import React from 'react';

const HomePage = () =&amp;gt; (
  &amp;lt;div&amp;gt;
    &amp;lt;h1&amp;gt;Welcome to My SEO Friendly React App&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;This is a server-side rendered page.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
);

export default HomePage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Start the Development Server:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Static Site Generation (SSG)
&lt;/h2&gt;

&lt;p&gt;Static Site Generation (SSG) is another effective method to enhance SEO. SSG generates static HTML files at build time, which can be served quickly and efficiently. This approach is ideal for content-heavy websites, such as blogs and marketing sites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing SSG with Next.js
&lt;/h2&gt;

&lt;p&gt;Next.js also supports SSG. To generate static pages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Static Pages:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/index.js
import React from 'react';

export async function getStaticProps() {
  // Fetch data at build time
  const data = await fetch('https://api.example.com/data');
  const jsonData = await data.json();

  return {
    props: {
      data: jsonData,
    },
  };
}

const HomePage = ({ data }) =&amp;gt; (
  &amp;lt;div&amp;gt;
    &amp;lt;h1&amp;gt;Welcome to My SEO Friendly React App&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;{data.message}&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
);

export default HomePage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Build the Application:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run build
npm run start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next.js will generate static HTML files for each page, making them easily crawlable by search engines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meta Tag Management
&lt;/h2&gt;

&lt;p&gt;Meta tags are essential for providing search engines with information about your web pages. Properly managing meta tags can significantly impact your SEO performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using React Helmet
&lt;/h3&gt;

&lt;p&gt;React Helmet is a library that helps manage meta tags in React applications. To use React Helmet:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install React Helmet:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install react-helmet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Add Meta Tags:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/index.js
import React from 'react';
import { Helmet } from 'react-helmet';

const HomePage = () =&amp;gt; (
  &amp;lt;div&amp;gt;
    &amp;lt;Helmet&amp;gt;
      &amp;lt;title&amp;gt;My SEO Friendly React App&amp;lt;/title&amp;gt;
      &amp;lt;meta name="description" content="Learn how to make React applications SEO friendly." /&amp;gt;
      &amp;lt;meta name="keywords" content="React, SEO, Server-Side Rendering, Static Site Generation" /&amp;gt;
    &amp;lt;/Helmet&amp;gt;
    &amp;lt;h1&amp;gt;Welcome to My SEO Friendly React App&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;This is a server-side rendered page.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
);

export default HomePage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;React Helmet allows you to dynamically manage meta tags, ensuring search engines receive the correct information.&lt;/p&gt;

&lt;h2&gt;
  
  
  URL Structure Optimization
&lt;/h2&gt;

&lt;p&gt;A clean and descriptive URL structure is crucial for SEO. Avoid using query parameters and instead use descriptive, hyphenated URLs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing Clean URLs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Use Next.js for Routing:&lt;/strong&gt;&lt;br&gt;
Next.js automatically creates clean URLs based on the file names in the pages directory. For example, a file named about.js in the pages directory will be accessible at /about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Dynamic Routes:&lt;/strong&gt;&lt;br&gt;
For dynamic routes, use square brackets. For example, to create a dynamic route for blog posts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/posts/[id].js
import React from 'react';
import { useRouter } from 'next/router';

const Post = () =&amp;gt; {
  const router = useRouter();
  const { id } = router.query;

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Post {id}&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;This is a dynamic route.&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Post;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Structured Data
&lt;/h2&gt;

&lt;p&gt;Structured data helps search engines understand the content of your web pages better. Using JSON-LD, you can add structured data to your React application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Structured Data
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Use React Helmet:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pages/index.js
import React from 'react';
import { Helmet } from 'react-helmet';

const HomePage = () =&amp;gt; (
  &amp;lt;div&amp;gt;
    &amp;lt;Helmet&amp;gt;
      &amp;lt;script type="application/ld+json"&amp;gt;
        {`
          {
            "@context": "http://schema.org",
            "@type": "WebSite",
            "name": "My SEO Friendly React App",
            "url": "https://www.myseofriendlyreactapp.com"
          }
        `}
      &amp;lt;/script&amp;gt;
    &amp;lt;/Helmet&amp;gt;
    &amp;lt;h1&amp;gt;Welcome to My SEO Friendly React App&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;This is a server-side rendered page.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
);

export default HomePage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding structured data can improve your website’s visibility in search results, enhancing the overall SEO performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lazy Loading Images
&lt;/h2&gt;

&lt;p&gt;Lazy loading images can improve page load times, enhancing both user experience and SEO.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use the loading Attribute:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const HomePage = () =&amp;gt; (
  &amp;lt;div&amp;gt;
    &amp;lt;h1&amp;gt;Welcome to My SEO Friendly React App&amp;lt;/h1&amp;gt;
    &amp;lt;img src="path/to/image.jpg" alt="Description" loading="lazy" /&amp;gt;
  &amp;lt;/div&amp;gt;
);

export default HomePage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lazy loading images ensure that only the images currently in the viewport are loaded, reducing initial page load times.&lt;/p&gt;

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

&lt;p&gt;SEO friendly React applications requires a combination of server-side rendering, static site generation, proper meta tag management, clean URL structures, structured data and lazy loading images. With these strategies, you can improve the SEO of your React apps for more visibility and higher search engine ranks. Adopting tools such as Next.js and React Helmet can make it easier to develop SEO-friendly React apps. With these best practices in place, you can make your React application performant and search engines friendly.&lt;/p&gt;

&lt;p&gt;Next.js will handle the server-side rendering, providing a fully rendered HTML page to search engines.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>seo</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Data Access with Dapper: A Lightweight ORM for .NET Apps</title>
      <dc:creator>Tapesh Mehta</dc:creator>
      <pubDate>Thu, 27 Jun 2024 15:49:55 +0000</pubDate>
      <link>https://dev.to/wirefuture/data-access-with-dapper-a-lightweight-orm-for-net-apps-1adb</link>
      <guid>https://dev.to/wirefuture/data-access-with-dapper-a-lightweight-orm-for-net-apps-1adb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this blog article, we'll cover how to efficiently access data using Dapper, a lightweight ORM for .NET applications. We'll discuss its key features and compare it with Entity Framework along the way.&lt;/p&gt;

&lt;p&gt;Data access is a crucial aspect of any application. The selection of the best tool for the job will impact performance, maintainability, and development ease. Dapper is a lightweight Object Relational Mapper (ORM) for .NET that will compete with standard ORMs like Entity Framework. This article will introduce Dapper, compare it with Entity Framework, and demonstrate real-world examples with performance benchmarks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For those interested in learning more about .NET development, check out our &lt;a href="https://wirefuture.com/blog/dot-net-development"&gt;.NET Development&lt;/a&gt; blogs. Stay updated with the latest insights and best practices!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction to Dapper
&lt;/h2&gt;

&lt;p&gt;Dapper is a micro-ORM developed by the team at Stack Exchange. Unlike full-fledged ORMs like Entity Framework, Dapper focuses on being simple and performant. It does this by providing a straightforward API for executing SQL queries and mapping results to strongly-typed objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features of Dapper
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lightweight and Fast:&lt;/strong&gt; Dapper is designed to be minimalistic and efficient, with minimal overhead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simple API:&lt;/strong&gt; The API is intuitive and easy to use, allowing developers to execute SQL queries directly and map results to objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility:&lt;/strong&gt; It allows you to write raw SQL queries, giving you full control over your database interactions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Extension Methods:&lt;/strong&gt; Dapper extends the IDbConnection interface, making it easy to integrate with existing ADO.NET code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To get started with Dapper, you need to install the Dapper package from NuGet. You can do this using the Package Manager Console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Install-Package Dapper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comparing Dapper with Entity Framework
&lt;/h2&gt;

&lt;p&gt;Entity Framework (EF) is a popular ORM for .NET that provides a high level of abstraction over database interactions. It uses a model-first or code-first approach to generate database schemas and manage data access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Differences:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance:&lt;/strong&gt; Dapper is significantly faster than Entity Framework because it generates minimal overhead. EF, on the other hand, offers rich features but at the cost of performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Complexity:&lt;/strong&gt; EF provides a higher level of abstraction and includes features like change tracking, lazy loading, and navigation properties. Dapper is more lightweight and requires you to write SQL queries manually.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility:&lt;/strong&gt; Dapper offers more control and flexibility as it allows direct SQL execution. EF abstracts much of the SQL away, which can be a limitation in some scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Learning Curve:&lt;/strong&gt; EF has a steeper learning curve due to its rich feature set. Dapper is easier to learn and use for developers familiar with SQL.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Real-world Examples
&lt;/h2&gt;

&lt;p&gt;Let's explore some real-world examples to see how Dapper can be used for common data access tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1: Basic CRUD Operations
&lt;/h3&gt;

&lt;p&gt;First, we need to set up a database connection. Assume we have a Product table in our database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE Product (
    Id INT PRIMARY KEY IDENTITY,
    Name NVARCHAR(100),
    Price DECIMAL(18, 2)
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's perform basic CRUD operations using Dapper.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System.Data.SqlClient;
using Dapper;

string connectionString = "your_connection_string";
using (var connection = new SqlConnection(connectionString))
{
    string insertQuery = "INSERT INTO Product (Name, Price) VALUES (@Name, @Price)";
    var result = connection.Execute(insertQuery, new { Name = "Laptop", Price = 999.99m });
    Console.WriteLine($"{result} row(s) inserted.");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Read:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using (var connection = new SqlConnection(connectionString))
{
    string selectQuery = "SELECT * FROM Product WHERE Id = @Id";
    var product = connection.QuerySingleOrDefault&amp;lt;Product&amp;gt;(selectQuery, new { Id = 1 });
    Console.WriteLine($"Product: {product.Name}, Price: {product.Price}");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using (var connection = new SqlConnection(connectionString))
{
    string updateQuery = "UPDATE Product SET Price = @Price WHERE Id = @Id";
    var result = connection.Execute(updateQuery, new { Id = 1, Price = 1099.99m });
    Console.WriteLine($"{result} row(s) updated.");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Delete:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using (var connection = new SqlConnection(connectionString))
{
    string deleteQuery = "DELETE FROM Product WHERE Id = @Id";
    var result = connection.Execute(deleteQuery, new { Id = 1 });
    Console.WriteLine($"{result} row(s) deleted.");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 2: Using Stored Procedures
&lt;/h3&gt;

&lt;p&gt;Dapper also supports executing stored procedures.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE PROCEDURE GetProductById
    @Id INT
AS
BEGIN
    SELECT * FROM Product WHERE Id = @Id
END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using (var connection = new SqlConnection(connectionString))
{
    var product = connection.QuerySingleOrDefault&amp;lt;Product&amp;gt;(
        "GetProductById",
        new { Id = 1 },
        commandType: CommandType.StoredProcedure);
    Console.WriteLine($"Product: {product.Name}, Price: {product.Price}");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 3: Mapping Complex Types
&lt;/h3&gt;

&lt;p&gt;Dapper can map complex types and relationships.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE Category (
    Id INT PRIMARY KEY IDENTITY,
    Name NVARCHAR(100)
);

ALTER TABLE Product ADD CategoryId INT;
ALTER TABLE Product ADD CONSTRAINT FK_Product_Category FOREIGN KEY (CategoryId) REFERENCES Category(Id);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





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

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
}

using (var connection = new SqlConnection(connectionString))
{
    string sql = @"
        SELECT p.*, c.* 
        FROM Product p 
        INNER JOIN Category c ON p.CategoryId = c.Id
        WHERE p.Id = @Id";

    var product = connection.Query&amp;lt;Product, Category, Product&amp;gt;(
        sql,
        (product, category) =&amp;gt; {
            product.Category = category;
            return product;
        },
        new { Id = 1 },
        splitOn: "Id").FirstOrDefault();

    Console.WriteLine($"Product: {product.Name}, Price: {product.Price}, Category: {product.Category.Name}");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Performance Benchmarks
&lt;/h2&gt;

&lt;p&gt;To illustrate the performance differences, let's compare Dapper and Entity Framework in terms of query execution time. Below are some benchmark results (in milliseconds) for retrieving 1000 records from a Product table.&lt;/p&gt;

&lt;p&gt;The benchmark results show that Dapper performs significantly better than Entity Framework for this specific use case. While EF offers more features, Dapper's performance advantage can be crucial for high-load applications.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ORM&lt;/th&gt;
&lt;th&gt;Query Execution Time (ms)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dapper&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entity Framework&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The benchmark results show that Dapper performs significantly better than Entity Framework for this specific use case. While EF offers more features, Dapper's performance advantage can be crucial for high-load applications.&lt;/p&gt;

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

&lt;p&gt;Dapper is an excellent choice for developers who need a lightweight, fast and flexible ORM for .NET applications. Its simplicity and performance make it suitable for many data access situations, whenever you want complete control over SQL queries. Though Entity Framework offers additional features, Dapper is more efficient and simpler to use compared to a lot of programs.&lt;/p&gt;

&lt;p&gt;Adding Dapper to your &lt;a href="//wirefuture.com/dot-net-development"&gt;.NET projects&lt;/a&gt; will help you optimize data access, improve performance, and maintain flexibility in your database interactions. Whether you are developing a small application or a large enterprise system, Dapper enables you to develop a maintainable data access code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For those interested in learning more about .NET development, check out our &lt;a href="https://wirefuture.com/blog/dot-net-development"&gt;.NET Development&lt;/a&gt; blogs. Stay updated with the latest insights and best practices!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>dapper</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>orm</category>
    </item>
    <item>
      <title>Advanced Logging in ASP.NET Core with Serilog</title>
      <dc:creator>Tapesh Mehta</dc:creator>
      <pubDate>Thu, 27 Jun 2024 15:16:42 +0000</pubDate>
      <link>https://dev.to/wirefuture/advanced-logging-in-aspnet-core-with-serilog-33bn</link>
      <guid>https://dev.to/wirefuture/advanced-logging-in-aspnet-core-with-serilog-33bn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In today's blog post we'll learn how to do advanced logging in ASP.NET Core with Serilog. Logging is a vital part of any business application and offers visibility into application behaviour, performance and possible issues. Among the logging frameworks available for .NET, Serilog offers a flexible, structured logging and multiple sink integration. This article will explain why you should use Serilog, how to configure it for different sinks and enrichers, and best practices for structured logging in enterprise applications.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For those interested in learning more about .NET development, check out our &lt;a href="https://wirefuture.com/blog/dot-net-development"&gt;.NET Development&lt;/a&gt; blogs. Stay updated with the latest insights and best practices!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Use Serilog for Logging?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Structured Logging:&lt;/strong&gt; Serilog's primary strength is its support for structured logging, which allows you to capture detailed, queryable log data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility:&lt;/strong&gt; Serilog is highly configurable and supports numerous sinks (outputs) and enrichers (additional data in logs).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ease of Use:&lt;/strong&gt; With a simple and fluent configuration API, setting up Serilog in your application is straightforward.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance:&lt;/strong&gt; Serilog is designed for high-performance logging, ensuring minimal overhead on your application.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Configuring Serilog for Various Sinks and Enrichers
&lt;/h2&gt;

&lt;p&gt;Let's dive into configuring Serilog in an ASP.NET Core application, focusing on different sinks and enrichers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Setting Up Serilog
&lt;/h3&gt;

&lt;p&gt;First, add the necessary Serilog packages to your project. You can do this via NuGet Package Manager or by running the following commands in the Package Manager Console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Install-Package Serilog.AspNetCore
Install-Package Serilog.Sinks.Console
Install-Package Serilog.Sinks.File
Install-Package Serilog.Sinks.MSSqlServer
Install-Package Serilog.Sinks.Datadog
Install-Package Serilog.Enrichers.Environment
Install-Package Serilog.Enrichers.Thread
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Configuring Serilog in Program.cs
&lt;/h3&gt;

&lt;p&gt;In the Program.cs file, configure Serilog as the logging provider for your ASP.NET Core application:&lt;br&gt;
&lt;/p&gt;

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

public class Program
{
    public static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .Enrich.WithEnvironmentName()
            .Enrich.WithThreadId()
            .WriteTo.Console()
            .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day)
            .WriteTo.MSSqlServer(
                connectionString: "YourConnectionString",
                sinkOptions: new Serilog.Sinks.MSSqlServer.MSSqlServerSinkOptions { TableName = "Logs" })
            .WriteTo.DatadogLogs(
                apiKey: "YourDatadogApiKey",
                source: "YourApplicationName")
            .CreateLogger();

        try
        {
            Log.Information("Starting up");
            CreateHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Application start-up failed");
            throw;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =&amp;gt;
        Host.CreateDefaultBuilder(args)
            .UseSerilog()
            .ConfigureWebHostDefaults(webBuilder =&amp;gt;
            {
                webBuilder.UseStartup&amp;lt;Startup&amp;gt;();
            });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Enriching Logs
&lt;/h3&gt;

&lt;p&gt;Enrichers add valuable context to your log entries. Here, we've used environment and thread ID enrichers. You can add more enrichers as needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.Enrich.WithEnvironmentName()
.Enrich.WithThreadId()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Detailed Configuration for Various Sinks
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Console Sink
&lt;/h4&gt;

&lt;p&gt;The console sink outputs logs to the console, which is useful during development:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.WriteTo.Console()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  File Sink
&lt;/h4&gt;

&lt;p&gt;The file sink writes logs to a file, with options for rolling logs daily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  SQL Server Sink
&lt;/h4&gt;

&lt;p&gt;The SQL Server sink stores logs in a database, allowing for robust querying and analysis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.WriteTo.MSSqlServer(
    connectionString: "YourConnectionString",
    sinkOptions: new Serilog.Sinks.MSSqlServer.MSSqlServerSinkOptions { TableName = "Logs" })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure you have a table in your database to store the logs. You can create it using the following SQL script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE Logs (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    Message NVARCHAR(MAX),
    MessageTemplate NVARCHAR(MAX),
    Level NVARCHAR(128),
    TimeStamp DATETIMEOFFSET,
    Exception NVARCHAR(MAX),
    Properties NVARCHAR(MAX)
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Datadog Sink
&lt;/h4&gt;

&lt;p&gt;The Datadog sink sends logs to Datadog, a popular monitoring and analytics platform:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.WriteTo.DatadogLogs(
    apiKey: "YourDatadogApiKey",
    source: "YourApplicationName")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace "YourDatadogApiKey" with your actual Datadog API key and set an appropriate source name for your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for Structured Logging in Enterprise Applications
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Structured Logging:&lt;/strong&gt; Capture logs in a structured format to enable advanced querying and analysis.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Log at Appropriate Levels:&lt;/strong&gt; Use different log levels (e.g., Debug, Information, Warning, Error, Fatal) to capture the right amount of detail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid Sensitive Information:&lt;/strong&gt; Ensure that sensitive data (e.g., passwords, personal information) is not logged.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Enrichers:&lt;/strong&gt; Add contextual information to your logs using enrichers to make them more informative.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Centralize Logging:&lt;/strong&gt; Store logs in a central location (e.g., SQL Server, Datadog) to facilitate monitoring and troubleshooting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Monitor Log Size and Performance:&lt;/strong&gt; Regularly monitor the size and performance impact of your logs, and configure log rotation or retention policies as needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Comparison of Serilog, NLog, and log4net for ASP.NET Core Logging
&lt;/h2&gt;

&lt;p&gt;NLog and log4net are other popular logging libraries used in the .NET ecosystem. Both have a strong user base and offer extensive features for various logging needs. However, Serilog stands out with its advanced structured logging capabilities, flexible configuration, and a wide range of built-in enrichers and sinks. The table below provides a detailed comparison of these three logging frameworks, highlighting their strengths and differences to help you choose the best option for your ASP.NET Core application.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Serilog&lt;/th&gt;
&lt;th&gt;NLog&lt;/th&gt;
&lt;th&gt;log4net&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Structured Logging&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High performance&lt;/td&gt;
&lt;td&gt;High performance&lt;/td&gt;
&lt;td&gt;Moderate performance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Enrichers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Extensive support for enrichers&lt;/td&gt;
&lt;td&gt;Basic support&lt;/td&gt;
&lt;td&gt;Basic support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sinks/Appenders&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Extensive (Console, File, SQL, Datadog, etc.)&lt;/td&gt;
&lt;td&gt;Extensive (Console, File, Database, etc.)&lt;/td&gt;
&lt;td&gt;Extensive (Console, File, Database, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Asynchronous Logging&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Community and Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong community and active development&lt;/td&gt;
&lt;td&gt;Strong community and active development&lt;/td&gt;
&lt;td&gt;Strong community but less active development&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Excellent documentation and examples&lt;/td&gt;
&lt;td&gt;Good documentation&lt;/td&gt;
&lt;td&gt;Good documentation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Highly flexible and easily extendable&lt;/td&gt;
&lt;td&gt;Highly flexible and easily extendable&lt;/td&gt;
&lt;td&gt;Highly flexible and easily extendable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Built-in Enrichers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes (e.g., Environment, Thread, Machine Name)&lt;/td&gt;
&lt;td&gt;No built-in enrichers, custom development needed&lt;/td&gt;
&lt;td&gt;No built-in enrichers, custom development needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Log Event Properties&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Structured properties with rich data types&lt;/td&gt;
&lt;td&gt;Structured properties, but less emphasis on richness&lt;/td&gt;
&lt;td&gt;Structured properties, but less emphasis on richness&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Library Size&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lightweight&lt;/td&gt;
&lt;td&gt;Lightweight&lt;/td&gt;
&lt;td&gt;Lightweight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Configuration Format&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Code-based, JSON, XML&lt;/td&gt;
&lt;td&gt;XML, JSON, code-based&lt;/td&gt;
&lt;td&gt;XML, code-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Support for .NET Core&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Excellent support for .NET Core&lt;/td&gt;
&lt;td&gt;Excellent support for .NET Core&lt;/td&gt;
&lt;td&gt;Excellent support for .NET Core&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom Sinks/Appenders&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Easy to create custom sinks&lt;/td&gt;
&lt;td&gt;Easy to create custom targets&lt;/td&gt;
&lt;td&gt;Easy to create custom appenders&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Serilog is a powerful logging framework supporting structured logging in ASP.NET Core applications. By configuring Serilog with different sinks and enrichers, you can analyze your application's behavior and performance. Best practices for structured logging help you make your logs informative, manageable, and useful for diagnosing issues in your enterprise applications.&lt;/p&gt;

&lt;p&gt;By following the steps outlined in this article, you can set up a robust logging system that enhances your application's observability and helps you maintain high reliability and performance.&lt;/p&gt;

&lt;p&gt;Hope you find this blog post helpful. Happy coding and exploring with Serilog!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For those interested in learning more about .NET development, check out our &lt;a href="https://wirefuture.com/blog/dot-net-development"&gt;.NET Development&lt;/a&gt; blogs. Stay updated with the latest insights and best practices!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>csharp</category>
      <category>aspnet</category>
      <category>aspnetcore</category>
    </item>
    <item>
      <title>Advanced Angular Forms: Dynamic Fields &amp; Custom Validators</title>
      <dc:creator>Tapesh Mehta</dc:creator>
      <pubDate>Wed, 26 Jun 2024 16:19:05 +0000</pubDate>
      <link>https://dev.to/wirefuture/advanced-angular-forms-dynamic-fields-custom-validators-3cn0</link>
      <guid>https://dev.to/wirefuture/advanced-angular-forms-dynamic-fields-custom-validators-3cn0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Forms are a fundamental part of web applications, allowing users to input and submit data. Form handling in Angular is robust and flexible using reactive forms. More complex and dynamic forms of applications require advanced techniques to handle them. In this article, we'll delve into advanced Angular form handling, focusing on dynamic forms and custom validators. We'll use Angular 18.0.3 for this and leverage the new features and improvements. This guide will help developers of any &lt;a href="https://wirefuture.com/blog/angular-development"&gt;Angular Development&lt;/a&gt; Company to improve their form handling capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up the Angular Project
&lt;/h2&gt;

&lt;p&gt;First, let's set up a new Angular project. Ensure you have Angular CLI installed, then create a new project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new advanced-angular-forms
cd advanced-angular-forms
ng add @angular/forms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup provides the basic structure and dependencies needed for our application. The Angular CLI facilitates a smooth development experience by scaffolding the project structure and managing dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Dynamic Forms
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.angular.lat/guide/dynamic-form"&gt;Dynamic forms&lt;/a&gt; are forms whose structure can change at runtime. This is useful when form fields need to be added or removed based on user interactions or data retrieved from a server. These forms provide flexibility and adaptability, crucial for applications with variable data input requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Define the Form Model
&lt;/h3&gt;

&lt;p&gt;Start by defining a form model using FormGroup and FormControl in your component. Create a new component for our form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate component dynamic-form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In dynamic-form.component.ts, define the form model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms';

@Component({
  selector: 'app-dynamic-form',
  templateUrl: './dynamic-form.component.html',
  styleUrls: ['./dynamic-form.component.css']
})
export class DynamicFormComponent implements OnInit {
  dynamicForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.dynamicForm = this.fb.group({
      name: ['', Validators.required],
      items: this.fb.array([])
    });
  }

  ngOnInit(): void { }

  get items(): FormArray {
    return this.dynamicForm.get('items') as FormArray;
  }

  addItem(): void {
    this.items.push(this.fb.control('', Validators.required));
  }

  removeItem(index: number): void {
    this.items.removeAt(index);
  }

  onSubmit(): void {
    console.log(this.dynamicForm.value);
  }
}

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

&lt;/div&gt;



&lt;p&gt;In this code, we use FormBuilder to simplify the creation of our form model. The form consists of a name control and an items form array. The items array will hold dynamically added form controls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Build the Template
&lt;/h3&gt;

&lt;p&gt;In dynamic-form.component.html, create a form template that allows adding and removing form controls dynamically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form [formGroup]="dynamicForm" (ngSubmit)="onSubmit()"&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;label for="name"&amp;gt;Name&amp;lt;/label&amp;gt;
    &amp;lt;input id="name" formControlName="name"&amp;gt;
  &amp;lt;/div&amp;gt;

  &amp;lt;div formArrayName="items"&amp;gt;
    &amp;lt;div *ngFor="let item of items.controls; let i = index"&amp;gt;
      &amp;lt;label for="item-{{ i }}"&amp;gt;Item {{ i + 1 }}&amp;lt;/label&amp;gt;
      &amp;lt;input [id]="'item-' + i" [formControlName]="i"&amp;gt;
      &amp;lt;button type="button" (click)="removeItem(i)"&amp;gt;Remove&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;

  &amp;lt;button type="button" (click)="addItem()"&amp;gt;Add Item&amp;lt;/button&amp;gt;
  &amp;lt;button type="submit" [disabled]="!dynamicForm.valid"&amp;gt;Submit&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;This template uses Angular's form directives to bind the form model to the view. The *ngFor directive iterates over the items array, creating form controls dynamically. The formArrayName directive binds the form array to the template, ensuring synchronization between the model and view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Custom Validators
&lt;/h2&gt;

&lt;p&gt;Custom validators are necessary for complex validation logic that goes beyond Angular's built-in validators. Validators ensure that the data entered by users meets specific criteria, enhancing data integrity and user experience. Let's implement a custom validator that ensures no duplicate items are added to the dynamic form.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create the Validator Function
&lt;/h3&gt;

&lt;p&gt;In dynamic-form.component.ts, add a custom validator function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';

export function uniqueItemsValidator(): ValidatorFn {
  return (formArray: AbstractControl): ValidationErrors | null =&amp;gt; {
    const items = formArray.value;
    const uniqueItems = new Set(items);
    return items.length !== uniqueItems.size ? { duplicateItems: true } : null;
  };
}

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

&lt;/div&gt;



&lt;p&gt;This function checks for duplicate items by comparing the length of the items array with the length of a Set created from the items array. If they differ, it means there are duplicates, and the validator returns an error object.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Apply the Validator to the Form Array
&lt;/h3&gt;

&lt;p&gt;Update the form group definition to include the custom validator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.dynamicForm = this.fb.group({
  name: ['', Validators.required],
  items: this.fb.array([], uniqueItemsValidator())
});

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

&lt;/div&gt;



&lt;p&gt;Here, we attach the uniqueItemsValidator to the items form array, ensuring that our custom validation logic is applied whenever the form array changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Display Validation Errors
&lt;/h3&gt;

&lt;p&gt;Update the template to display validation errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div formArrayName="items"&amp;gt;
  &amp;lt;div *ngFor="let item of items.controls; let i = index"&amp;gt;
    &amp;lt;label for="item-{{ i }}"&amp;gt;Item {{ i + 1 }}&amp;lt;/label&amp;gt;
    &amp;lt;input [id]="'item-' + i" [formControlName]="i"&amp;gt;
    &amp;lt;button type="button" (click)="removeItem(i)"&amp;gt;Remove&amp;lt;/button&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div *ngIf="items.hasError('duplicateItems')"&amp;gt;
    Duplicate items are not allowed.
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;This ensures that users receive immediate feedback when they attempt to add duplicate items, enhancing the form's usability and data integrity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;p&gt;When dealing with dynamic forms, performance can be a concern, especially if forms are large or complex. Here are some tips to keep performance in check:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debounce Input Changes:&lt;/strong&gt; Use debounceTime with valueChanges to reduce the frequency of form updates. This can prevent performance degradation in forms with many controls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.dynamicForm.valueChanges.pipe(
  debounceTime(300)
).subscribe(value =&amp;gt; {
  console.log(value);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;OnPush Change Detection:&lt;/strong&gt; Use ChangeDetectionStrategy.OnPush to reduce unnecessary change detection cycles. This strategy tells Angular to check the component's view only when its input properties change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component({
  selector: 'app-dynamic-form',
  templateUrl: './dynamic-form.component.html',
  styleUrls: ['./dynamic-form.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicFormComponent { /*...*/ }

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Lazy Loading Form Controls:&lt;/strong&gt; Load form controls only when necessary, such as when a user interacts with a particular section of the form. This can significantly reduce initial load times and improve performance.&lt;/p&gt;

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

&lt;p&gt;Advanced form scenarios in Angular require creating dynamic forms and using custom validators to validate data integrity. Using Angular's reactive forms, we build flexible, robust forms that respond to changing requirements. Taking performance into account, these techniques can be used to produce fast and friendly forms in any Angular app.&lt;/p&gt;

&lt;p&gt;This article demonstrated how to create dynamic forms and custom validators, from which more complex form-based features can be built in Angular. Exploring these concepts will help you to fully utilize Angular's form management capabilities. As you continue to create applications, these advanced form handling methods will prove invaluable for producing user-friendly, responsive, and dynamic forms.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
