<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Praneet Nadkar</title>
    <description>The latest articles on Forem by Praneet Nadkar (@praneetnadkar).</description>
    <link>https://forem.com/praneetnadkar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F127487%2Fa59a36e9-d66b-4066-a462-4e8832df3eb8.jpeg</url>
      <title>Forem: Praneet Nadkar</title>
      <link>https://forem.com/praneetnadkar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/praneetnadkar"/>
    <language>en</language>
    <item>
      <title>Getting Started with OpenTelemetry in C# - Part 1</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Mon, 03 Mar 2025 09:02:36 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/getting-started-with-opentelemetry-in-c-part-1-2pgm</link>
      <guid>https://forem.com/praneetnadkar/getting-started-with-opentelemetry-in-c-part-1-2pgm</guid>
      <description>&lt;p&gt;Software applications grow in complexity and monitoring and troubleshooting becomes more critical than developing. OpenTelemetry, an open-source observability framework, provides a common way to collect and export telemetry data, such as traces, metrics, and logs, from your applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  How We Used to Do It: A Look at the Past
&lt;/h2&gt;

&lt;p&gt;Before OpenTelemetry or other modern observability tools existed, developers had to manually generate correlation IDs for tracking requests across services. This often involved-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generating a unique ID at the start of a request&lt;/li&gt;
&lt;li&gt;Adding it to API response headers&lt;/li&gt;
&lt;li&gt;Passing the ID across service calls to track the request flow&lt;/li&gt;
&lt;li&gt;Logging the ID manually in different parts of the system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While this approach worked, it required additional effort and was prone to inconsistencies. OpenTelemetry simplifies this by automatically generating trace IDs, propagating them across services, and exporting them in a structured way, making debugging and monitoring much easier.&lt;/p&gt;

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

&lt;p&gt;Like any other telemetry tool, OpenTelemetry provides a set of APIs, libraries, agents, and instrumentation that enables you to capture distributed traces, metrics, and logs from your application. &lt;/p&gt;

&lt;p&gt;All you have to do is gain a comprehensive view of your application's behavior, making it easier to detect issues, optimize performance, and troubleshoot in real time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why OpenTelemetry then?
&lt;/h2&gt;

&lt;p&gt;Ans - a unified way for ALL !!&lt;br&gt;
You manage observability data from different sources, without vendor lock-in. You can&lt;/p&gt;

&lt;p&gt;-Monitor system health and performance&lt;br&gt;
-Detect bottlenecks and reduce downtime&lt;br&gt;
-Trace the flow of requests across microservices&lt;br&gt;
-Ensure seamless integration with popular backend observability -platforms like Prometheus, Grafana etc&lt;/p&gt;
&lt;h2&gt;
  
  
  What the heck is vendor lock-in?
&lt;/h2&gt;

&lt;p&gt;Vendor lock-in refers to a situation where a customer becomes dependent on a particular vendor's products or services, making it difficult or expensive to switch to another vendor. This dependency is often created because the customer has integrated the vendor's specific technologies, tools, or services into their infrastructure.&lt;/p&gt;

&lt;p&gt;Vendor lock-in can occur when&lt;br&gt;
Proprietary Tools&lt;br&gt;
Data Portability Issues&lt;br&gt;
Custom Integrations&lt;/p&gt;

&lt;p&gt;Vendor lock-in can be risky for businesses because it limits flexibility, increases long-term costs, and may make it harder to adopt better or more cost-effective solutions in the future. Open standards and open-source tools, like OpenTelemetry, are often used to avoid this issue, as they provide greater interoperability across different platforms and vendors.&lt;/p&gt;
&lt;h2&gt;
  
  
  Spans and Activities
&lt;/h2&gt;

&lt;p&gt;Each request is associated with a trace, represented as a tree of System.Diagnostics.Activity instances. The first Activity serves as the root, tracking the overall duration and success/failure of the request. Child activities can be created to monitor specific steps, such as database queries, allowing independent tracking of their duration and outcome.&lt;/p&gt;

&lt;p&gt;Activities also store metadata, including:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OperationName (type of work)&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Tags (descriptive parameters)&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Events (timestamped logs)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE: In distributed tracing, these units of work are commonly called Spans, but .NET historically uses the term Activity instead.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Activity IDs and Parent-Child Relationships
&lt;/h3&gt;

&lt;p&gt;.NET uses Activity objects to track operations in distributed tracing. Parent-child relationships are established through unique IDs. .NET supports two ID formats:&lt;/p&gt;

&lt;p&gt;Each trace has a globally unique 16-byte trace ID (&lt;strong&gt;Activity.TraceId&lt;/strong&gt;), and each activity within the trace has an 8-byte span ID (&lt;strong&gt;Activity.SpanId&lt;/strong&gt;). Parent-child relationships are defined using &lt;strong&gt;Activity.ParentSpanId&lt;/strong&gt;, allowing tracking across different processes.&lt;/p&gt;

&lt;p&gt;A span is the fundamental unit of a trace, representing a distinct part of a distributed system's workflow. Multiple spans form a trace, which is structured like a tree, showing the start and end times of each span.&lt;/p&gt;

&lt;p&gt;In .NET, a span is represented by an Activity. The OpenTelemetry client for .NET leverages the existing Activity class, allowing applications to generate OpenTelemetry-compatible traces using the .NET Runtime itself.&lt;/p&gt;

&lt;p&gt;To create a span in .NET, an ActivitySource is first defined:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static readonly ActivitySource Activity = new(nameof(MyBestSideProjectIdeaEver));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Activity Lifecycle
&lt;/h3&gt;

