<?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: Nuno Reis</title>
    <description>The latest articles on DEV Community by Nuno Reis (@no0law1).</description>
    <link>https://dev.to/no0law1</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%2F348080%2F93dd817d-4779-4d1e-94af-7e3e12f29a6a.jpg</url>
      <title>DEV Community: Nuno Reis</title>
      <link>https://dev.to/no0law1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/no0law1"/>
    <language>en</language>
    <item>
      <title>Propagate headers with .NET Core Web API</title>
      <dc:creator>Nuno Reis</dc:creator>
      <pubDate>Fri, 16 Oct 2020 21:29:52 +0000</pubDate>
      <link>https://dev.to/no0law1/propagate-headers-with-net-core-web-api-cpa</link>
      <guid>https://dev.to/no0law1/propagate-headers-with-net-core-web-api-cpa</guid>
      <description>&lt;p&gt;Welcome. Today we are going to learn how to propagate any header you receive onto another HTTP service using .NET Core Web API.&lt;/p&gt;




&lt;p&gt;Let’s say I have a pipeline which consists of three services, like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F77ikglpv5s1ap2crehrx.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%2F77ikglpv5s1ap2crehrx.png" alt="Alt Text" width="521" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And I want my service at the end of the line to receive the headers that were sent from the client that requested information from the service at the beginning of the line.&lt;/p&gt;

&lt;p&gt;How is this useful in real life? Well, imagine your service down the line needs the accept-language sent from the client to access some information that is language-specific. Propagating the headers is one way to achieve that the service down the line will receive that header.&lt;/p&gt;

&lt;p&gt;Let’s see how we can achieve this with a simple solution that requires no workarounds.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1: Create your Web API&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can create it using the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet new webapi &lt;span class="nt"&gt;--name&lt;/span&gt; HeaderPropagationDemo &lt;span class="nt"&gt;--language&lt;/span&gt; &lt;span class="s2"&gt;"C#"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Install HeaderPropagation package
&lt;/h3&gt;

&lt;p&gt;If you’re already using .NET Core 3.1, add this package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package Microsoft.AspNetCore.HeaderPropagation &lt;span class="nt"&gt;--version&lt;/span&gt; 3.1.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re using a lower version, add this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package HeaderPropagation &lt;span class="nt"&gt;--version&lt;/span&gt; 3.0.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Setup Dependency Injection
&lt;/h3&gt;

&lt;p&gt;Enable middleware on &lt;em&gt;Startup.Configure&lt;/em&gt; using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHeaderPropagation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add the service onto &lt;em&gt;Startup.ConfigureServices&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHeaderPropagation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;  
&lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="c1"&gt;// Add Default   &lt;/span&gt;
    &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User-Agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"HeaderPropagationDemo"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="c1"&gt;// Propagate if header exists  &lt;/span&gt;
    &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Accept-Language"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’ve only added two specific examples. One for &lt;code&gt;User-Agent&lt;/code&gt; where I can specifically define it so it can be added if there is no User-Agent present and the &lt;code&gt;Accept-Language&lt;/code&gt; header with no default value.&lt;/p&gt;

&lt;p&gt;This is pretty much all you need for a basic setup to propagate the headers you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Setup a Client (optional)
&lt;/h3&gt;

&lt;p&gt;If you are using &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1" rel="noopener noreferrer"&gt;HttpClientFactory&lt;/a&gt;, you need to add a delegating handler to every client, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DefaultClient"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHeaderPropagation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: See it actually working
&lt;/h3&gt;

&lt;p&gt;Let’s create a controller with an endpoint capable of making a request to one of the &lt;a href="https://httpbin.org/" rel="noopener noreferrer"&gt;httpbin.org&lt;/a&gt; GET method which in turn will send us the headers we propagated onto him.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ApiController&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[controller]"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;  
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PropagationController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;  
&lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IHttpClientFactory&lt;/span&gt; &lt;span class="n"&gt;_factory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;PropagationController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IHttpClientFactory&lt;/span&gt; &lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="n"&gt;_factory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;factory&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="n"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
    &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DefaultClient"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://httpbin.org/get"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAsStringAsync&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your API and make a request to this endpoint. You should receive a response with the headers. Try not passing any User-Agent and if you’ve followed everything correctly, you should be able to see the default value provided on the code.&lt;br&gt;&lt;br&gt;
Using the browser may be a little tricky to modify the headers, you can use an extension for Chrome for example, but I personally use &lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Wrap up
&lt;/h3&gt;

&lt;p&gt;That’s it. Hope this has helped you in any way.&lt;br&gt;&lt;br&gt;
Have a nice day!&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>api</category>
    </item>
    <item>
      <title>Generate Client SDK for .NET Core using Open Api</title>
      <dc:creator>Nuno Reis</dc:creator>
      <pubDate>Wed, 22 Jul 2020 17:18:50 +0000</pubDate>
      <link>https://dev.to/no0law1/generate-client-sdk-for-net-core-using-open-api-2dgh</link>
      <guid>https://dev.to/no0law1/generate-client-sdk-for-net-core-using-open-api-2dgh</guid>
      <description>&lt;p&gt;This article is intended to be a tutorial on how to generate a client sdk of an API using OpenAPI specification (a.k.a. Swagger) so you can focus more on implementing new software instead of maintaining useless one.&lt;/p&gt;




&lt;h3&gt;
  
  
  Pre Requisites
&lt;/h3&gt;

&lt;p&gt;Before we begin, we are going to need two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://dotnet.microsoft.com/download" rel="noopener noreferrer"&gt;dotnet&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;npm&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we have them we can start our journey.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create a Web Api&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/tools/" rel="noopener noreferrer"&gt;dotnet command line interface&lt;/a&gt; create a webapi with the command &lt;code&gt;dotnet new&lt;/code&gt;, just like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet new webapi --name Api --language "C#"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Generate Open API spec of our Web Api&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;webapi&lt;/code&gt; template already has a resource called &lt;em&gt;WeatherForecast&lt;/em&gt; which we can use to generate our client sdk, so our next logical step will be to add the Swashbuckle required package to our project using &lt;code&gt;dotnet add package&lt;/code&gt;. &lt;em&gt;(The command must be executed on the same directory as where the csproj is located.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet add package Swashbuckle.AspNetCore.SwaggerGen --version 5.5.1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now that we have the necessary package, it’s time for some code.&lt;/p&gt;