&lt;p&gt;Each thread has a &lt;strong&gt;Current&lt;/strong&gt; activity that flows with synchronous and asynchronous calls.&lt;br&gt;
Starting a new &lt;strong&gt;Activity&lt;/strong&gt; makes it the current activity until it stops, after which the previous activity is restored.&lt;br&gt;
Activities record StartTimeUtc and calculate Duration upon stopping.&lt;br&gt;
Tracking Across Process Boundaries&lt;br&gt;
To maintain trace continuity across services, parent IDs are transmitted via HTTP headers:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;W3C TraceContext&lt;/em&gt; format uses standard headers. Hierarchical format uses a custom request-id header. .NET automatically encodes and decodes Activity IDs in HTTP requests, reducing the need for manual implementation.&lt;/p&gt;
&lt;h2&gt;
  
  
  Activity vs ActivitySource
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Activity
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Represents a &lt;strong&gt;single unit of work&lt;/strong&gt; (span) within a trace.
&lt;/li&gt;
&lt;li&gt;Tracks operations such as HTTP requests, database calls, or background tasks.
&lt;/li&gt;
&lt;li&gt;Captures metadata like start time, duration, tags, events, and parent-child relationships.
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Example:
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using (var activity = new Activity("ProcessOrder"))
{
    activity.Start();
    // Perform work
    activity.Stop();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  ActivitySource
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Acts as a factory for creating Activity instances in an organized and efficient manner.&lt;/li&gt;
&lt;li&gt;Enables filtering and sampling before an Activity is created, reducing unnecessary instrumentation overhead.&lt;/li&gt;
&lt;li&gt;Encourages structured tracing by defining named sources for activities.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static readonly ActivitySource ActivitySource = new("BestEverServiceName");

using (var activity = ActivitySource.StartActivity("ProcessOrder"))
{
    // Work inside this block is recorded in the Activity
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Attributes
&lt;/h2&gt;

&lt;p&gt;Attributes in OpenTelemetry are key-value pairs that provide additional context to a trace. In .NET, these are referred to as Tags and can be added to an Activity to capture metadata about operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;activity?.SetTag("user_agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
activity?.SetTag("client_ip", "192.168.1.100");
activity?.SetTag("name", "godzilla");

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Collecting Traces
&lt;/h2&gt;

&lt;p&gt;Activities must be collected and stored for later analysis. Tools like Application Insights, OpenTelemetry, or third-party APM solutions help with this.&lt;br&gt;
In order to make a system observable, it must be instrumented: That is, code from the system’s components must emit traces, metrics, and logs.&lt;/p&gt;

&lt;p&gt;Using OpenTelemetry, you can instrument your code in two primary ways:&lt;br&gt;
&lt;strong&gt;Code-based solutions&lt;/strong&gt; via official APIs and SDKs for most languages&lt;br&gt;
&lt;strong&gt;Zero-code solutions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Code-based solutions allow you to get deeper insight and rich telemetry from your application itself. They let you use the OpenTelemetry API to generate telemetry from your application, which acts as an essential complement to the telemetry generated by zero-code solutions.&lt;/p&gt;

&lt;p&gt;Zero-code solutions are great for getting started, or when you can’t modify the application, you need to get telemetry out of. They provide rich telemetry from libraries you use and/or the environment your application runs in. Another way to think of it is that they provide information about what’s happening at the edges of your application.&lt;/p&gt;

&lt;p&gt;You can use both solutions simultaneously.&lt;/p&gt;

&lt;p&gt;For a deeper dive into OpenTelemetry concepts, refer to the &lt;a href="https://opentelemetry.io/docs/" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;OpenTelemetry simplifies observability by providing a standardized way to collect traces, metrics, and logs across distributed applications.&lt;/li&gt;
&lt;li&gt;Vendor lock-in is a major challenge with proprietary observability tools. OpenTelemetry ensures flexibility and interoperability.&lt;/li&gt;
&lt;li&gt;Before OpenTelemetry, manual tracking was tedious—developers had to generate and propagate correlation IDs themselves. OpenTelemetry automates this process.&lt;/li&gt;
&lt;li&gt;Spans (Activities in .NET) are the building blocks of tracing and help track request flows across services.&lt;/li&gt;
&lt;li&gt;ActivitySource in .NET provides a structured way to create traces efficiently while reducing unnecessary instrumentation overhead.&lt;/li&gt;
&lt;li&gt;Attributes (Tags) enrich traces by adding contextual metadata, making debugging more effective.&lt;/li&gt;
&lt;li&gt;Instrumentation can be done via code-based or zero-code solutions, or both for deeper insights into system performance.&lt;/li&gt;
&lt;li&gt;OpenTelemetry integrates seamlessly with popular observability platforms like Prometheus, Grafana, Application Insights, AWS Cloudwatch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's now shift our focus to the practical implementation of OpenTelemetry in a distributed .NET environment. In Part 2, we will look at the code in the simplest way and break it down and understand how to do it.&lt;/p&gt;

</description>
      <category>otel</category>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>C# Collections - how to choose?</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Mon, 25 Oct 2021 05:41:29 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/c-collections-how-to-choose-loh</link>
      <guid>https://forem.com/praneetnadkar/c-collections-how-to-choose-loh</guid>
      <description>&lt;h6&gt;
  
  
  Cover image &lt;a href="https://unsplash.com/@clemono" rel="noopener noreferrer"&gt;source&lt;/a&gt;
&lt;/h6&gt;

&lt;h2&gt;
  
  
  Collections
&lt;/h2&gt;

&lt;p&gt;C# collections have plenty of options to use. When it comes to simple scenarios and small data handling any of these would work fine or at least give you the desired results. Things start to get messy when you have complex scenarios like multi-threading, huge chunks of data, indexing on collections, searching etc.&lt;/p&gt;

&lt;p&gt;The Microsoft &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/collections/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; on collections is a decent place to get started. One of the key things to note from this documentation is:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There are two main types of collections; generic collections and non-generic collections. Generic collections are type-safe at compile time. Because of this, generic collections typically offer better performance. Generic collections accept a type parameter when they are constructed and do not require that you cast to and from the Object type when you add or remove items from the collection.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This means that, in general, a generic collection should be used. The non generic collections will be stored as Object. This means that they will need casting when you are playing around with data. IMHO, I think this will play a very imp role when it comes to performance.&lt;/p&gt;

&lt;p&gt;The MSDN link I added before has an excellent piece of advice that will help us in understanding which collection is to be chosen based on our requirement.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Collection&lt;/th&gt;
&lt;th&gt;Generic Option&lt;/th&gt;
&lt;th&gt;Non-generic Option&lt;/th&gt;
&lt;th&gt;Thread-safe or immutable collection options&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Store items as key/value pairs for quick look-up by key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Dictionary&amp;lt;TKey,TValue&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Hashtable&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ConcurrentDictionary&amp;lt;TKey,TValue&amp;gt;&lt;/code&gt;, &lt;code&gt;ReadOnlyDictionary&amp;lt;TKey,TValue&amp;gt;&lt;/code&gt;, &lt;code&gt;ImmutableDictionary&amp;lt;TKey,TValue&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access items by index&lt;/td&gt;
&lt;td&gt;&lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Array&lt;/code&gt;, &lt;code&gt;ArrayList&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ImmutableList&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;ImmutableArray&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use items first-in-first-out (FIFO)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Queue&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Queue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ConcurrentQueue&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;ImmutableQueue&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use data Last-In-First-Out (LIFO)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Stack&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Stack&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ConcurrentStack&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;ImmutableStack&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access items sequentially&lt;/td&gt;
&lt;td&gt;&lt;code&gt;LinkedList&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;No recommendation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;No recommendation&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Receive notifications when items are removed or added to the collection. (implements &lt;code&gt;INotifyPropertyChanged&lt;/code&gt; and &lt;code&gt;INotifyCollectionChanged&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ObservableCollection&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;No recommendation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;No recommendation&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A sorted collection&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SortedList&amp;lt;TKey,TValue&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SortedList&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ImmutableSortedDictionary&amp;lt;TKey,TValue&amp;gt;&lt;/code&gt;, &lt;code&gt;ImmutableSortedSet&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A set for mathematical functions&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;HashSet&amp;lt;T&amp;gt;&lt;/code&gt; ,&lt;code&gt;SortedSet&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;No recommendation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ImmutableHashSet&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;ImmutableSortedSet&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Another important point that can act as a deciding factor is Algorithmic complexity of &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/collections/#algorithmic-complexity-of-collections" rel="noopener noreferrer"&gt;collections&lt;/a&gt;. Before you chose a collection, it is really important that the complexities are taken into account. This can sort out a lot of issues with respect to time complexities before hand.&lt;/p&gt;

&lt;p&gt;In addition to this, David Fowler tweeted excellent points on Hashtable, Dictionary, ConcurrentDictionary, ImmutableDictionary&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1444467842418548737-778" src="https://platform.twitter.com/embed/Tweet.html?id=1444467842418548737"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1444467842418548737-778');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1444467842418548737&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dictionary&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1444467844641484803-856" src="https://platform.twitter.com/embed/Tweet.html?id=1444467844641484803"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1444467844641484803-856');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1444467844641484803&amp;amp;theme=dark"
  }



&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HashTable, ImmutableDictionary&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1444467845589454851-698" src="https://platform.twitter.com/embed/Tweet.html?id=1444467845589454851"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1444467845589454851-698');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1444467845589454851&amp;amp;theme=dark"
  }



&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ConcurrentDictionary&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1444467843651620866-196" src="https://platform.twitter.com/embed/Tweet.html?id=1444467843651620866"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1444467843651620866-196');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1444467843651620866&amp;amp;theme=dark"
  }



&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The motivation for all of this to put into once place, to keep things handy, came when I was working on one of the scenarios to select a collection. I ran into Scott Hanselman's &lt;a href="https://www.hanselman.com/blog/differences-between-hashtable-vs-dictonary-vs-concurrentdictionary-vs-immutabledictionary" rel="noopener noreferrer"&gt;blog&lt;/a&gt;, where he added a few pointers from David's tweet.&lt;/p&gt;

&lt;p&gt;I would keep this handy for the next time I have to work on collections.&lt;/p&gt;

</description>
      <category>c</category>
      <category>collections</category>
    </item>
    <item>
      <title>Authenticating &amp; Calling Google Cloud Function with Service Account</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Mon, 07 Sep 2020 14:47:50 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/authenticating-calling-google-cloud-function-with-service-account-4pjb</link>
      <guid>https://forem.com/praneetnadkar/authenticating-calling-google-cloud-function-with-service-account-4pjb</guid>
      <description>&lt;p&gt;(Cover Image from &lt;a href="https://unsplash.com/@cdr6934" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The services from Google Cloud have been around for a while. Google Cloud Functions is a serverless, event-driven service within Google Cloud Platform meant to create and implement programmatic functions within Google's public cloud.&lt;/p&gt;

&lt;p&gt;All infrastructure resources are provisioned and recovered automatically by Google Cloud Platform (GCP). The GCP also gives a good list of console commands to work with them. &lt;/p&gt;

&lt;h3&gt;
  
  
  Authenticating Cloud Functions
&lt;/h3&gt;

&lt;p&gt;There are various scenarios which are applicable for authenticating the functions. One such scenario for me for authenticating user Service account.&lt;/p&gt;

&lt;p&gt;At this point of time, I am assuming you already have a service account created. For the very first step to start with, add your service account to IAM. For this Navigate to IAM on your GCP, and click on Add&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvermj2ul91qd6aaou8vx.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvermj2ul91qd6aaou8vx.PNG" alt="Alt Text" width="283" height="49"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you do that, there will be an input for member name. Put your service account name there. Next we will add roles to this service account.&lt;/p&gt;

&lt;p&gt;To authenticate a could service using service account, make sure your service account has these roles&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Service Account Token Creator&lt;/li&gt;
&lt;li&gt;Service Account User&lt;/li&gt;
&lt;li&gt;Service Usage Consumer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Click on Save to save your data.&lt;/p&gt;

&lt;p&gt;One last setup before we jump to the code for generating token is generating keys for the Service Account. Navigate to the service accounts on your GCP. Under the list, that shows the service accounts, click on the Create Key option. This should download a .json file that will have the key information. This is an imp file that has sensitive information. For more, refer &lt;a href="https://cloud.google.com/iam/docs/creating-managing-service-account-keys#iam-service-account-keys-create-console" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our service account is now setup. Now we need to get an auth token for this service account. This generated token, can then be used to call a GCP service that is using auth as service account. I had used a google cloud function in my scenario. Make sure the service we are trying to access, has the same service account set. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwprcaaemevf16uwdvimd.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwprcaaemevf16uwdvimd.PNG" alt="Alt Text" width="361" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now lets look the code snippet that will generate a JWT Token for us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from google.oauth2 import id_token
from google.oauth2 import service_account
import google.auth
import google.auth.transport.requests
from google.auth.transport.requests import AuthorizedSession
import requests

# path to your cloud function or any other service
url = 'https://{region}-{project-id}.cloudfunctions.net/{cloud-function-name}'

# path to you keys file that was downloaded when keys for SA were created
keyFilePath = 'key.json'
creds = service_account.IDTokenCredentials.from_service_account_file
(keyFilePath,
target_audience=url)
# auth session
authed_session = AuthorizedSession(creds)

# make authenticated request and print the response, status_code
resp = authed_session.get(url)

# to verify an ID Token
request = google.auth.transport.requests.Request()
token = creds.token
# print the generated token
print(token)
print(id_token.verify_token(token,request))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should give you the JWT token which will be required to authenticate the subsequent requests. All you have to do is pass this token in the headers when calling the respective cloud service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {token}'.format(token = token)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using these steps we can get a token and then call a service hosted on GCP. The same code and steps can be used to call a GCP cloud function from AWS Lambda or any other HTTP Request.&lt;/p&gt;

</description>
      <category>python</category>
      <category>google</category>
      <category>cloud</category>
      <category>cloudfunctions</category>
    </item>
    <item>
      <title>Daily reads for .NET and programming</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Thu, 11 Jun 2020 09:16:37 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/daily-reads-for-net-and-programming-651</link>
      <guid>https://forem.com/praneetnadkar/daily-reads-for-net-and-programming-651</guid>
      <description>&lt;h6&gt;
  
  
  image source: Photo by [Kevin Ku] on Unsplash
&lt;/h6&gt;

&lt;p&gt;Technologies are changing, evolving and deprecating every day. One needs to be well versed with the jargon like open-source, architecture, programming model or buzzwords like AI, ML.&lt;/p&gt;

&lt;p&gt;To keep yourself updated with these trends, reading and exploring is imperative. When I start my day and before I jump onto my work, I go through some posts, blogs and articles.  The internet is flooded with content so here is my recommendation for beginners.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.alvinashcraft.com/" rel="noopener noreferrer"&gt;Dew Drop&lt;/a&gt;&lt;br&gt;
This is my favorite link and I never miss on reading this one everyday. The best part is that it is regularly updated with great content to explore.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://discoverdot.net/" rel="noopener noreferrer"&gt;Discover Dot&lt;/a&gt;&lt;br&gt;
My second most favorite and an another brilliant web-page to visit daily. A unified place that has new NuGet packages information, blogs, links and videos to go through.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://channel9.msdn.com/Shows/On-NET" rel="noopener noreferrer"&gt;Channel 9&lt;/a&gt;&lt;br&gt;
An extensive channel to go through .NET videos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/"&gt;Dev.to&lt;/a&gt;&lt;br&gt;
Obviously, how can I forget Dev.to :) &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.cwa.me.uk/" rel="noopener noreferrer"&gt;The Morning Brew&lt;/a&gt;&lt;br&gt;
Another blog post that gets updated on a daily basis is this one. This too has some useful references to go through.&lt;/p&gt;

&lt;p&gt;This is my list of top 5 links that I usually follow and read whenever I get time. Also, Twitter is another good source that gives you a lot of content to explore. A great microblogging and social networking service where I follow many tech evangelists.&lt;br&gt;
If there is an amazing data or blog that I am not aware of, feel free to update these in the comments section.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>dotnet</category>
      <category>learn</category>
      <category>blog</category>
    </item>
    <item>
      <title>Understanding Server-Sent Events</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Thu, 23 Jan 2020 10:58:27 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/understanding-server-sent-events-17n8</link>
      <guid>https://forem.com/praneetnadkar/understanding-server-sent-events-17n8</guid>
      <description>&lt;p&gt;Since a last few weeks I have been checking this with a lot of dev(s) that I know, if they are aware of server-sent events. Surprisingly a very few of them know what is a server-sent event. Let us understand this term.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is SSE?
&lt;/h1&gt;

&lt;p&gt;As the name suggests, an event that is sent or initiated by a server, and this is exactly what it does.&lt;br&gt;
According to the &lt;a href=""&gt;wiki page&lt;/a&gt;, &lt;em&gt;Server-Sent Events (SSE) is a server push technology enabling a client to receive automatic updates from a server via HTTP connection&lt;/em&gt;.&lt;br&gt;
This is standardized as the part of HTML5. The server-sent event is an API that is operated through the &lt;a href=""&gt;EventSource&lt;/a&gt; interface&lt;/p&gt;

&lt;p&gt;A client subscribes to a “stream” from a server and the server will send messages (“event-stream”) to the client until the server closes the stream. &lt;br&gt;
It is the server that decides when and what to send the client and when to end the stream.&lt;/p&gt;
&lt;h1&gt;
  
  
  Why should you know about SSE?
&lt;/h1&gt;

&lt;p&gt;Since the applications and their users are becoming more real-time oriented, you need Server-Sent Events. Displaying the last data updates to your users may change their actions.&lt;/p&gt;
&lt;h1&gt;
  
  
  Why SSE? I have Websockets.
&lt;/h1&gt;

&lt;p&gt;&lt;a href=""&gt;WebSockets&lt;/a&gt; indeed is a long awaited evolution in client/server web technology. They allow a &lt;br&gt;
single TCP socket connection to be established between the client and server which allows for bi-directional, full duplex, messages to be instantly distributed. Now there is a catch, if you read this meticulously, you would definitely notice that WebSockets are bi-directional. So if I need only unidirectional, WebSockets will cause great latency issues.&lt;/p&gt;

&lt;p&gt;SSE is single directional (server to client) which surely would improve the latency issues. If we are looking from a server load point of view, SSE can be a way much better option than WebSockets.&lt;/p&gt;
&lt;h1&gt;
  
  
  Fields
&lt;/h1&gt;

&lt;p&gt;As per the MDN, an event stream is a simple stream of text data which must be encoded using UTF-8. Messages in the event stream are separated by a pair of newline characters. A colon as the first character of a line is in essence a comment, and is ignored.&lt;/p&gt;

&lt;p&gt;Each message received has some combination of the following fields, one per line:&lt;/p&gt;
&lt;h3&gt;
  
  
  event
&lt;/h3&gt;

&lt;p&gt;A string identifying the type of event described. If this is specified, an event will be dispatched on the browser to the listener for the specified event name; the website source code should use addEventListener() to listen for named events. The onmessage handler is called if no event name is specified for a message.&lt;/p&gt;
&lt;h3&gt;
  
  
  data
&lt;/h3&gt;

&lt;p&gt;The data field for the message. When the EventSource receives multiple consecutive lines that begin with data:, it will concatenate them, inserting a newline character between each one. Trailing newlines are removed.&lt;/p&gt;
&lt;h3&gt;
  
  
  id
&lt;/h3&gt;

&lt;p&gt;The event ID to set the EventSource object's last event ID value.&lt;/p&gt;
&lt;h3&gt;
  
  
  retry
&lt;/h3&gt;

&lt;p&gt;The reconnection time to use when attempting to send the event. This must be an integer, specifying the reconnection time in milliseconds. If a non-integer value is specified, the field is ignored.&lt;/p&gt;

&lt;p&gt;&lt;a href=""&gt;click here for MDN Docs&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Examples
&lt;/h1&gt;

&lt;p&gt;To use the server-sent events, we need to call an API from a client and then the server will keep on sending the events, till the stream is closed.&lt;/p&gt;
&lt;h3&gt;
  
  
  .Net Core
&lt;/h3&gt;

&lt;p&gt;Create a controller with any route. Add the following code to the controller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        [HttpGet]
        public async Task Get()
        {
            var response = Response;
            response.Headers.Add("Content-Type", "text/event-stream");

            for (var i = 0; true; ++i)
            {
                await response.WriteAsync($"data: Controller {i} at {DateTime.Now}\r\r");

                response.Body.Flush();
                await Task.Delay(5 * 1000);
            }
        }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In this implementation we are using the WriteAsync method in from the &lt;a href=""&gt;Microsoft.AspNetCore.Http&lt;/a&gt; namespace. The writeAsync method will write the given text to the response body with the UTF-8 encoding.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EventSource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;EventSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://localhost:44317/api/sse&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;open&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eventPhase&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;EventSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLOSED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;EventSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLOSED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Disconnected&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;EventSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CONNECTING&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Connecting...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your browser doesn't support SSE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

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



&lt;p&gt;When I ran the HTML, this is how the output was showing up in the console.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HmbiodUL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/nr5v29mbion8uhwa8p0e.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HmbiodUL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/nr5v29mbion8uhwa8p0e.gif" alt="sse"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>serversentevents</category>
      <category>netcore</category>
      <category>net</category>
      <category>aspnetcore</category>
    </item>
    <item>
      <title>Call AWS AppSync API from JS</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Thu, 17 Oct 2019 11:55:26 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/call-aws-appsync-api-from-js-2lbi</link>
      <guid>https://forem.com/praneetnadkar/call-aws-appsync-api-from-js-2lbi</guid>
      <description>&lt;p&gt;AppSync can do everything GraphQL specifies and also has additional features like authentication, authorization, filtering the data you return and the operations that the clients can perform, depending on which user is in. &lt;/p&gt;

&lt;p&gt;AppSync supports Cognito, API Key, IAM permissions, and Open ID Connect and even provides support for DynamoDB, AWS Lambda, Elasticsearch, HTTP, and RDS as data sources.&lt;/p&gt;

&lt;p&gt;Now to call this AppSync api, it also provides a code generator command with the AWS Amplify CLI which will generate a client code to call the API for you with the AWS Configuration file.&lt;/p&gt;

&lt;p&gt;To integrate your app with the client, make sure you have AWS Amplify CLI installed. You can install it using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @aws-amplify/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then finally&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;amplify add codegen --apiId &amp;lt;API_ID_HERE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate a .ts file which will make you reach pretty much there to integrate.&lt;/p&gt;

&lt;p&gt;However, what if you want to call the API using JS only. I started to dig at many places but didn't find anything concrete. Here is my approach to call the AWS AppSync API using &lt;a href="https://developers.google.com/web/updates/2015/03/introduction-to-fetch" rel="noopener noreferrer"&gt;fetch()&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

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

const configuration = 'awsconfiguration.json';

/**
 * API module for calling the AWS AppSync GraphQL API
 * @module API
 */

/**
 * Call this if a mutation has to be run for the GraphQL API.
 * This method will call AWS AppSync GraphQL API with the mutation sent as a parameter.
 * The mutationQuery parameter should be of proper format, else the API call will fail. 
 * @module mutation
 * @param { mutationQuery } mutationQuery This is the mutation that has to be called for in GraphQL
*/
function mutation(mutationQuery) {
    callAPI(mutationQuery);
}

/**
 * This method will call AWS AppSync GraphQL API with the query sent as a parameter
 * The getQuery parameter should be of proper format, else the API call will fail 
 * @param { getQuery } getQuery This is the query that has to be called for in GraphQL
*/
function query(getQuery) {
    callAPI(getQuery);
}

/**
 * This method calls the AWS AppSync GraphQL API. The path and options to call the API
 * is read via the AWS Config file.
 * @param { query } query This is the query, mutation or subscription that has to be called for in GraphQL
 * @throws {UnauthenticatedError} When the user is authentication to AWS fails.
*/
function callAPI(query){
    readAwsConfiguration(configuration); 
    // this obj will have all the configurations for AWS AppSync
    var obj = JSON.parse(configText);    

    // if the jwt is null, then the user authentication has not happened
    // in such a case, we will raise an errot that the user auth is required
    if(localStorage.getItem('jwt') === null)
    {
        throw new Error('User authentication is required to access the API. ');
    }

    const opts = {
        method: 'POST',
        headers:
        {
            'Content-Type': 'application/json',
            'aws_appsync_region':  obj.AppSync.Default.Region,
            'aws_appsync_authenticationType': obj.AppSync.Default.AuthMode,
            Authorization:  localStorage.getItem('jwt')
        },

        body: query
    };

    const url = obj.AppSync.Default.ApiUrl;

    fetch(url, opts)
        .then(res =&amp;gt; res.json())
        .then(console.log)
        .catch(console.error);
}

/**
 * This method reads the aws configuration file. The config file has the AppSync URL,
 * Auth type and region details for the API
 * @param { file } file This is the file path from where the file has to be read
*/
function readAwsConfiguration(file) {

    var rawFile = new XMLHttpRequest(); // XMLHttpRequest (often abbreviated as XHR) is a browser object accessible in JavaScript that provides data in XML, JSON, but also HTML format, or even a simple text using HTTP requests.
    rawFile.open('GET', file, false); // open with method GET the file with the link file ,  false (synchronous)
    rawFile.onreadystatechange = function () {
        if (rawFile.readyState === 4) // readyState = 4: request finished and response is ready
        {
            if (rawFile.status === 200) // status 200: "OK"
            {
                var allText = rawFile.responseText; //  Returns the response data as a string
                configText = allText;
            }
        }
    }

    rawFile.send(null); //Sends the request to the server Used for GET requests with param null
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I am reading the AWS Configuration from the file awsconfiguration.json&lt;br&gt;
This file has the AWS Configuration with the AppSync URL, Region, AuthMethod etc.&lt;br&gt;
In case if you are wondering from where one should get the configuration json file, you can download it from your AppSync API page.&lt;/p&gt;

&lt;p&gt;Please note that the I have added a header named 'Authorization'. This has the JWT which will be used for authentication.&lt;/p&gt;

&lt;p&gt;Note: If you are using the AWS Cognito, this value should be fetched from&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;signInUserSession.accessToken.jwtToken
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, to call the API, all we have to do is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mutationQuery = JSON.stringify({
        query: `mutation {
            updatePost(input: {postId:"asd97jd-kjd78-alfd"                  
                  authoredBy:"Sam"
                  editedBy:"Jonathan" }) {
              postId
              authoredBy
              editedBy              
            }
          }
          `
    });

    mutation(mutationQuery);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
      <category>awsappsync</category>
      <category>graphql</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Create your own multi date picker using JQuery/Javascript</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Thu, 25 Jul 2019 06:13:42 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/create-your-own-multi-date-picker-using-jquery-javascript-50f6</link>
      <guid>https://forem.com/praneetnadkar/create-your-own-multi-date-picker-using-jquery-javascript-50f6</guid>
      <description>&lt;p&gt;I know this is the era of Vue, Angular, React etc, but there are still applications running on old JQuery and javascript code. Recently I had a task to create or use a multidates picker from JQuery. I ran into the JQuery UI's multidatepicker and it was pretty nice. But I had a lot of issues and challanges customizing it. I then thought of why not creating one like I want.&lt;/p&gt;

&lt;p&gt;Well I am no expert in front-end or scripting, but I still thought it was worth a try.&lt;/p&gt;

&lt;p&gt;Though I was thinking to convert it to a plugin, here is a pure html and jquery code that I did for the multidatepicker. Here is my attempt: &lt;/p&gt;

&lt;h3&gt;
  
  
  Use bootstrap to create a HTML Skeleton
&lt;/h3&gt;

&lt;p&gt;I have used bootstrap to create a HTML skeleton for the calendar that I will build 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;input type="text" id="selectedValues" class="date-values" readonly/&amp;gt;
        &amp;lt;div id="parent" class="container" style="display:none;"&amp;gt;
            &amp;lt;div class="row header-row"&amp;gt;
                &amp;lt;div class="col-xs previous"&amp;gt;
                    &amp;lt;a href="#" id="previous" onclick="previous()"&amp;gt;
                        &amp;lt;i class="fa fa-arrow-left" aria-hidden="true"&amp;gt;&amp;lt;/i&amp;gt;
                    &amp;lt;/a&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class="card-header month-selected col-sm" id="monthAndYear"&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class="col-sm"&amp;gt;
                    &amp;lt;select class="form-control col-xs-6" name="month" id="month" onchange="change()"&amp;gt;&amp;lt;/select&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class="col-sm"&amp;gt;
                    &amp;lt;select class="form-control col-xs-6" name="year" id="year" onchange="change()"&amp;gt;&amp;lt;/select&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class="col-xs next"&amp;gt;
                    &amp;lt;a href="#" id="next" onclick="next()"&amp;gt;
                        &amp;lt;i class="fa fa-arrow-right" aria-hidden="true"&amp;gt;&amp;lt;/i&amp;gt;
                    &amp;lt;/a&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;table id="calendar"&amp;gt;
                &amp;lt;thead&amp;gt;
                    &amp;lt;tr&amp;gt;
                        &amp;lt;th&amp;gt;S&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;M&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;T&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;W&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;T&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;F&amp;lt;/th&amp;gt;
                        &amp;lt;th&amp;gt;S&amp;lt;/th&amp;gt;
                    &amp;lt;/tr&amp;gt;
                &amp;lt;/thead&amp;gt;
                &amp;lt;tbody id="calendarBody"&amp;gt;&amp;lt;/tbody&amp;gt;
            &amp;lt;/table&amp;gt;
        &amp;lt;/div&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;I have added the Bootstrap, Font-awesome(for the previous and next arrows) and JQuery in my html.&lt;/p&gt;

&lt;p&gt;I have added some styles as well to this. The css file can be accessed from &lt;a href="https://github.com/praneetnadkar/multidatepicker/blob/master/multidatepicker/styles.css" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the crux of the script is generating the dates based on the days. Here is my attempt on it:&lt;/p&gt;

&lt;h3&gt;
  
  
  Script to load the calendar
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function loadControl(month, year) {

    addMonths(month);
    addYears(year);

    let firstDay = (new Date(year, month)).getDay();

     // body of the calendar
    var tbl = document.querySelector("#calendarBody");
    // clearing all previous cells
    tbl.innerHTML = "";


    var monthAndYear = document.getElementById("monthAndYear");
    // filing data about month and in the page via DOM.
    monthAndYear.innerHTML = months[month] + " " + year;


    selectYear.value = year;
    selectMonth.value = month;

    // creating the date cells here
    let date = 1;

    selectedDates.push((month + 1).toString() + '/' + date.toString() + '/' + year.toString());

    // there will be maximum 6 rows for any month
    for (let rowIterator = 0; rowIterator &amp;lt; 6; rowIterator++) {

        // creates a new table row and adds it to the table body
        let row = document.createElement("tr");

        //creating individual cells, filing them up with data.
        for (let cellIterated = 0; cellIterated &amp;lt; 7 &amp;amp;&amp;amp; date &amp;lt;= daysInMonth(month, year); cellIterated++) {

            // create a table data cell
            cell = document.createElement("td");
            let textNode = "";

            // check if this is the valid date for the month
            if (rowIterator !== 0 || cellIterated &amp;gt;= firstDay) {
                cell.id = (month + 1).toString() + '/' + date.toString() + '/' + year.toString();
                cell.class = "clickable";
                textNode = date;

                // this means that highlightToday is set to true and the date being iterated it todays date,
                // in such a scenario we will give it a background color
                if (highlightToday
                    &amp;amp;&amp;amp; date === today.getDate() &amp;amp;&amp;amp; year === today.getFullYear() &amp;amp;&amp;amp; month === today.getMonth()) {
                    cell.classList.add("today-color");
                }

                // set the previous dates to be selected
                // if the selectedDates array has the dates, it means they were selected earlier. 
                // add the background to it.
                if (selectedDates.indexOf((month + 1).toString() + '/' + date.toString() + '/' + year.toString()) &amp;gt;= 0) {
                    cell.classList.add(highlightClass);
                }

                date++;
            }

            cellText = document.createTextNode(textNode);
            cell.appendChild(cellText);
            row.appendChild(cell);
        }

        tbl.appendChild(row); // appending each row into calendar body.
    }

    // this adds the button panel at the bottom of the calendar
    addButtonPanel(tbl);

    // function when the date cells are clicked
    $("#calendarBody tr td").click(function (e) {
        var id = $(this).attr('id');
        // check the if cell clicked has a date
        // those with an id, have the date
        if (typeof id !== typeof undefined) {
            var classes = $(this).attr('class');
            if (typeof classes === typeof undefined || !classes.includes(highlightClass)) {
                var selectedDate = new Date(id);
                selectedDates.push((selectedDate.getMonth() + 1).toString() + '/' + selectedDate.getDate().toString() + '/' + selectedDate.getFullYear());
            }
            else {
                var index = selectedDates.indexOf(id);
                if (index &amp;gt; -1) {
                    selectedDates.splice(index, 1);
                }
            }

            $(this).toggleClass(highlightClass);
        }

        // sort the selected dates array based on the latest date first
        var sortedArray = selectedDates.sort((a, b) =&amp;gt; {
            return new Date(a) - new Date(b);
        });

        // update the selectedValues text input
        document.getElementById('selectedValues').value = datesToString(sortedArray);
    });


    var $search = $('#selectedValues');
    var $dropBox = $('#parent');

    $search.on('blur', function (event) {
        //$dropBox.hide();
    }).on('focus', function () {
        $dropBox.show();
    });
}

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

&lt;/div&gt;



&lt;p&gt;I have added a button panel to the bottom of the dates panel. It has two buttons, Reset and Done. &lt;/p&gt;

&lt;p&gt;Also, to set the dates to be pre-selected on load, add your dates to the selectedDates array.&lt;/p&gt;

&lt;p&gt;This is how the control looks:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9cqllgifbveiaw9tigs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz9cqllgifbveiaw9tigs.gif" alt="multi_dates_picker" width="416" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have been trying to improve my code here as I am not a JS or a frontend expert.&lt;/p&gt;

&lt;p&gt;You can download the whole working sample from &lt;a href="https://github.com/praneetnadkar/multidatepicker" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is extremely easy to create your own controls and use them using simple HTML and JQuery/Javascript codes.&lt;/p&gt;

</description>
      <category>jquery</category>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>Using "Reload" options in Chrome</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Thu, 06 Jun 2019 07:29:41 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/using-reload-options-in-chrome-3cgn</link>
      <guid>https://forem.com/praneetnadkar/using-reload-options-in-chrome-3cgn</guid>
      <description>&lt;p&gt;One of the most popular browsers with the best debugging tools is Google Chrome. When working with CSS or JS, the dev tools in chrome are of great help. Chrome definitely makes the dev work easier. On the same lines, while working on the front end things and editing CSS or JS, refreshing is one of the things we are ought to do.&lt;/p&gt;

&lt;p&gt;Let us explore what chrome offers on this little but very important thing.&lt;/p&gt;

&lt;p&gt;Whenever you are working chrome, try this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Press F12 and open the developer tools.&lt;/li&gt;
&lt;li&gt;On the refresh button, on the top left of the browser window, do a right click.&lt;/li&gt;
&lt;li&gt;You will see three options.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qxjcln9mf53ft1l9yc8.png" alt="Reload options" width="800" height="433"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Normal Reload
&lt;/h2&gt;

&lt;p&gt;This is as good as clicking the refresh button or pressing F5.&lt;br&gt;
This will use the cache but re-validate everything during page load. The browser will avoid re-downloading cached JavaScript files, images, text files, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hard Reload
&lt;/h2&gt;

&lt;p&gt;In this option, the browser will not use anything from the cache when making the request. This can also be done using Ctrl+Shift+R option we don't need to open the Developer Console for this. This forces the browser do re-download every JavaScript file, image, text file, etc. Here the cache will still remain as is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Empty Cache and Hard Reload
&lt;/h2&gt;

&lt;p&gt;Use this option if the cache is to be emptied and we want the page to be hard reloaded. Note that here, the browser's cache will not be cleared, it is the page cache which will be cleared. This will force the browser to re-download everything with respect to the page.&lt;br&gt;
This is the best option to use if you really want to reload a web page completely.&lt;/p&gt;

</description>
      <category>chrome</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Code formatting in SSMS</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Thu, 23 May 2019 11:58:39 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/code-formatting-in-ssms-3g20</link>
      <guid>https://forem.com/praneetnadkar/code-formatting-in-ssms-3g20</guid>
      <description>&lt;p&gt;I am big fan of the code formatting that happens in Visual Studio. It does help. Really, there are times when it makes it easier to just format it and you feel good and nice and think that it is readable. Sometimes, someone else's formatted code is obviously more readable. &lt;br&gt;
The other day, I was trying to find something similar for SQL Server and found this: &lt;a href="http://architectshack.com/PoorMansTSqlFormatter.ashx" rel="noopener noreferrer"&gt;The Poor Man's Sql Formatter&lt;/a&gt;&lt;br&gt;
The Poor Man's Sql Formatter. It is indeed helpful and works smooth as an add-on for SQL Server Management Studio. &lt;/p&gt;

&lt;p&gt;You can install it and try it. Is there anything else similar to this that anyone knows?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>git cherry-pick is bliss. More than the git merge</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Mon, 20 May 2019 08:46:53 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/git-cherry-pick-is-bliss-more-than-the-git-merge-241d</link>
      <guid>https://forem.com/praneetnadkar/git-cherry-pick-is-bliss-more-than-the-git-merge-241d</guid>
      <description>&lt;p&gt;When you are working on separate branches with separate teams in parallel there are immense no of check-ins that we all do. The next big thing is to merge the code on git. I have started to feel that this becomes extremely easy if each functionality as a whole has a single check-in, which in-turn will have a commit id. It then makes it really easier to merge by cherry-pick rather than the whole branch merge. It also gives a power to pick just one part of the code base and not as a whole.&lt;/p&gt;

&lt;p&gt;what do you guys prefer while merging? I would love to know and learn.&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Generating a fake data in .Net Core API</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Tue, 14 May 2019 07:10:46 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/generating-a-fake-data-in-net-core-api-3kba</link>
      <guid>https://forem.com/praneetnadkar/generating-a-fake-data-in-net-core-api-3kba</guid>
      <description>&lt;p&gt;Well, the other day, I was working on something where I needed some fake data or some random data to be generated in my .net core web API. On searching I ran into many blogs and links and I am sure there are many who have run into this scenario where we have to generate a fake data for some or the other reason. &lt;/p&gt;

&lt;p&gt;Well there is a simple and easy way to do it, add a loop, create a new object of a class and add it to a list. Return the list.&lt;/p&gt;

&lt;p&gt;Well all of us are aware of this. However, it is was pain in the neck to add this new and loops every time. I searched and found &lt;a href="http://genfu.io/" rel="noopener noreferrer"&gt;Genfu&lt;/a&gt; which generates the test data. I am like wow! Most of my work is done now. If you look at it, I will have to call a method from this GenFu package which is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GenFu.GenFu.ListOf&amp;lt;T&amp;gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But again, I was thinking, I will have to write it at too many places. What else can be done here?&lt;/p&gt;

&lt;p&gt;I was thinking to write a service for this, add it in the startup, and use it through DI in every controller. I somehow managed to do this. Here is my interface and the service that I am using for DI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    public interface IDataGenerator&amp;lt;T&amp;gt; where T : class
    {
        /// &amp;lt;summary&amp;gt;
        /// Generates a collection of type T based on the properties in T
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;returns&amp;gt;List&amp;lt;T&amp;gt;&amp;lt;/returns&amp;gt;
        List&amp;lt;T&amp;gt; Collection();

        /// &amp;lt;summary&amp;gt;
        /// Generates the collection of type T of size = length 
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="length"&amp;gt;The size of the collection to be passed&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;A collection of type T based on the length passed&amp;lt;/returns&amp;gt;
        List&amp;lt;T&amp;gt; Collection(int length);

        /// &amp;lt;summary&amp;gt;
        /// Generates an object of type T with data
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;returns&amp;gt;T with data based on the properties in T&amp;lt;/returns&amp;gt;
        T Instance();
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is my class inheriting the interface.&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 DataGeneratorService&amp;lt;T&amp;gt; : IDataGenerator&amp;lt;T&amp;gt;
        where T : class, new()
    {
        /// &amp;lt;summary&amp;gt;
        /// Generates a collection of type T based on the properties in T
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;returns&amp;gt;List&amp;lt;T&amp;gt;&amp;lt;/returns&amp;gt;
        public List&amp;lt;T&amp;gt; Collection() =&amp;gt; GenFu.GenFu.ListOf&amp;lt;T&amp;gt;();

        /// &amp;lt;summary&amp;gt;
        /// Generates the collection of type T of size = length 
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;param name="length"&amp;gt;The size of the collection to be passed&amp;lt;/param&amp;gt;
        /// &amp;lt;returns&amp;gt;A collection of type T based on the length passed&amp;lt;/returns&amp;gt;
        public List&amp;lt;T&amp;gt; Collection(int length) =&amp;gt; GenFu.GenFu.ListOf&amp;lt;T&amp;gt;(length);

        /// &amp;lt;summary&amp;gt;
        /// Generates an object of type T with data
        /// &amp;lt;/summary&amp;gt;
        /// &amp;lt;returns&amp;gt;T with data based on the properties in T&amp;lt;/returns&amp;gt;
        public T Instance() =&amp;gt; GenFu.GenFu.New&amp;lt;T&amp;gt;();
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, there can be many methods that can be added. GenFu gives way lot of things. I have shown a couple of them here. You can always try and play with them.&lt;/p&gt;

&lt;p&gt;The method Collection will give me a list of type T and Collection(int length) will give me a list of size which is passed to the method.&lt;/p&gt;

&lt;p&gt;Now here, don't forget to add the package Genfu. You can add it using package manager console like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;install-package GenFu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it, now the only thing that remains is adding this to the startup. Since this is a generic thing, I have added this to the startup like this:&lt;/p&gt;

&lt;p&gt;In your ConfigureServices method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services.AddSingleton(typeof(IDataGenerator&amp;lt;&amp;gt;), typeof(DataGeneratorService&amp;lt;&amp;gt;));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now before going to DI, consider a class like a Contact. This is a model class for which the data will be generated.&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 Contact
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string EmailAdress { get; set; }
        public string PhoneNumber { get; set; }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, I have a values controller, in which there is a HttpGet, that will give me a fake data for these contacts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Route("api/[controller]")]
public class ValuesController : Controller
{
    private readonly IDataGenerator&amp;lt;Contact&amp;gt; _contactsGeneratorService;

    public ValuesController(IDataGenerator&amp;lt;Contact&amp;gt; dataGeneratorService)
    {
        _contactsGeneratorService = dataGeneratorService;
    }

    // GET: api/&amp;lt;controller&amp;gt;
    [HttpGet]
    public IEnumerable&amp;lt;Contact&amp;gt; Get()
    {
        var data = _contactsGeneratorService.Collection(100);
        return data;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it ! I have a service ready. Whenever I need any fake data, I will just inject into my controller and run it.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnetcore</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>What are developers looking for? A good tech or a good manager</title>
      <dc:creator>Praneet Nadkar</dc:creator>
      <pubDate>Mon, 22 Apr 2019 06:12:36 +0000</pubDate>
      <link>https://forem.com/praneetnadkar/what-are-developers-looking-for-a-good-tech-or-a-good-manager-nbf</link>
      <guid>https://forem.com/praneetnadkar/what-are-developers-looking-for-a-good-tech-or-a-good-manager-nbf</guid>
      <description>&lt;p&gt;I always wonder if everyone is happy as a developer. I have always thought that many, either look for a good manager or a good tech or if you are lucky, you get both. In cases where even if you have a pretty old tech to work on, if you have good people's company, it works out. &lt;/p&gt;

&lt;p&gt;If you have a good tech or a project with an impeccable architecture, you should be happy, as you have loads to dig in to and learn. Learning is everything. A good tech guy or a dev is one who is always learning. (I am assuming that :) )&lt;/p&gt;

&lt;p&gt;Some are really lucky to get both.&lt;/p&gt;

&lt;p&gt;How does that work for you guys !?&lt;br&gt;
What are you looking for.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>career</category>
      <category>dev</category>
    </item>
  </channel>
</rss>