&lt;p&gt;We will only need to add some lines on &lt;em&gt;Startup.cs&lt;/em&gt; file.&lt;br&gt;&lt;br&gt;
Go to &lt;strong&gt;ConfigureServices&lt;/strong&gt; method and add the &lt;em&gt;AddSwaggerGen&lt;/em&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddSwaggerGen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;  
&lt;span class="p"&gt;{&lt;/span&gt;  
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SwaggerDoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OpenApiInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"API"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;  
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method will register the swagger document generator which we will need to retrieve the json document afterwards.&lt;/p&gt;

&lt;p&gt;Now we need to install a tool in order to get the json file with the Open API spec of our API called &lt;a href="https://github.com/domaindrivendev/Swashbuckle.AspNetCore#swashbuckleaspnetcorecli" rel="noopener noreferrer"&gt;&lt;em&gt;Swashbuckle.AspNetCore.Cli&lt;/em&gt;&lt;/a&gt; using this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet tool install --global Swashbuckle.AspNetCore.Cli&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But before running this tool, we must generate a &lt;em&gt;dll&lt;/em&gt; of our project, so:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;dotnet restore Api/Api.csproj&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dotnet build -c Release Api/Api.csproj&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Afterwards, validate if our &lt;em&gt;dll&lt;/em&gt; was properly generated in &lt;code&gt;Api/bin/Release/netcoreapp3.1&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Now that we have a proper &lt;em&gt;dll&lt;/em&gt;, we can use the tool we installed previously by executing 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;swagger tofile --output swagger.json Api/bin/Release/netcoreapp3.1/Api.dll v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will generate the open api spec into a file named &lt;em&gt;swagger.json&lt;/em&gt; which we will then use it to generate our Client SDK.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Generate Client SDK for .NET Core&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the beginning I told you it was necessary to install npm. Now it’s time to use it. We are going to install a package from &lt;a href="https://openapi-generator.tech/" rel="noopener noreferrer"&gt;OpenAPI Generator&lt;/a&gt; that will help us generate our Client SDK.&lt;/p&gt;

&lt;p&gt;Install the Open Api Generator Command Line Interface globally by executing 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 @openapitools/openapi-generator-cli -g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally execute Open Api Generator CLI to generate our SDK with this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;openapi-generator generate -i swagger.json -g csharp-netcore -o Api.Client.Sdk --additional-properties packageName=Api.Client.Sdk&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command will create a directory called Api.Client.Sdk where the generated client sdk of our API with the specified package name is.&lt;/p&gt;




&lt;h3&gt;
  
  
  Wrap Up
&lt;/h3&gt;

&lt;p&gt;That is basically it. Now you can generate your API SDK without any code, you can even automate the SDK generation and pack it into your package manager.&lt;br&gt;&lt;br&gt;
If you need a different technology for your SDK, open api generator provides a lot more generators which are listed &lt;a href="https://openapi-generator.tech/docs/generators" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’ll leave some useful links below if you’d like to know more about some topics talked here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://swagger.io/specification/" rel="noopener noreferrer"&gt;OpenAPI Specification&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://openapi-generator.tech/" rel="noopener noreferrer"&gt;OpenAPI Generator&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ll also leave the code of this tiny tutorial which is present &lt;a href="https://github.com/no0law1/open-api-client-sdk-generator-tutorial" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>tutorial</category>
      <category>productivity</category>
      <category>openapi</category>
    </item>
    <item>
      <title>Building a React Native App w/ Expo</title>
      <dc:creator>Nuno Reis</dc:creator>
      <pubDate>Thu, 02 Jul 2020 11:14:39 +0000</pubDate>
      <link>https://dev.to/no0law1/building-a-react-native-app-w-expo-2bl5</link>
      <guid>https://dev.to/no0law1/building-a-react-native-app-w-expo-2bl5</guid>
      <description>&lt;p&gt;In this article I will try to guide you on how to start a react native application from scratch using expo and consequently build it into an apk.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzt3sfa0ge98nh53vhhw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdzt3sfa0ge98nh53vhhw.jpeg" width="468" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For quite some time I wanted to learn Swift and enter the world of Mobile Software Development, but the opportunity never arose.&lt;/p&gt;

&lt;p&gt;Around 2019, I came across an opportunity to develop a mobile application which had a simple requisite. The application had to work both on Android and iOS. Since me and my team did not have knowledge whatsoever about Swift and little time to deliver, we decided to use something we already knew and that would work both on Android and iOS.&lt;/p&gt;

&lt;p&gt;This was React Native. Since I had already worked with React, this was the best option for us.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is React Native?&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;React Native is a JavaScript framework for writing real, native rendering mobile applications for iOS and Android. It’s based on React, Facebook’s JavaScript library for building user interfaces, but instead of targeting the browser, it targets mobile platforms.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We had no experience using React Native, however there is a really neat tool that really helped us developing our application. This tool is called Expo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Expo?&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Expo is a framework and a platform for universal React applications. It is a set of tools and services built around React Native and native platforms that help you develop, build, deploy, and quickly iterate on iOS, Android, and web apps from the same JavaScript/TypeScript codebase.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I was very satisfied with this and would absolutely try it again to develop mobile applications. But right now, I will help you develop your own. 😄&lt;/p&gt;

&lt;p&gt;Enough talking. Let’s get down to business.&lt;/p&gt;




&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;What’s required for us to get started?&lt;/p&gt;

&lt;p&gt;React Native’s language is JavaScript so we are going to need a package manager for JavaScript which is &lt;em&gt;npm&lt;/em&gt;. You can go &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;here&lt;/a&gt; and install Node and NPM.&lt;/p&gt;

&lt;p&gt;After installing you can open a terminal and validate 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 --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next will be to install, using &lt;em&gt;npm&lt;/em&gt;, expo command line interface using the following commands:&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 --global expo-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step by Step
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create your app using Expo&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;expo init --template blank
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After executing this command, you’ll need to provide the name you want to give your app. This name will be used to create the folder where your project will be. Within this new folder there will be a bunch of stuff already configured which are necessary for you to run your app.&lt;br&gt;&lt;br&gt;
I’ll leave below an image of what should have been created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ux6i6wkzeb1lupvfw2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ux6i6wkzeb1lupvfw2t.png" width="252" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretty standard stuff here, but what’s most important and what’s required for your app to run here are the &lt;em&gt;assets&lt;/em&gt; folder, the &lt;em&gt;node_modules&lt;/em&gt; folder, the &lt;em&gt;App.js&lt;/em&gt;, &lt;em&gt;app.json&lt;/em&gt;, &lt;em&gt;babel.config.js&lt;/em&gt; and the &lt;em&gt;package.json.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you want to deep dive on any of these files, I’ll leave some links for you to have fun. 😄&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  For &lt;em&gt;babel.config.js&lt;/em&gt; related stuff, go &lt;a href="https://babeljs.io/docs/en/config-files" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  For &lt;em&gt;package.json&lt;/em&gt; related stuff, go &lt;a href="https://docs.npmjs.com/files/package.json" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  For &lt;em&gt;app.json&lt;/em&gt; related stuff, go &lt;a href="https://docs.expo.io/versions/latest/workflow/configuration/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Run the App&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;p&gt;After running that command, Expo Command Line Interface will start Metro Bundler, which is an HTTP server that compiles the JavaScript code of your app using &lt;a href="https://babeljs.io/" rel="noopener noreferrer"&gt;Babel&lt;/a&gt; and serves it to the Expo app.&lt;br&gt;&lt;br&gt;
It also pops up Expo Developer Tools, a graphical interface for Expo CLI.&lt;/p&gt;

&lt;p&gt;The Expo Developer Tool should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo716vaz9a0ppd9idm7en.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo716vaz9a0ppd9idm7en.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Expo does have some nice features. Did you know you can install your app on your phone with a tiny app that Expo developed and reading that QR code? You can also install your app into your Android Virtual Device or plug in your Phone with a USB cable, but the QR code option was quite welcoming for me. 😄&lt;/p&gt;

&lt;p&gt;Since I am using the QR code, I had to install this &lt;a href="https://play.google.com/store/apps/details?id=host.exp.exponent&amp;amp;hl=en" rel="noopener noreferrer"&gt;App&lt;/a&gt; on my Android.&lt;/p&gt;

&lt;p&gt;After installing the app, the only thing you need to worry about is putting the connection to Tunnel (&lt;em&gt;if expo shows a warning saying&lt;/em&gt; &lt;strong&gt;&lt;em&gt;Tunnel URL not found, falled back to LAN URL&lt;/em&gt;&lt;/strong&gt;&lt;em&gt;, please stop and start the app again&lt;/em&gt;) and make sure the Phone and the Computer are on the same internet, otherwise it won’t work. 😞&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flg6zymn6wkt1l0u79hal.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flg6zymn6wkt1l0u79hal.png" width="321" height="691"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should see something like this on your phone. From this step forward, you can start and explore your React abilities and make your app pretty and useful.&lt;/p&gt;

&lt;p&gt;If you want to use some basic components from React Native, you can see their documentation &lt;a href="https://facebook.github.io/react-native/docs/components-and-apis#basic-components" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more complex stuff, like device permissions and so on, you can see this &lt;a href="https://docs.expo.io/versions/latest/sdk/permissions/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; from Expo.&lt;/p&gt;
&lt;h4&gt;
  
  
  Step 3: Build your Android Package with Expo
&lt;/h4&gt;

&lt;p&gt;The next logical step after you’ve developed your App, would be to build it and distribute it. Since I haven’t distributed the App we were developing to Apple Store, or to Google Play Store, I can only guide you on how to build your &lt;strong&gt;Android Package&lt;/strong&gt; (&lt;strong&gt;APK&lt;/strong&gt;) using Expo.&lt;/p&gt;

&lt;p&gt;In order for us to be able to generate an APK using Expo we need to create an account. You can create one &lt;a href="https://expo.io/signup" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, we will need to change some settings on the &lt;code&gt;app.json&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Since we are creating an Android Package, the only thing we need to worry is to define the Android package name like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="nl"&gt;"android"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;  
    &lt;/span&gt;&lt;span class="nl"&gt;"package"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"com.tutorial.reactnative"&lt;/span&gt;&lt;span class="w"&gt;  
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;  
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to deep dive on this matter, you can follow this &lt;a href="https://docs.expo.io/versions/latest/workflow/configuration/#android" rel="noopener noreferrer"&gt;link&lt;/a&gt;. It is the documentation for every supported field on the &lt;code&gt;app.json&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Start your app using &lt;code&gt;npm run start&lt;/code&gt; and then open a new terminal on the same directory and execute the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expo build:android -t apk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are not logged in yet, it will ask you to log in or to create a new user, since we’ve done this previously, we can choose to log in.&lt;/p&gt;

&lt;p&gt;Afterwards, it will ask you for a Keystore, don’t worry about it and let them handle it.&lt;/p&gt;

&lt;p&gt;This will trigger a build of your app and after that build is concluded, it will be sent to the expo servers to be transformed into an APK.&lt;/p&gt;

&lt;p&gt;This may take some time as Android builds are the most popular within Expo servers. If you want an estimate on how much time it will take, you can follow this &lt;a href="https://expo.io/turtle-status" rel="noopener noreferrer"&gt;link&lt;/a&gt;. It shows how many Android builds are on Expo servers waiting for processing.&lt;/p&gt;

&lt;p&gt;You do not need to wait in the terminal for the build to complete. Generally, you will receive an info stating that the terminal command timed out. No worries. Just check the build status on the expo website.&lt;/p&gt;

&lt;p&gt;After some time, your APK will appear on your Expo Dashboard and it will be ready for download! 🎉&lt;/p&gt;




&lt;h3&gt;
  
  
  Wrap up
&lt;/h3&gt;

&lt;p&gt;Now that we have a functioning react native application and you know how to build your own APK for delivery, you can continue and develop that app which we know will be the next big thing.&lt;/p&gt;




&lt;h3&gt;
  
  
  Useful Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/no0law1/react_native_tutorial" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.expo.io/versions/latest/" rel="noopener noreferrer"&gt;Expo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Hangfire w/ Mongo using Docker</title>
      <dc:creator>Nuno Reis</dc:creator>
      <pubDate>Thu, 02 Jul 2020 08:33:13 +0000</pubDate>
      <link>https://dev.to/no0law1/hangfire-w-mongo-using-docker-25f1</link>
      <guid>https://dev.to/no0law1/hangfire-w-mongo-using-docker-25f1</guid>
      <description>&lt;p&gt;This article is a basic tutorial on how to setup Hangfire using a dotnet core application.&lt;/p&gt;

&lt;p&gt;Before I start rambling, what is Hangfire and what does it do?&lt;/p&gt;

&lt;p&gt;Hangfire is an easy way to perform background processing in .NET and .NET Core applications. No Windows Service or separate process are required. It is also backed by persistent storage. It’s great for long running tasks where you have multiple instances of an application and you need or want to start or stop those tasks.&lt;/p&gt;




&lt;h3&gt;
  
  
  Let’s Start
&lt;/h3&gt;

&lt;p&gt;First we need to choose a database that is compatible with Hangfire. I chose MongoDB because it’s free, but SQL Server is also compatible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create a docker-compose file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This docker compose will be responsible to create our mongo database. I’ve also added mongo-express to visualize our mongo db on the browser and a beautiful little script runner to create our user with access to the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;mongo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:3.4.14&lt;/span&gt;
  &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MONGO_INITDB_ROOT_USERNAME=admin&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MONGO_INITDB_ROOT_PASSWORD=admin&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;27017:27017&lt;/span&gt;
  &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
 &lt;span class="na"&gt;mongo-express&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo-express&lt;/span&gt;
  &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo_express&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;8081:8081&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;ME_CONFIG_MONGODB_ADMINUSERNAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;admin&lt;/span&gt;
   &lt;span class="na"&gt;ME_CONFIG_MONGODB_ADMINPASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;admin&lt;/span&gt;
  &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
 &lt;span class="na"&gt;mongo-scripts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo-scripts&lt;/span&gt;
  &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo_scripts&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SERVER=mongo&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PORT=27017&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DATABASE=HANGFIRE_TUTORIAL&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;USERNAME=myuser&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PASSWORD=pwd&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
   &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dockerfile&lt;/span&gt;
  &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mongo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are new to docker compose files, you can read about it &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create a Dockerfile&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will need to create the Dockerfile in the same space of the docker compose file with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; mongo:3.4.14&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; SERVER&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; PORT&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; DATABASE&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; USERNAME&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; PASSWORD&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; mongoscripts&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'\r'&lt;/span&gt; &amp;lt;run-mongoscripts.sh &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;run-mongoscripts.sh.tmp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; run-mongoscripts.sh.tmp run-mongoscripts.sh
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; sh run-mongoscripts.sh ${SERVER} ${PORT} ${DATABASE} ${USERNAME} ${PASSWORD}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This Dockerfile is responsible for copying our bash script and execute it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create a bash script&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The bash script name should be equivalent to the one given in the Dockerfile. The name I gave it was &lt;em&gt;run-mongoscripts.sh&lt;/em&gt; and it should be in the same space as the docker compose file.&lt;/p&gt;

&lt;p&gt;The bash script should have the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
main&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
 &lt;span class="nv"&gt;server&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nv"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nv"&gt;database&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nv"&gt;workTime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nv"&gt;totalTimes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;50&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nv"&gt;numberOfChecks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
 &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$numberOfChecks&lt;/span&gt; &lt;span class="nt"&gt;-le&lt;/span&gt; &lt;span class="nv"&gt;$totalTimes&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
   &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;timeout&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$workTime&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"echo &amp;gt; /dev/tcp/&lt;/span&gt;&lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$port&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;do
   &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$port&lt;/span&gt;&lt;span class="s2"&gt; is DOWN after &lt;/span&gt;&lt;span class="nv"&gt;$numberOfChecks&lt;/span&gt;&lt;span class="s2"&gt; check"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="nv"&gt;$workTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;numberOfChecks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="nv"&gt;$numberOfChecks&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;timeout&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$workTime&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"echo &amp;gt; /dev/tcp/&lt;/span&gt;&lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$port&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$port&lt;/span&gt;&lt;span class="s2"&gt; is DOWN after all checks"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$server&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$port&lt;/span&gt;&lt;span class="s2"&gt; is UP"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;fi

 &lt;/span&gt;mongo &lt;span class="nt"&gt;--host&lt;/span&gt; &lt;span class="nv"&gt;$server&lt;/span&gt; &lt;span class="nt"&gt;--port&lt;/span&gt; &lt;span class="nv"&gt;$port&lt;/span&gt; admin &lt;span class="nt"&gt;-u&lt;/span&gt; admin &lt;span class="nt"&gt;-p&lt;/span&gt; admin &lt;span class="nt"&gt;--eval&lt;/span&gt; &lt;span class="s2"&gt;"db.getSiblingDB('&lt;/span&gt;&lt;span class="nv"&gt;$database&lt;/span&gt;&lt;span class="s2"&gt;').createUser({user:'&lt;/span&gt;&lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="s2"&gt;',pwd:'&lt;/span&gt;&lt;span class="nv"&gt;$password&lt;/span&gt;&lt;span class="s2"&gt;',roles:[{role:'readWrite',db:'&lt;/span&gt;&lt;span class="nv"&gt;$database&lt;/span&gt;&lt;span class="s2"&gt;'}]})"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
main &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script is responsible for creating a user capable of reading and writing in a mongo database of our choosing. It contains a loop for it to wait until the mongodb container is up.&lt;/p&gt;

&lt;p&gt;Ok, the worst is over. 😅&lt;/p&gt;

&lt;p&gt;Now we can run our docker compose file using this command where the docker compose file is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose up -d --build&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Go to your browser and you will be able to access &lt;em&gt;mongo-express&lt;/em&gt; on &lt;a href="http://localhost:8081/" rel="noopener noreferrer"&gt;http://localhost:8081/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmk9jhrt5bf5xjv2425rc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmk9jhrt5bf5xjv2425rc.png" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We finally have our setup complete. 🎉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Create a new ASP.NET Core Web API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open Visual Studio and create a new project using the following templates:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsg2azbgbc8k0vgo6zqic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsg2azbgbc8k0vgo6zqic.png" width="508" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vh16a8sn17jdj942e7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vh16a8sn17jdj942e7f.png" width="666" height="84"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Add Hangfire to our project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After our ASP.NET Core Web API has been created, let’s proceed to the installation of Hangfire into our project. Head out to our &lt;em&gt;.csproj&lt;/em&gt; and add the following:&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;ItemGroup&amp;gt;
  &amp;lt;PackageReference Include="Hangfire" Version="1.7.9" /&amp;gt;
  &amp;lt;PackageReference Include="HangFire.Mongo" Version="0.6.6" /&amp;gt;
&amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are all the packages we are going to need so now we can add our connection string to Mongo DB to feed onto Hangfire.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Add MongoDB connection string&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mongo’s template connection string should look like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mongodb://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;host&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;database&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s add it into &lt;code&gt;appsettings.json&lt;/code&gt; using our settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ConnectionStrings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"HangfireConnection"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"mongodb://myuser:pwd@localhost:27017/HANGFIRE_TUTORIAL"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;After that we can start to add our dependencies to the &lt;strong&gt;Startup.cs&lt;/strong&gt; file located at the root of the project.&lt;/p&gt;

&lt;p&gt;You will have two methods. &lt;em&gt;ConfigureServices&lt;/em&gt; and &lt;em&gt;Configure. ConfigureServices&lt;/em&gt; is used to add services to the container for them to be available for dependency injection. &lt;em&gt;Configure&lt;/em&gt; is where we set up the middlewares that handle every HTTP request.&lt;/p&gt;

&lt;p&gt;So, in &lt;em&gt;ConfigureServices&lt;/em&gt; we will add our dependency to Hangfire like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MongoStorageOptions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;MigrationOptions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MongoMigrationOptions&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;BackupStrategy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MongoBackupStrategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Strategy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MongoMigrationStrategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Drop&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHangfire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseMongoStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConnectionString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HangfireConnection"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in &lt;em&gt;Configure&lt;/em&gt; we will add this so that we can open the Hangfire Dashboard and to be able to schedule jobs and stop them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHangfireDashboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHangfireServer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome. Now we can just run our application and go to &lt;code&gt;/hangfire&lt;/code&gt; and we will be able to see this beautiful dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20tbvjmabkw1p6osk1or.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20tbvjmabkw1p6osk1or.png" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We now have our Hangfire configured and ready to go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8: Add a Job to Hangfire&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our next step will be to add a job to execute every day at 8AM to tell us good morning.&lt;/p&gt;

&lt;p&gt;In our &lt;strong&gt;Startup.cs&lt;/strong&gt; file, on the &lt;em&gt;Configure&lt;/em&gt; method, we will add this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;RecurringJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddOrUpdate&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HangfireJobs&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
   &lt;span class="s"&gt;"GoodMorning"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GoodMorning&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
   &lt;span class="n"&gt;Cron&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Daily&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, what does this do? This tiny method will add a recurring job to Hangfire that will execute the method &lt;code&gt;GoodMorning&lt;/code&gt; declared on the class &lt;code&gt;HangfireJobs&lt;/code&gt; every day at 8AM identified in the last argument.&lt;/p&gt;

&lt;p&gt;Next Step will be to create the class &lt;em&gt;HangfireJobs&lt;/em&gt; and its method, &lt;em&gt;GoodMorning&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HangfireJobs&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GoodMorning&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Good Morning!"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, we can run our app and go to &lt;code&gt;/hangfire/recurring&lt;/code&gt; and see this job waiting for it to be ran. It should look something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy79p307gxcz75sr27v39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy79p307gxcz75sr27v39.png" width="800" height="224"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Wrap up
&lt;/h3&gt;

&lt;p&gt;This is it. Now you have a functioning application using Hangfire with Mongo DB using Docker where you can add Jobs to run whenever you want and how many times you need.&lt;/p&gt;

&lt;p&gt;If you want to follow up on something more, here is some links that may be helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/no0law1/hangfire_tutorial" rel="noopener noreferrer"&gt;My Github Repo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.docker.com/compose/" rel="noopener noreferrer"&gt;Docker Compose Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.hangfire.io/" rel="noopener noreferrer"&gt;Hangfire Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/sergeyzwezdin/Hangfire.Mongo" rel="noopener noreferrer"&gt;Hangfire.Mongo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>csharp</category>
      <category>mongodb</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
