<?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: Mark Davies</title>
    <description>The latest articles on Forem by Mark Davies (@joro550).</description>
    <link>https://forem.com/joro550</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%2F154679%2F1c24515e-71db-4cac-8c7d-0cbb40879011.png</url>
      <title>Forem: Mark Davies</title>
      <link>https://forem.com/joro550</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/joro550"/>
    <language>en</language>
    <item>
      <title>I'll make my own dev container with nvim and blackjack</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Sat, 09 Mar 2024 19:20:05 +0000</pubDate>
      <link>https://forem.com/joro550/ill-make-my-own-dev-container-with-nvim-and-blackjack-2pjl</link>
      <guid>https://forem.com/joro550/ill-make-my-own-dev-container-with-nvim-and-blackjack-2pjl</guid>
      <description>&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://giphy.com/gifs/cYhhUmbtbneb6/fullscreen" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--SiY_gjKP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExYmR0cWk1aXE2MmR1MzUxancybjVlZjJtNmZhNWM5ZmJycTk2M3M0YSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/cYhhUmbtbneb6/giphy.gif" height="309" class="m-0" width="425"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://giphy.com/gifs/cYhhUmbtbneb6/fullscreen" rel="noopener noreferrer" class="c-link"&gt;
          Blackjack Hookers GIF - Find &amp;amp; Share on GIPHY
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Discover &amp;amp; share this Blackjack GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--bzD6Ar5---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://giphy.com/static/img/favicon.png" width="16" height="16"&gt;
        giphy.com
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Over the last year I have been watching a lot of The primeagen on youtube and he has been saying something that really resonating with me that you should learn your editor and use something that you personally reallly enjoy. I have to admit at the time (being a dotnet developer) I used a lot of JetBrains Rider, but I was what most people would say a "shortcut demon" and one day I saw prime doing stuff with Vim and it blew my mind, the fact that he could do almost any thing he wanted without using the mouse was stunning - I wanted that skill.&lt;/p&gt;

&lt;p&gt;I come from a computer games background - back in the early 2000's I loved command and conquer and played the hell out of Starcraft 2, and I loved a good hotkey. I thought I had reached the peak of my hotkey usage in software development, but I was &lt;em&gt;so&lt;/em&gt; wrong. Little did I know that you could spend 90% of your day without even thinking about the mouse. And now I have a crazy stupid idea that I want to share - and I have no idea what this is going to be like. &lt;/p&gt;

&lt;p&gt;But first of all &lt;/p&gt;

&lt;h1&gt;
  
  
  What is vim
&lt;/h1&gt;

&lt;p&gt;vim is a terminal based text editor - it has three modes - insert, visual and command mode, when you first "enter" vim you might be confused as none of the keys actually type letters, this is because you are in visual mode - this is the mode you use to navigate the file, it is actually called normal mode because this is the mode it expects you'll be in most of the time and can do very quick edits. insert mode it where you actually edit and add text and visual mode is a selection mode.&lt;/p&gt;

&lt;p&gt;vim is installed on almost every version of unix, I am but a simple windows user so I had to actually install it. I will add the caveat that I actually use neovim just because I prefer the lua interface and only used vim when I was starting out.&lt;/p&gt;

&lt;h1&gt;
  
  
   How did you get started
&lt;/h1&gt;

&lt;p&gt;One of the things that primeagen (and yes sorry seeing as he is the driving force behind this I will be mentioning him a bit) mentioned is that before you go "full vim" you should learn the keybindings as those alone will make you more productive. and here I have to admit I had my first slip up - I have never learned how to type on a computer keyboard properly, meaning that at the most I was using two or three fingers to actually type anything when it came to computers. &lt;/p&gt;

&lt;p&gt;I had seen the ways in which people used vim so I actually dedicated myself to learn how to type properly on a keybaord for months - if you ever find yourself in a similar situation here are my suggestions:&lt;/p&gt;

&lt;p&gt;typing.com - good for leaning finger placement and starting out&lt;br&gt;
keybr.com - amazing for learning how to type properly and picking up some speed&lt;br&gt;
&lt;a href="https://monkeytype.com/"&gt;https://monkeytype.com/&lt;/a&gt; - amazing when you are feeling more comfortable with the touch typing and feel you can do it without guardrails&lt;/p&gt;

&lt;p&gt;It took months to get back to where I was speed wise when typing and I have to admit it was agonizing - I would be typign messages out to people at half even quarter of the speed I was used to but I stuck at it. If I was under a lot of time pressure only then would I revert back to using my way of typing, jsut to crack out what I need to crack out and then I immediately went back to typing at 20 words per minute (probably not that bad but you get my meaning).&lt;/p&gt;

&lt;p&gt;I have been working at it for around 9 months now and I touch type at twice the speed i used to be able to type - I would highly sugges this for any programmer out there that might be putting it off like I did.&lt;/p&gt;

&lt;p&gt;With that under way I moved to vim key motions in Rider - here is where the struggles really began because it tooks another couple of months to get used to moving around with my keyboard, I gave up at this more than the typing because I just felt it was horrible. But I persisted. &lt;/p&gt;
&lt;h1&gt;
  
  
  Downloading neovim
&lt;/h1&gt;

&lt;p&gt;The first time I downloaded nvim I was dissapointed because I couldn't even do anything with code I had no highlighting and I couldn't go to definition on anything.&lt;/p&gt;

&lt;p&gt;I heard of some ways that you can configure nvim I initially went with NVChad: &lt;a href="https://nvchad.com/"&gt;https://nvchad.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was more like it! I had syntax highlighting and could move around my code, again it took MONTHS to learn the hotkeys I eventually prefered lunar vim &lt;a href="https://www.lunarvim.org/"&gt;https://www.lunarvim.org/&lt;/a&gt; but these days use lazyvim &lt;a href="https://www.lazyvim.org/"&gt;https://www.lazyvim.org/&lt;/a&gt; as the hotkeys click a little easier and I find lazy a little "closer to the metal" than the other two - I think if I was to start again I would go for kickstart - &lt;a href="https://github.com/nvim-lua/kickstart.nvim"&gt;https://github.com/nvim-lua/kickstart.nvim&lt;/a&gt; which is just one file that is heavily commented with what is going on, the less the distro is doing the better I feel now that I am more comfortable with neovim.&lt;/p&gt;
&lt;h1&gt;
  
  
   Embracing the terminal
&lt;/h1&gt;

&lt;p&gt;The terminal is a super power - I have been developing for almost 10 years and I think this has been the best shift I have made - I have such better understanding of my tools and how to use them than I did at the start of this journey. I truely believe that ALL developers should go through this journey it is very much worth while - running terminal commands to start, build,test your program, learn how to grep how to curl, I swear the terminal is absolute magical.&lt;/p&gt;

&lt;p&gt;I said that I had windows I will say one of the big shifts that I did that was a little crazy (or felt it at the time) was that I was slowly wanting to try a linux distro, I turned to WSL as a toe in the water.&lt;/p&gt;

&lt;p&gt;I will say I had a rocky relationship with linux I installed it on some old computers when I was younger and the amount of terminal usage put me off. and the amount of commands or having to just copy and paste from the internet to get things running.&lt;/p&gt;

&lt;p&gt;I WAS SO WRONG &lt;/p&gt;

&lt;p&gt;Once you learn some simple commands a whole new world in opened to you it felt amazing. I was looking up just ways I could use the terminal more I bumped into tmux - which yes now I use it is amazing.&lt;/p&gt;
&lt;h1&gt;
  
  
  Dev Containers
&lt;/h1&gt;

&lt;p&gt;This came as one of those quirky ideas that occurred to me now that I am more comfortable with linux - what if you could encapsulate your dev environment into a docker container that you could clone and run - everything would be there and you could seperate one project from another. Wouldn't you know it docker were thinking something very similar - the only thing wrong with their thinking was that they seem to be centering it around vs code 🥲 &lt;/p&gt;

&lt;p&gt;This is where I have to say it - I hate vscode&lt;/p&gt;

&lt;p&gt;not because it's owned by microsoft or that it's slow and eats all my ram (even though those are contributing factors) but I genuinley think that as a text editor it sucks. The hotkeys are horrible and I could never find a workflow that stuck with me - when using vscode I felt like I was dragging my feet through wet mud.&lt;/p&gt;

&lt;p&gt;seeing as I am loving the new neovim workflow I was thinking to myself that you could have a docker container that downloaded and installed neovim and git and boom your dev environment - what else do you need.&lt;/p&gt;

&lt;p&gt;This is what I am trying out and I think I will try and update in a month to say either this was the worst idea ever or that actually this is legit. I'll let you know, look out for the github updates here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/joro550"&gt;
        joro550
      &lt;/a&gt; / &lt;a href="https://github.com/joro550/docker-dev"&gt;
        docker-dev
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      some images to dev with 
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>docker</category>
      <category>vim</category>
    </item>
    <item>
      <title>In Memory Request buckets</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Tue, 22 Nov 2022 10:30:22 +0000</pubDate>
      <link>https://forem.com/joro550/in-memory-request-buckets-131g</link>
      <guid>https://forem.com/joro550/in-memory-request-buckets-131g</guid>
      <description>&lt;p&gt;The other day I wrote a blog post about my new dev tools page:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/joro550" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PLQFrtj_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--6DrX81EK--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/154679/1c24515e-71db-4cac-8c7d-0cbb40879011.png" alt="joro550"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/joro550/some-dev-tools-1mje" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Some Dev Tools&lt;/h2&gt;
      &lt;h3&gt;Mark Davies ・ Nov 18 ・ 2 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#showdev&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;And I was saying that I had a bunch of ideas - this was one of the first thing I wanted to create was a request bucket, basically it would create an endpoint that you could plug into a webhook page and any request that comes into the endpoint would be printed out:&lt;/p&gt;

&lt;p&gt;Create a bucket:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WwJMVvEi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4klsgiqrquc1s65gc7zv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WwJMVvEi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4klsgiqrquc1s65gc7zv.png" alt="Creating a bucket via dev tools" width="764" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I have an address where I can post any data I want to:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rZU6siSK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ctqzmz58g3x21yz8hzit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rZU6siSK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ctqzmz58g3x21yz8hzit.png" alt="Bucket created screen" width="765" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll test it with a post request:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2xPeO5Jv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ex31ihentc1nre81ly0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2xPeO5Jv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ex31ihentc1nre81ly0p.png" alt="Sending a post request via insomnia" width="880" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I will have information about the request on the page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rkxoNSVm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bknhqt6x0aq1hsjz3r31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rkxoNSVm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bknhqt6x0aq1hsjz3r31.png" alt="Table displaying request information" width="880" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right now this is all an "in memory" endpoint but I'm hoping to make it a little more persistent, right now I'm thinking that maybe I can hold onto endpoints/requests for an hour (after the bucket was created) - maybe in the future I can create a "Pro" feature that allows people to create permanent endpoints, but let's not think about that right now 😅&lt;/p&gt;

</description>
      <category>programming</category>
      <category>showdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Some Dev Tools</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Fri, 18 Nov 2022 08:25:37 +0000</pubDate>
      <link>https://forem.com/joro550/some-dev-tools-1mje</link>
      <guid>https://forem.com/joro550/some-dev-tools-1mje</guid>
      <description>&lt;p&gt;As part of my dev journey there are a couple of sites that I use to do various things such as generate guids, generate text etc. But I thought recently how nice it would be to have all that information in one place, all those tools in one place. I have started down that journey.&lt;/p&gt;

&lt;p&gt;I eventually want this to be a "one stop shop" for all things dev. Where you can get code snippets, look something up, or just get some random data to test something your working on.&lt;/p&gt;

&lt;p&gt;Right now I feel the website is a little simple, but I promised myself to start sharing it once I got the first couple of things done, and now that I have I would like you to join me on my journey.&lt;/p&gt;

&lt;p&gt;Here is a list of things currently supported on the site:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Base64 Encode/Decode&lt;/li&gt;
&lt;li&gt;Guid Generation&lt;/li&gt;
&lt;li&gt;Md5/Sha1/Sha256/Sha512 Hash generation&lt;/li&gt;
&lt;li&gt;CSV Generation&lt;/li&gt;
&lt;li&gt;Lorem ipsum generation&lt;/li&gt;
&lt;li&gt;Url encode/decode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is a list (currently in my head of what I would like to get done next) &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regex validation&lt;/li&gt;
&lt;li&gt;CSV to Markdown&lt;/li&gt;
&lt;li&gt;Markdown to csv&lt;/li&gt;
&lt;li&gt;Json object creator &lt;/li&gt;
&lt;li&gt;Request buckets&lt;/li&gt;
&lt;li&gt;Code snippets&lt;/li&gt;
&lt;li&gt;Mobile support (I expect most devs to visit this from laptop or desktop so it's not that high right now)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bunch of things that I want to get done, but obviously don't want to burn myself out too quickly here. I promised myself that as soon as the first couple of things were working that I would start to promote the website so here I go:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sometools.dev/"&gt;some-tools.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is an open source website, so if you want to request features or tell me about a bug, be my guest, I look forward to when people are actually using it and giving me feedback&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/joro550"&gt;
        joro550
      &lt;/a&gt; / &lt;a href="https://github.com/joro550/some-dev-tools"&gt;
        some-dev-tools
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Devtools
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
some-dev-tools&lt;/h1&gt;
&lt;p&gt;Devtools&lt;/p&gt;
&lt;p&gt;npx tailwindcss -i ./wwwroot/css/input.css -o ./wwwroot/css/output.css --watch&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/joro550/some-dev-tools"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Hope you all enjoy!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>showdev</category>
    </item>
    <item>
      <title>What happens when we don't refactor</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Mon, 27 Jun 2022 15:36:43 +0000</pubDate>
      <link>https://forem.com/joro550/what-happens-when-we-dont-refactor-5d74</link>
      <guid>https://forem.com/joro550/what-happens-when-we-dont-refactor-5d74</guid>
      <description>&lt;p&gt;I've just come across what I think is the most hilariously bad code I've ever seen, and the best part is - it's only 6 lines long with braces, here we go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private readonly IMemoryCache _cache;

public object Modify(string code, bool Flag)
{
    object result;
    if (_cache.TryGetValue(code.ToLower(), out result))
    {
        return true;
    }

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

&lt;/div&gt;



&lt;p&gt;Now the language I work in from day to day is c# so there may be things here that you may not be aware of, but let's break each thing that (I think) is wrong with this snippet and then - let's fix it!&lt;/p&gt;

&lt;h1&gt;
  
  
  Return Type
&lt;/h1&gt;

&lt;p&gt;Why exactly are we returning &lt;code&gt;object&lt;/code&gt;? We know that this is going to return a bool, how do we know that? Well either we return true if this code is in the cache there or we return the &lt;code&gt;Flag&lt;/code&gt; whatever that is, but the &lt;code&gt;Flag&lt;/code&gt; is a bool. &lt;/p&gt;

&lt;h1&gt;
  
  
  The Method name
&lt;/h1&gt;

&lt;p&gt;We try and make our methods as brief but as descriptive as possible &lt;code&gt;Modify&lt;/code&gt; is brief I'll give it that but if we look inside the method we can see that nothing in there is being modified (now the code that calls this function modifies a property on another class) so we can say that this method name is not descriptive of the logic inside the method.&lt;/p&gt;

&lt;p&gt;so now we have to ask ourselves what is this function doing? Well it is checking some sort of cache for a code, if that code exists in the cache then it returns true, if not it returns the value of the flag. so maybe something like &lt;code&gt;CheckCacheForCode&lt;/code&gt; I don't know, all I do know is that is a much more descriptive name for this method than &lt;code&gt;Modify&lt;/code&gt; so let's stuck to it for now.&lt;/p&gt;

&lt;h1&gt;
  
  
  The parameters
&lt;/h1&gt;

&lt;p&gt;These are obviously not the names of the original parameters - I had to obfuscate them to talk about this code, because this is commercial software under a non OSS license. But I did try and capture the spirit of the names&lt;/p&gt;

&lt;p&gt;Quick suggestion here - pascal case for variable names, so &lt;code&gt;Flag&lt;/code&gt; becomes &lt;code&gt;flag&lt;/code&gt;, easy&lt;/p&gt;

&lt;h1&gt;
  
  
  The first line
&lt;/h1&gt;

&lt;p&gt;Now this line might not be as obvious for people who have not touched c# for a while but:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;First of all again with the &lt;code&gt;object&lt;/code&gt; - just make it a bool! But why are we defining this here? we could just do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_cache.TryGetValue(code.ToLower(), out var result)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but then again we're not even &lt;em&gt;using&lt;/em&gt; this variable so we can just use a discard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_cache.TryGetValue(code.ToLower(), out _)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again this one is a newer feature in c# but it's there so use it.&lt;/p&gt;

&lt;h1&gt;
  
  
  The if statement
&lt;/h1&gt;

&lt;p&gt;Now we are left with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (_cache.TryGetValue(code.ToLower(), out _))
{
    return true;
}

return Flag;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we can get rid of that if statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return _cache.TryGetValue(code.ToLower(), out _) || Flag;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  The result
&lt;/h1&gt;

&lt;p&gt;We went from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private readonly IMemoryCache _cache;

public object Modify(string code, bool Flag)
{
    object result;
    if (_cache.TryGetValue(code.ToLower(), out result))
    {
        return true;
    }

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

&lt;/div&gt;



&lt;p&gt;to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public bool CheckCacheForCode(string code, bool flag)
{
    return _cache.TryGetValue(code.ToLower(), out _) || flag;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just by thinking about our code just a little bit.&lt;/p&gt;

&lt;p&gt;Thanks all for reading &lt;/p&gt;

&lt;p&gt;j&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>dotnet</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Creating a command line tool</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Mon, 30 May 2022 15:26:18 +0000</pubDate>
      <link>https://forem.com/joro550/creating-a-command-line-tool-f01</link>
      <guid>https://forem.com/joro550/creating-a-command-line-tool-f01</guid>
      <description>&lt;p&gt;For a long time now I have been using various website to (for example) generate guids, and I thought to myself "why am I all ways searching the same thing when I can create a tool that generates guid&lt;/p&gt;

&lt;p&gt;Well I have finally done it :D&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/joro550"&gt;
        joro550
      &lt;/a&gt; / &lt;a href="https://github.com/joro550/DevConsoleTools"&gt;
        DevConsoleTools
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Dev tools for the command line
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Command line tools&lt;/h1&gt;
&lt;p&gt;I wanted to create a command line tool that could do some stuff that I was using different websites for daily&lt;/p&gt;
&lt;h1&gt;
How to use&lt;/h1&gt;
&lt;p&gt;Each release should have a &lt;code&gt;dev.exe&lt;/code&gt; file, you can download this file into a folder of your choice then set a environment varibable to go to that folder and just type &lt;code&gt;dev&lt;/code&gt; plus the command you want to run i.e. &lt;code&gt;dev gg&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here are a few that are currently supported:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Generate a random guid&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;generate guid [--hyphens true|false] [--uppercase true|false]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;gg [--hyphens true|false] [--uppercase true|false]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Generate a random email&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;generate email
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Generate a random number&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;generate number [--min 0] [--max 1]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Generate a lorem ipsum words&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;generate lorem [--word-count 1]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Base64 encode value&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;base64 encode &amp;lt;value&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Base64 decode value&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;base64 decode &amp;lt;value&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Upper case string&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;string to-upper &amp;lt;value&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Lower case string&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;string to-lower &amp;lt;value&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/joro550/DevConsoleTools"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;I have bundled a bunch of tools that I think would be useful together here is a little list of what it can do right now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate random guids&lt;/li&gt;
&lt;li&gt;Generate random email address&lt;/li&gt;
&lt;li&gt;Generate random number&lt;/li&gt;
&lt;li&gt;Generate lorem ipsum&lt;/li&gt;
&lt;li&gt;Base64 encode/decode strings&lt;/li&gt;
&lt;li&gt;Upper/lower case strings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also want to add&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MD5 hashing&lt;/li&gt;
&lt;li&gt;SHA1 hashing&lt;/li&gt;
&lt;li&gt;SHA256 hashing&lt;/li&gt;
&lt;li&gt;To do list?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll see how far we can push this &lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>AspNet Core and Xml</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Fri, 14 May 2021 13:56:56 +0000</pubDate>
      <link>https://forem.com/joro550/aspnet-core-and-xml-21im</link>
      <guid>https://forem.com/joro550/aspnet-core-and-xml-21im</guid>
      <description>&lt;p&gt;I have been recently working on a legacy api that accepts xml that uses namespaces, and I found the documentation in this space very sparse. So I'm hoping that if I ever have this problem again I can just search for this blog post and read what I wrote 😂&lt;/p&gt;

&lt;p&gt;So let's talk about xml:&lt;/p&gt;

&lt;h2&gt;
  
  
  Accepting xml in asp .net core
&lt;/h2&gt;

&lt;p&gt;First of all there is a small piece of code that we need to add to our startup to accept xml in our api:&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;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&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;AddControllers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddXmlSerializerFormatters&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&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 adds the default input and output formatters - which trust me we'll come back to!&lt;/p&gt;

&lt;p&gt;If we haev OpenApi connected to our application then we need to tell it that we accept xml:&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WeatherController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BaseController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Produces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"application/xml"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;Consumes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"application/xml"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IActionResult&lt;/span&gt; &lt;span class="nf"&gt;Test&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to add the correct tag to tell asp where your going to get your information from:&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="nf"&gt;Produces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"application/xml"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;Consumes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"application/xml"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IActionResult&lt;/span&gt; &lt;span class="nf"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;FromBody&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;RequsetModel&lt;/span&gt; &lt;span class="n"&gt;request&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;h2&gt;
  
  
  Namespaces
&lt;/h2&gt;

&lt;p&gt;When I was looking into this problem this was probably the &lt;em&gt;biggest&lt;/em&gt; headache, searching for how to actually add a namespace onto a xml is a nightmare, lots of false information laying around so...... Firstly we want to "declare" which namespaces we want to use, this can go in any class, I opted to create a namespace class:&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;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;XmlNamespaces&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;XmlNamespaceDeclarations&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;static&lt;/span&gt; &lt;span class="n"&gt;XmlSerializerNamespaces&lt;/span&gt; &lt;span class="n"&gt;Namespaces&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;XmlSerializerNamespaces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;XmlQualifiedName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"http://schemas.xmlsoap.org/soap/envelope/"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;XmlQualifiedName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"xsi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&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="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;Please ignore the fact that I'm adding soap envelope namespace, that's just an example 💀 I swear.&lt;/p&gt;

&lt;p&gt;Now that we have the namespaces declared we can now add them to our model:&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="nf"&gt;XmlRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Envelope"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Namespace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://schemas.xmlsoap.org/soap/envelope/"&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;RequsetModel&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;XmlElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Namespace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="nf"&gt;XmlElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Namespace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;BulkActionBody&lt;/span&gt; &lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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;now if we were to request the api we should be able to send a request that looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Envelope&lt;/span&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;xsi:Header&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;/xsi:Header/&amp;gt;
    &lt;span class="nt"&gt;&amp;lt;xsi:Body&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;/xsi:Body/&amp;gt;
&lt;span class="nt"&gt;&amp;lt;/Envelope&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Outputting xml
&lt;/h2&gt;

&lt;p&gt;You know how I said before that we would come back to the default serializers in aspnet core? Well here we go! Turns out declaring these namespaces only works for requests, if we were to return a model that had these attributes on it (with namespaces that were declared) it won't actually add those namespaces.&lt;/p&gt;

&lt;p&gt;First we need to override our serializer:&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;XmlOutputSerializer&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;XmlSerializerOutputFormatter&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;XmlSerializer&lt;/span&gt; &lt;span class="n"&gt;xmlSerializer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;XmlWriter&lt;/span&gt; &lt;span class="n"&gt;xmlWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;xmlSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xmlWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;XmlNamespaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Namespaces&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;This tells the serializer that we want to use the namespaces that we have declared when deserializing xml.&lt;/p&gt;

&lt;p&gt;Next we need to tell Asp net core that we want to use this serilizer and not the default one, back to our startup:&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;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&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;AddControllers&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="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OutputFormatters&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="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;XmlOutputSerializer&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddXmlSerializerFormatters&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;And kapow 🎉🎊🎊🎉 There's three weeks worth of googling in a 2 minute blog post &lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>asp</category>
      <category>aspnet</category>
    </item>
    <item>
      <title>Lies you should never tell yourself about your software</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Tue, 26 Jan 2021 16:22:48 +0000</pubDate>
      <link>https://forem.com/joro550/lies-you-should-never-tell-yourself-about-your-software-4akg</link>
      <guid>https://forem.com/joro550/lies-you-should-never-tell-yourself-about-your-software-4akg</guid>
      <description>&lt;h1&gt;
  
  
  Intro
&lt;/h1&gt;

&lt;p&gt;You know, during my career I've worked on some good sysytems and some bad systems - software development is a fast moving industry, things are changing constantly.... Or are they? &lt;/p&gt;

&lt;p&gt;Most of the things that are coming "into vogue" actually date back to the 1970's, people need to remember that above everything, the technology, the good ideas, the bad ideas, that good software - code that is seperated well and has clear boundaries - can transend time and technologies.&lt;/p&gt;

&lt;p&gt;With that in mind I wanted to talk about 5 things that developers tell themselves (and sometimes others) to defend and excuse their bad choices. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: you should always try your professional best to produce what is your best effort for every single line your write, no matter the curcumstances&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Other note&lt;/em&gt;: Yes, I have been part of the problem in every case I'm about to list, plese learn from my mistakes&lt;/p&gt;

&lt;h2&gt;
  
  
  5 - We need to (take a period of time to) refactor
&lt;/h2&gt;

&lt;p&gt;This is just plain wrong, I've ended up in this situation where you feel like you need to just take a quarter or hell a year to just reorganise your code. You've just come off of a big project or have just implmented your feature and are feeling good about yourself until the next request comes in and now the wind has been stripped from your sails because it is something that has been unaccounted for and now you have to &lt;em&gt;cough&lt;/em&gt; rewrite &lt;em&gt;cough&lt;/em&gt; &lt;em&gt;everything&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We need to remember that unexpected requests like this are going come in, and we need to react to them - we need to be honest with managers and product owners to say that what they have listed was out of scope and that if they want this feature that a lot of re-work  will need to be done &lt;em&gt;as part of adding the feature&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;We cannot as an industry take "time off" to refactor all of our code to keep our selves happy - it has to be natural, part of day to day living other wise we will fall behind or just be in a perpetual cycle of refactoring.&lt;/p&gt;

&lt;p&gt;Remember that Perfect is the enemy of good enough&lt;/p&gt;

&lt;h2&gt;
  
  
  4 - We need take a maintenance sprint
&lt;/h2&gt;

&lt;p&gt;This is an extension on the last one but moe focused on bugs (and maintenance). Bugs should be apart of your day to day life, if your application is erroring and it takes you 10 minutes to fix each time and the fix is only an hours worth of work then just do the work..... I don't know how many times I've been in a situation beeging and pleading with product owners to allow me to put fixes in for issues like this. &lt;/p&gt;

&lt;p&gt;Now I just do them, and when they ask I say "You're welcome" because that's a lot of time and responsibility I'm taking away from my day to day to focus on more important features.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 - This technology is not fit for purpose let's try....
&lt;/h2&gt;

&lt;p&gt;Before I start I should say: always do your research when beginning a project to try and find the most appropriate technology for your sue case.&lt;/p&gt;

&lt;p&gt;Now... This has kind of gone out of fashion because the whole "front end" SPA framework wars are finally dying down (a little) but you don't know how many times I've heard the words "This would be so much easier if we did this in X technology", that may be the case - you may be right - but it adds nothing. &lt;/p&gt;

&lt;p&gt;Remember that the technology that has been chosen has been chosen for a reason everything has advantages and disadvantages, the grass is always greener on the other side. When working on one technology for a long times (3-4 years) your bound to find that you're frustrated, just remember because another technology looks easier or better doesn't mean that you should hop onto the "hype" train as soon as the opportunity arises.&lt;/p&gt;

&lt;p&gt;For me this is a big one because developers have a huge need to want to keep up to date with the industry (or at least what they hear about the industry) so if they hear that the industry has changed from one thing to another then they immediately want to switch, use case be damned.&lt;/p&gt;

&lt;h2&gt;
  
  
  2 - This is only a prototype
&lt;/h2&gt;

&lt;p&gt;IT IS NEVER JUST A PROTOTYPE.&lt;/p&gt;

&lt;p&gt;That's all I have to say here 😂&lt;/p&gt;

&lt;h2&gt;
  
  
  1 - A re-write is coming (soon tm)
&lt;/h2&gt;

&lt;p&gt;No it's not.&lt;br&gt;
I don't care if your boss told you that it is. it's not.&lt;/p&gt;

&lt;p&gt;Even if it is, what are the chances of that code base being the nivana you want it to be? I MEAN REALLY? What if a new feature request comes in and now you have to rewrite the rewrite.&lt;/p&gt;

&lt;p&gt;This is the ultimate cop-out in my books "I don't have to implement this properly now because in a year we'll be replacing it anyway" attitude has lead to some pretty horrifying stories.&lt;/p&gt;

&lt;p&gt;I have not once ever seen a complete re-write of a system pan out, even when they were started developers were complaining about the new code within a year. It never happens. Do the best with what you all ready have.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using localstack to run an API</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Tue, 19 Jan 2021 10:21:45 +0000</pubDate>
      <link>https://forem.com/joro550/using-localstack-to-run-an-api-38he</link>
      <guid>https://forem.com/joro550/using-localstack-to-run-an-api-38he</guid>
      <description>&lt;h1&gt;
  
  
  What is localstack?
&lt;/h1&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/localstack"&gt;
        localstack
      &lt;/a&gt; / &lt;a href="https://github.com/localstack/localstack"&gt;
        localstack
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      💻  A fully functional local AWS cloud stack. Develop and test your cloud &amp;amp; Serverless apps offline!
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://travis-ci.org/localstack/localstack" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/6272bdccac9776009eefcdd787143f8200bd2e3df32bf4ea5a77a2c1b4e87278/68747470733a2f2f7472617669732d63692e6f72672f6c6f63616c737461636b2f6c6f63616c737461636b2e737667" alt="Build Status"&gt;&lt;/a&gt; &lt;a href="https://raw.githubusercontent.com/localstack/localstack/master/#backers"&gt;&lt;img src="https://camo.githubusercontent.com/27ab23dd97d9f06f5c391439cc1bc03331dffa74e6774b6e62696b82e12290a7/68747470733a2f2f6f70656e636f6c6c6563746976652e636f6d2f6c6f63616c737461636b2f6261636b6572732f62616467652e737667" alt="Backers on Open Collective"&gt;&lt;/a&gt; &lt;a href="https://raw.githubusercontent.com/localstack/localstack/master/#sponsors"&gt;&lt;img src="https://camo.githubusercontent.com/a53cb0755f48004ecd08e881475de549a1b1ca94cb562fe50dab49390ae5e290/68747470733a2f2f6f70656e636f6c6c6563746976652e636f6d2f6c6f63616c737461636b2f73706f6e736f72732f62616467652e737667" alt="Sponsors on Open Collective"&gt;&lt;/a&gt; &lt;a href="https://coveralls.io/github/localstack/localstack?branch=master" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/94ac5da65317fdcc1e4dfcda5a44d8c880c39238270e5f9d0e59a30974fef8c8/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f6c6f63616c737461636b2f6c6f63616c737461636b2f62616467652e7376673f6272616e63683d6d6173746572" alt="Coverage Status"&gt;&lt;/a&gt;
&lt;a href="https://gitter.im/localstack/Platform" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/915baae739e9d97e022a9870f85555c109c224766824fdbed391449105f82ef2/68747470733a2f2f696d672e736869656c64732e696f2f6769747465722f726f6f6d2f6c6f63616c737461636b2f506c6174666f726d2e737667" alt="Gitter"&gt;&lt;/a&gt;
&lt;a href="https://badge.fury.io/py/localstack" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/e0742bca9c59ab39aa6df1a7a80c4135a8735edf74c00363c99ed4b0480fef1b/68747470733a2f2f62616467652e667572792e696f2f70792f6c6f63616c737461636b2e737667" alt="PyPI Version"&gt;&lt;/a&gt;
&lt;a href="https://img.shields.io/pypi/l/localstack.svg" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/c81453ce0308eb5b28b0942bbf0b87ad308459f997d6da4b41bda707ce98571e/68747470733a2f2f696d672e736869656c64732e696f2f707970692f6c2f6c6f63616c737461636b2e737667" alt="PyPI License"&gt;&lt;/a&gt;
&lt;a href="https://codeclimate.com/github/localstack/localstack" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/f0346447fe069d5d50bb14a062eb95702dbaf3de858b00bb143ec8308a82cad8/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f6c6f63616c737461636b2f6c6f63616c737461636b2f6261646765732f6770612e737667" alt="Code Climate"&gt;&lt;/a&gt;
&lt;a href="https://twitter.com/_localstack" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/90bc908826728c0e4261acfff5619fd732c7be2b2a00624fce6363c9a3623c90/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f75726c2f687474702f736869656c64732e696f2e7376673f7374796c653d736f6369616c" alt="Twitter"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
LocalStack - A fully functional local AWS cloud stack&lt;/h1&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/localstack/localstack/raw/master/localstack/dashboard/web/img/localstack.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9gumtAy9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/localstack/localstack/raw/master/localstack/dashboard/web/img/localstack.png" alt="LocalStack"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;LocalStack&lt;/em&gt; provides an easy-to-use test/mocking framework for developing Cloud applications.&lt;/p&gt;
&lt;p&gt;Currently, the focus is primarily on supporting the AWS cloud stack.&lt;/p&gt;
&lt;h1&gt;
Announcements&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2020-12-28&lt;/strong&gt;: Check out the LocalStack Pro &lt;strong&gt;feature roadmap&lt;/strong&gt; here: &lt;a href="https://roadmap.localstack.cloud" rel="nofollow"&gt;https://roadmap.localstack.cloud&lt;/a&gt; - please help us prioritize our backlog by creating and upvoting feature requests. Looking forward to getting your feedback!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2020-09-15&lt;/strong&gt;: A major (breaking) change has been merged in PR #2905 - starting with releases after &lt;code&gt;v0.11.5&lt;/code&gt;, all services are now exposed via the edge service (port 4566) only! Please update your client configurations to use this new endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2019-10-09&lt;/strong&gt;: &lt;strong&gt;LocalStack Pro is out!&lt;/strong&gt; We're incredibly excited to announce the launch of LocalStack Pro - the enterprise version of LocalStack with additional APIs and advanced features. Check out the free trial at &lt;a href="https://localstack.cloud" rel="nofollow"&gt;https://localstack.cloud&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2018-01-10&lt;/strong&gt;: &lt;strong&gt;Help wanted!&lt;/strong&gt; Please &lt;a href="https://lambdastudy.typeform.com/to/kDUvvy?source=localstack-github" rel="nofollow"&gt;fill out this survey&lt;/a&gt; to support a research…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/localstack/localstack"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Let's start at the beginning - what is localstack exactly?&lt;/p&gt;

&lt;p&gt;Localstack an open source project that provides users with api's that fulfil the api's provided by the amazon web services, what does this mean? It means that you can have your own AWS running on your own - local - machine. &lt;/p&gt;

&lt;h1&gt;
  
  
  What are the advantages of this?
&lt;/h1&gt;

&lt;p&gt;There are a few reason why you might use localstack, let's quickly list them 😄&lt;/p&gt;

&lt;h2&gt;
  
  
  💰💰 Price 💰💰
&lt;/h2&gt;

&lt;p&gt;Sometimes spinning up test resources in AWS is expensive, especially if you are an individual (or maybe a corporation with a a lot of individual employees) spinning up a &lt;em&gt;for example&lt;/em&gt; dynamo db table for each developer to develop against would probably be more expensive than any service you want to create.&lt;/p&gt;

&lt;p&gt;The base version of localstack (that includes dynamo service) is free! So in a development environment you could have people communicate with that service.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏃‍♀️🏃‍♂️ Speed 🏃‍♀️🏃‍♂️
&lt;/h2&gt;

&lt;p&gt;Sometimes communicating with the cloud can be expensive not for the pocket but for wait times, this way all tests and code will be talking to a local version so &lt;em&gt;should be faster&lt;/em&gt; 😉.&lt;/p&gt;

&lt;p&gt;I don't know about you but I work at a company that has a devops team that like to be "in charge" of all of the infrastructure - which means that if I need a new S3 bukcet, dynamo database, or (insert other services here) I have to raise a ticket to create a piece of insfrastructure for testing, which can take time. With a local version of AWS I can spin up whatever I want, so whilst I wait for actual infrastructure I can continue with my work locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎤🎤 Testing 🎤🎤
&lt;/h2&gt;

&lt;p&gt;We can create tests against the local version, which means if we've broken anything we can run the same tests as we did for the previous version and if any fail we know that something has been broken whilst developing the new feature faster.&lt;/p&gt;

&lt;h1&gt;
  
  
  📕📖📑 How do we use it? 📕📖📑
&lt;/h1&gt;

&lt;p&gt;There are a few ways to "use" localstack, one of my favourite ways is to have a docker compose file (just to note I will not be talking about docker here) which look something 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;version: '3.4'

services:
  my.localstack:
    image: localstack/localstack:latest
    container_name: my-localstack
    ports:
      - "4566:4566"
    environment:
      - DEFAULT_REGION=eu-west-1
      - DATA_DIR=/tmp/localstack/data
    volumes:
      - "./setup-dev-env.sh:/docker-entrypoint-initaws.d/setup-dev-env.sh"
      - "./local/creds.json:/docker-entrypoint-initaws.d/creds.json"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Working with Localstack
&lt;/h1&gt;

&lt;p&gt;One of the things that I wanted to achieve with Localstack was to create a test infrastucture with a legacy application I've been working on. This particular API made use of the following AWS features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dynamo DB&lt;/li&gt;
&lt;li&gt;S3&lt;/li&gt;
&lt;li&gt;SQS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Attempting to make it as simple as possible for developers to clone the code from our private repository and hit build and have a localstack instance running on their machine in a configuration that would allow them to perform every branch of code in the API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Localstack
&lt;/h2&gt;

&lt;p&gt;We work with c# dotnet - our editor of choice is visual studio (my personal editor of choice is Rider), dotnet provides two event hooks to run anything that you may want to run before the build completes, this is where I added a call to powershell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File $(SolutionDir)setup-dev-env.ps1 $(SolutionDir)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Just as a note of where this is in Visual studio&lt;/em&gt; if you right click your project and click "properties" and go to build events, this particular script is entered intot he "pre-build event command line"&lt;/p&gt;

&lt;p&gt;This script checks to see if a particular docker container has been created - if not then it will call the &lt;code&gt;docker-compose&lt;/code&gt; file within the direction that is passed into the script (the solution directory):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;param($dir)

$isLocalStackRunning = docker container ps -f Name=localstack -q

if([string]::IsNullOrEmpty($isLocalStackRunning))
{
    docker-compose --file $dir\docker-compose.yml up -d
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;just as a reference:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Flag&lt;/th&gt;
&lt;th&gt;What this does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;-f&lt;/td&gt;
&lt;td&gt;Filters the results&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-q&lt;/td&gt;
&lt;td&gt;"Quiet" mode (just returns the docker container id)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;full reference for this command &lt;a href="https://docs.docker.com/engine/reference/commandline/ps/#examples"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The docker file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.4'

services:
  my.localstack:
    image: localstack/localstack:latest
    container_name: localstack
    ports:
      - "4566:4566"
    environment:
      - DEFAULT_REGION=eu-west-1
      - DATA_DIR=/tmp/localstack/data
    volumes:
      - "./setup-dev-env.sh:/docker-entrypoint-initaws.d/setup-dev-env.sh"
      - "./local/creds.json:/docker-entrypoint-initaws.d/creds.json"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Infrastructure
&lt;/h2&gt;

&lt;p&gt;You may have noticed this line in my &lt;code&gt;docker-compose&lt;/code&gt; file: "./setup-dev-env.sh:/docker-entrypoint-initaws.d/setup-dev-env.sh", this is essentially copying a file into directory inside the docker container, every &lt;code&gt;.sh&lt;/code&gt; file in this particular directory of localstack gets run when we run the &lt;code&gt;docker-compose up&lt;/code&gt; command, this is where I create all of the infrastructure that the API need to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;awslocal dynamodb create-table --table-name Table1 --attribute-definitions AttributeName=KC,AttributeType=S AttributeName=Domain,AttributeType=S --key-schema AttributeName=KC,KeyType=HASH  AttributeName=Domain,KeyType=RANGE --provisioned-throughput ReadCapacityUnits=1000,WriteCapacityUnits=1000
awslocal dynamodb create-table --table-name table2 --attribute-definitions AttributeName=KC,AttributeType=S AttributeName=Domain,AttributeType=S --key-schema AttributeName=KC,KeyType=HASH  AttributeName=Domain,KeyType=RANGE --provisioned-throughput ReadCapacityUnits=1000,WriteCapacityUnits=1000
awslocal sqs create-queue --queue-name queue1
awslocal sqs create-queue --queue-name queue2.fifo --attributes "FifoQueue=true"
awslocal sqs create-queue --queue-name queue2failover.fifo --attributes "FifoQueue=true"
awslocal kinesis create-stream --stream-name stream1 --shard-count 1
awslocal s3 mb s3://bucket --region eu-west-1
awslocal s3 cp /docker-entrypoint-initaws.d/creds.json s3://bucket/SVC/apiauth/creds.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; Because this files runs inside of the container keep in mind that it is a Linux exclusive container so this file will need the LF new line endings (yes this caught me out 😄)&lt;/p&gt;




&lt;p&gt;Now when I build my solution it checks to see if I have my container running if I don't it will create it with all of the things I need to exercise the API 😄&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>dotnet</category>
      <category>aws</category>
    </item>
    <item>
      <title>My Electron app - Organising my bookmarks</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Mon, 10 Aug 2020 10:16:34 +0000</pubDate>
      <link>https://forem.com/joro550/my-electron-app-organising-my-bookmarks-ha2</link>
      <guid>https://forem.com/joro550/my-electron-app-organising-my-bookmarks-ha2</guid>
      <description>&lt;p&gt;Over the last couple weeks I've been working on a simple electron app 😄 there has been some anger, some love, but mainly there has been code!&lt;/p&gt;

&lt;p&gt;Let me tell you about my journey&lt;/p&gt;

&lt;h1&gt;
  
  
  😧 JavaScript in 2020
&lt;/h1&gt;

&lt;p&gt;You know I'm not an old person (at least I don't want to be known as an old person - not yet, I guess I am nearing the big 3-0 👀. Any way I feel like anyone picking up JavaScript (or as the cool kids call it ECMAScript) won't remember the old days, or should I say the days &lt;em&gt;before&lt;/em&gt; node was a "thing". &lt;/p&gt;

&lt;p&gt;Don't get me wrong I am &lt;em&gt;NOT&lt;/em&gt; nostalgic for those days in anyway shape or form, the days where you downloaded a file, added it to your file system and then added a script tag into your html &lt;em&gt;shudder&lt;/em&gt;. that's how it was done in my day. &lt;/p&gt;

&lt;p&gt;These days we have node, npm - and let me tell you I was there for all of these innovations in the langauage but as a .Net developer I never really took much notice of them - I was mainly a backend developer.&lt;/p&gt;

&lt;p&gt;Couple years ago I got a job as a developer in a website company and we started work on this hideously complex frontend and it felt like we were coding in c++, having to include things in the right order.&lt;/p&gt;

&lt;p&gt;Then I looked into some of these technologies that I had been hearing passing coments &lt;em&gt;webpack&lt;/em&gt;, &lt;em&gt;TypeScript&lt;/em&gt;, &lt;em&gt;Node&lt;/em&gt;, and I quickly got overwhelmed and kind of wrote it off.&lt;/p&gt;

&lt;p&gt;Since then I have had a few projects where I've been playing around more nad more with Javacript. I wouldn't say I'm it's biggest fan but I get it - I get why people use it.&lt;/p&gt;

&lt;h1&gt;
  
  
  📜 The Project
&lt;/h1&gt;

&lt;p&gt;You know when I'm working on a project I'm constantly making notes, on confluence (which I personally hate but you know...) in vscode, but I am also constantly forgetting where I put these things. So I thought to myself - you know what I need, I need somewhere where I can have bookmarks, not just to websites but to files, but I want to organise things by project. You know what else would be sweet? a todo list that has repeatable tasks that keep popping onto your list to say "Hey this needs attention".&lt;/p&gt;

&lt;p&gt;I started looking around for something that would have my needs in mind, I mena just the bookmarking tool would be nice, and you know what I was faced with?&lt;/p&gt;

&lt;p&gt;This:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OgeMsWs7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gzjnucet56o10qk8n3ei.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OgeMsWs7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gzjnucet56o10qk8n3ei.png" alt="Picture displaying pricing plans for tools"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I don't blame companies for wanting to do this, obviosuly they need to make money, but all I wanted to do was to group my bookmarks into categories.... It couldn't be that hard right?&lt;/p&gt;

&lt;h1&gt;
  
  
  🔖 The pain
&lt;/h1&gt;

&lt;p&gt;So I decided then and there that I was going to start my own bookmarking tool with hookers and blackjack..... More like electron and React 😄, no real reason I chose these technolgies, I tried the .Net Blazor + Electron dev experience and it was .... lacking, with JavaScript I got immediate reloads and was a lot faster.&lt;/p&gt;

&lt;p&gt;So I started my own little thing, it was really slow going, the most of the pain was in the actual &lt;em&gt;setup&lt;/em&gt; of the project, every tutorial seemed to be out of date, documentation lacking I had to piece things together. I found my hardest hurdle was actually getting the thing to build and render, and when I finally did it felt like a massive relief.&lt;/p&gt;

&lt;h1&gt;
  
  
  Doin a little bit every day
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tDaESJi2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9j1b3fn6hdwoe5o80z1d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tDaESJi2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9j1b3fn6hdwoe5o80z1d.png" alt="Electron application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the application, it's really nothing fancy but it works, and it's a massive relief just to be here! Over the next couple weeks I'm going to be tidying things up and hopefully producing a build so that more people can consume it, oh yeah - it's open source 😄&lt;/p&gt;

&lt;p&gt;I'm happy to share more of my story if people are interested but yeah - I'm a little happy with my progress so far so here I am looking for other peoples approval and to prove to people that even after years of working as a dev that new things can be scary and hard but persistence wins out th day 😄&lt;/p&gt;

&lt;p&gt;Have a joyous day friends!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>electron</category>
      <category>learning</category>
    </item>
    <item>
      <title>Hackathon update #4 - Shoot into the wild blue</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Sat, 25 Apr 2020 18:24:21 +0000</pubDate>
      <link>https://forem.com/joro550/hackathon-update-4-shoot-into-the-wild-blue-44bf</link>
      <guid>https://forem.com/joro550/hackathon-update-4-shoot-into-the-wild-blue-44bf</guid>
      <description>&lt;p&gt;So this is it, my final update on the hackathon, it's kind of sad really but it's been pushed to a live server (azure to be specific) but I just wanted to let people have a sneak peak into how to get messages.&lt;/p&gt;

&lt;h1&gt;
  
  
  Subscribing to an event:
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E-xm-yaf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7yx38wuu49ksubrs681h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E-xm-yaf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7yx38wuu49ksubrs681h.png" alt="how-to-subscribe"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you are logged into the website these buttons will appear, these buttons allow you to subscribe to the updates on the event, once an update is published to the event a message will be sent to all of the subscribers of the event via twilios api.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; : Oh I should mention that these buttons only appear if you have a mobilenumber associated with your account.&lt;/p&gt;

&lt;p&gt;And well.. that's all I have to say. This was a blast to work on &lt;/p&gt;

&lt;p&gt;Checkout the website: &lt;a href="https://artemiswebserver.azurewebsites.net"&gt;https://artemiswebserver.azurewebsites.net&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vWogaON8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-28d89282e0daa1e2496205e2f218a44c755b0dd6536bbadf5ed5a44a7ca54716.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/joro550"&gt;
        joro550
      &lt;/a&gt; / &lt;a href="https://github.com/joro550/Artemis"&gt;
        Artemis
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Volunteer for events in your area
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;Artemis&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Artemis, in Greek religion, the goddess of wild animals, the hunt, and vegetation, and of chastity and childbirth;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Master branch: &lt;a rel="noopener noreferrer" href="https://github.com/joro550/Artemis/workflows/.NET%20Core/badge.svg"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GeomU485--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/joro550/Artemis/workflows/.NET%2520Core/badge.svg" alt=".NET Core"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Develop branch: &lt;a rel="noopener noreferrer" href="https://github.com/joro550/Artemis/workflows/.NET%20Core/badge.svg?branch=develop"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KI5Y0Mbg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/joro550/Artemis/workflows/.NET%2520Core/badge.svg%3Fbranch%3Ddevelop" alt=".NET Core"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;License: &lt;a rel="noopener noreferrer" href="https://camo.githubusercontent.com/6f72e2ef9c278966d0014c30c88c54e72083c6c3/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6a6f726f3535302f417274656d6973"&gt;&lt;img src="https://camo.githubusercontent.com/6f72e2ef9c278966d0014c30c88c54e72083c6c3/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6a6f726f3535302f417274656d6973" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
What is this?&lt;/h1&gt;
&lt;p&gt;This is a project that I am going to submit for the dev.to hackathon in association with twilio on 2020-04.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Quick intro&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Right now the world has it's mind on COVID-19 how can you help? But looking beyond and forward how do we help the homeless the starving, how do we fix global warming. This project is to help people who want to help with all of these causes and more, oganizations can create events that they are currently running i.e. Donate to fix a curch roof, and have a quick "call to action" that people can use to donate to help that event.&lt;/p&gt;
&lt;p&gt;Updates can be published to events to share how progress is coming along so that people are informed with…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/joro550/Artemis"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>twiliohackathon</category>
      <category>cloud</category>
      <category>production</category>
    </item>
    <item>
      <title>Hackathon update #3 - Building a pager in Blazor</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Thu, 23 Apr 2020 15:57:56 +0000</pubDate>
      <link>https://forem.com/joro550/hackathon-update-3-building-a-pager-in-blazor-448c</link>
      <guid>https://forem.com/joro550/hackathon-update-3-building-a-pager-in-blazor-448c</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;You know I feel as though there are a lot of subtle things that happen on websites that people don't appreciate, paging I feel is one of those things, over the years I've just imported whatever was convienient to a project, grabbed a jquery pager or datatables pager because for the most part they are a solved problem and I don't want to deal with it.&lt;/p&gt;

&lt;p&gt;But seeing as we've been given an oppertunity as part of the twilio hackathon to create whatever we wanted I wanted to visit what I think is a grossley underviewed component on the page, the pager! &lt;/p&gt;

&lt;p&gt;Writing it in c#/blazor (and bootstrap) I'm gonna walk through the code of how I created this wonderful component.&lt;/p&gt;

&lt;h1&gt;
  
  
  Parameters
&lt;/h1&gt;

&lt;p&gt;So first off, I believe we only need three pieces of information from tha page that is going to include this control&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Count of items&lt;/li&gt;
&lt;li&gt;How many per page&lt;/li&gt;
&lt;li&gt;A callback function&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Let's dive in!
&lt;/h1&gt;

&lt;p&gt;We want to create something that looks like this: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1e14asys8le6n6x6nc5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1e14asys8le6n6x6nc5g.png" alt="Pager"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, so I'm gonna be a little lazy here and say hey, I already did the work - so for all you people who have read this before or for people who just want something to copy and paste here ya go :D. I hope that some of you stick around to see the explanation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="container"&amp;gt;
    &amp;lt;nav&amp;gt;
        &amp;lt;ul class="pagination justify-content-center"&amp;gt;
            &amp;lt;li class="page-item @GetActiveClass(1)"&amp;gt;
                &amp;lt;a class="page-link" @onclick="@(async () =&amp;gt; await ChangePage(1))"&amp;gt;1&amp;lt;/a&amp;gt;
            &amp;lt;/li&amp;gt;

            @if (_numberOfPages &amp;gt; 1)
            {
                @if (_numberOfPages &amp;gt; 2)
                {
                    @if (_hasLeftSpill)
                    {
                        &amp;lt;li class="page-item"&amp;gt;
                            &amp;lt;a class="page-link" aria-label="Previous" @onclick="@(async () =&amp;gt; await ChangePage(_currentPage - (NumberOfNeighbours + 1)))"&amp;gt;
                                &amp;lt;span aria-hidden="true"&amp;gt;
                                    &amp;amp;laquo;
                                &amp;lt;/span&amp;gt;
                            &amp;lt;/a&amp;gt;
                        &amp;lt;/li&amp;gt;
                    }

                    @foreach (var pageId in _pages)
                    {
                        &amp;lt;li class="page-item @GetActiveClass(pageId)"&amp;gt;
                            &amp;lt;a class="page-link" @onclick="@(async () =&amp;gt; await ChangePage(pageId))"&amp;gt;@pageId&amp;lt;/a&amp;gt;
                        &amp;lt;/li&amp;gt;
                    }

                    @if (_hasRightSpill)
                    {
                        &amp;lt;li class="page-item"&amp;gt;
                            &amp;lt;a class="page-link" aria-label="Previous" @onclick="@(async () =&amp;gt; await ChangePage(_currentPage + (NumberOfNeighbours + 1)))"&amp;gt;
                                &amp;lt;span aria-hidden="true"&amp;gt;&amp;amp;raquo;&amp;lt;/span&amp;gt;
                            &amp;lt;/a&amp;gt;
                        &amp;lt;/li&amp;gt;
                    }
                }

                &amp;lt;li class="page-item @GetActiveClass(_numberOfPages)"&amp;gt;
                    &amp;lt;a class="page-link" @onclick="@(async () =&amp;gt; await ChangePage(_numberOfPages))"&amp;gt;@_numberOfPages&amp;lt;/a&amp;gt;
                &amp;lt;/li&amp;gt;
            }
        &amp;lt;/ul&amp;gt;
    &amp;lt;/nav&amp;gt;
&amp;lt;/div&amp;gt;

@code {
    private int _numberOfPages;
    private int _currentPage = 1;

    private bool _hasLeftSpill;
    private bool _hasRightSpill;
    private List&amp;lt;int&amp;gt; _pages = new List&amp;lt;int&amp;gt;();

    [Parameter]
    public double ItemsPerPage { get; set; }

    [Parameter]
    public double TotalItems { get; set; }

    [Parameter]
    public int NumberOfNeighbours { get; set; }

    [Parameter]
    public Func&amp;lt;int, Task&amp;gt; OnItemClick { get; set; }

    protected override void OnInitialized()
    {
        _numberOfPages = (int)Math.Ceiling(TotalItems / ItemsPerPage);
        ProcessPage();
    }

    private string GetActiveClass(int page) =&amp;gt; _currentPage == page ? "active" : string.Empty;

    private void ProcessPage()
    {
        var maxPageNumber = _numberOfPages - 1;
        var maxNeighbours = NumberOfNeighbours * 2;

        var startPage = Math.Max(2, _currentPage - NumberOfNeighbours);
        var neighbourBuffer = _currentPage &amp;gt; NumberOfNeighbours + 1 ? maxNeighbours + 1 : maxNeighbours;

        var endPage = startPage + neighbourBuffer;
        var count = endPage &amp;lt;= maxPageNumber ? neighbourBuffer : _numberOfPages - startPage;

        _pages = Enumerable.Range(startPage, count).ToList();

        _hasLeftSpill = startPage &amp;gt; 2;
        _hasRightSpill = _currentPage &amp;lt; maxPageNumber - NumberOfNeighbours;
    }

    private async Task ChangePage(int pageId)
    {
        pageId = Math.Max(1, pageId);
        pageId = Math.Min(pageId, _numberOfPages);

        await OnItemClick(pageId - 1);
        _currentPage = pageId;

        ProcessPage();
        StateHasChanged();
    }
}

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

&lt;/div&gt;


&lt;p&gt;Okay that's a lot of code! but let me take you through things and why this took a good number of hours to really nail down. Let me take you through the code, one function at a time and see where we end up, let's start at the beginning:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protected override void OnInitialized()
{
    _numberOfPages = (int)Math.Ceiling(TotalItems / ItemsPerPage);
    ProcessPage();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is a bit of an easy function to explain, we have a total number of items and a count of items we want to show per page, from these two pieces of information we can find out how many pages we actually need to display all of the data. We use the &lt;code&gt;System.Math&lt;/code&gt; library just to say, hey if this is a decimal then just round it up to the nearest number, for some reason this returns a decimal so we just convert it to an int.&lt;/p&gt;

&lt;p&gt;We then call a function called &lt;code&gt;ProcessPage&lt;/code&gt; which we'll get onto shortly.....&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private string GetActiveClass(int page) =&amp;gt; _currentPage == page ? "active" : string.Empty;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Another short simple function, this basically take a page id and if the current page is equal to the page id that has been passed in then bobs your uncle we pass back the string "active" which we use to show the user that that particular page is active.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private async Task ChangePage(int pageId)
{
    pageId = Math.Max(1, pageId);
    pageId = Math.Min(pageId, _numberOfPages);

    await OnItemClick(pageId - 1);
    _currentPage = pageId;

    ProcessPage();
    StateHasChanged();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;pageId = Math.Max(1, pageId);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This function takes a page id, we do a couple of safe guard functions just to be sure that we are operating in normal conditions, we can't possibly be &lt;em&gt;lower&lt;/em&gt; than page one so if the page id has somehow been changed to a value less than one then just set it to one.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pageId = Math.Min(pageId, _numberOfPages);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The page id can't possibly be larger than the total number of pages we need to display all of the informaiton presented so we just set it to the total number of pages if it has swayed above that number in any way.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;await OnItemClick(pageId - 1);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We call the callback function that the page gave to use to say "hey the user has clciked a page and here is it's id, we reduce it by one here because most (if not all) programming languages start indexing in 0, so this is just to make that a little easier.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_currentPage = pageId;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Set the current page id to the page id we have just specified.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;StateHasChanged();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Tell the framwork that something has changed and it most likely needs to re-render something on the page.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private void ProcessPage()
{
    var maxPageNumber = _numberOfPages - 1;
    var maxNeighbours = NumberOfNeighbours * 2;

    var startPage = Math.Max(2, _currentPage - NumberOfNeighbours);
    var neighbourBuffer = _currentPage &amp;gt; NumberOfNeighbours + 1 ? maxNeighbours + 1 : maxNeighbours;

    var endPage = startPage + neighbourBuffer;
    var count = endPage &amp;lt;= maxPageNumber ? neighbourBuffer : _numberOfPages - startPage;

    _pages = Enumerable.Range(startPage, count).ToList();

    _hasLeftSpill = startPage &amp;gt; 2;
    _hasRightSpill = _currentPage &amp;lt; maxPageNumber - NumberOfNeighbours;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Can I just say at this moment of time that I hate this funciton, it took me so long to refine it and it to actually make sense &lt;em&gt;and&lt;/em&gt; work, this is why people don't write their own pagers. Let's walk through the code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var maxPageNumber = _numberOfPages - 1;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ok so.... we print out the last page number manually so in a scenario where we have 10 pages this will be 9 so if you squint and look youll be able to see in your minds eye something like: &lt;code&gt;1 &amp;lt;&amp;lt; 4 | 5 &amp;gt;&amp;gt; 10&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var maxNeighbours = NumberOfNeighbours * 2;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We double the amount of neightbours here because we need the same amount of them for each side of our pager.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var startPage = Math.Max(2, _currentPage - NumberOfNeighbours);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Much the same concept here as before we actually print out the first page manually so the minimum number that the pager will start on will be 2, if the current page minus the number of neighbours is more than two then that is where we ned to _start the page count, so for example we were on page 5 of 10 with 2 neighbours we would start at 3.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var neighbourBuffer = _currentPage &amp;gt; NumberOfNeighbours + 1 ? maxNeighbours + 1 : maxNeighbours;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Sigh... this is where things start getting a little complex, so we need a neighbour buffer, so if the user is on a page that is one &lt;em&gt;more&lt;/em&gt; than the amount of neighbours then we have to add one to the amount of neighbours (this will be clear soon) for the actual &lt;em&gt;page&lt;/em&gt; that we are on so in a two neighbour scenario:&lt;/p&gt;

&lt;p&gt;Neighbours: 2,3 | Page we are on: 4 | Neighbours: 5,6&lt;/p&gt;

&lt;p&gt;I swear this will make sense when we get to actually creating the list of number, please stick with me....&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var endPage = startPage + neighbourBuffer;
var count = endPage &amp;lt;= maxPageNumber ? neighbourBuffer : _numberOfPages - startPage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;End page is basically where the pager will &lt;em&gt;stop&lt;/em&gt; counting so if it's going to go &lt;em&gt;above&lt;/em&gt; the number of pages that we have then we need to instead count the spaces between the page we are on and the maximum numer of pages.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_pages = Enumerable.Range(startPage, count).ToList();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Thank goodness, so, we are creating a list of number from the number stored in startPage and count are the amount of numbers we want to generate, so in this example: &lt;code&gt;Enumerable.Range(1, 10);&lt;/code&gt; we would get this list: &lt;code&gt;1,2,3,4,5,6,7,8,9,10&lt;/code&gt;, yes it is an inclusive call, so if we do &lt;code&gt;Enumerable.Range(2, 10);&lt;/code&gt; we will get &lt;code&gt;2,3,4,5,6,7,8,9,10,11&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I hope that makes sense.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_hasLeftSpill = startPage &amp;gt; 2;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If we are on a page that is more than two (where the pager starts) then we can say that there are pages to the left of us that we are not showing to the user.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_hasRightSpill = _currentPage &amp;lt; maxPageNumber - NumberOfNeighbours;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If we are not on a page that is the amount of neighbours away from the maximum number of pages then we have page number not being printed and have right spill.&lt;/p&gt;



&lt;p&gt;What I've learned is that pagers are way harder than I originally thought they were, hopefully you are able to go back to the razor syntax and point at things and make them make sense. Looking forward to getting this website on azure and into the hackathon, I have thought of ways to extend this website and it might actually become a little bit of a pet project of mine but we'll see. Thanks for the opportunity either way, this has been so much fun!&lt;/p&gt;




&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/joro550" rel="noopener noreferrer"&gt;
        joro550
      &lt;/a&gt; / &lt;a href="https://github.com/joro550/Artemis" rel="noopener noreferrer"&gt;
        Artemis
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Volunteer for events in your area
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;Artemis&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Artemis, in Greek religion, the goddess of wild animals, the hunt, and vegetation, and of chastity and childbirth;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Master branch: &lt;a rel="noopener noreferrer" href="https://github.com/joro550/Artemis/workflows/.NET%20Core/badge.svg"&gt;&lt;img src="https://github.com/joro550/Artemis/workflows/.NET%20Core/badge.svg" alt=".NET Core"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Develop branch: &lt;a rel="noopener noreferrer" href="https://github.com/joro550/Artemis/workflows/.NET%20Core/badge.svg?branch=develop"&gt;&lt;img src="https://github.com/joro550/Artemis/workflows/.NET%20Core/badge.svg?branch=develop" alt=".NET Core"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;License: &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/b36b2d9b7372b045118631f79b0c7488ac77b710a845622a7b1dbfe07cf17235/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6a6f726f3535302f417274656d6973"&gt;&lt;img src="https://camo.githubusercontent.com/b36b2d9b7372b045118631f79b0c7488ac77b710a845622a7b1dbfe07cf17235/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6a6f726f3535302f417274656d6973" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;What is this?&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;This is a project that I am going to submit for the dev.to hackathon in association with twilio on 2020-04.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quick intro&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Right now the world has it's mind on COVID-19 how can you help? But looking beyond and forward how do we help the homeless the starving, how do we fix global warming. This project is to help people who want to help with all of these causes and more, oganizations can create events that they are currently running i.e. Donate to fix a curch roof, and have a quick "call to action" that people can use to donate to help that event.&lt;/p&gt;

&lt;p&gt;Updates can be published to events to share how progress is coming along so that people are informed with…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/joro550/Artemis" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>csharp</category>
      <category>twiliohackathon</category>
      <category>blazor</category>
    </item>
    <item>
      <title>Hackathon update #2 - progress a plenty</title>
      <dc:creator>Mark Davies</dc:creator>
      <pubDate>Tue, 21 Apr 2020 07:00:35 +0000</pubDate>
      <link>https://forem.com/joro550/hackathon-update-2-progress-a-plenty-2378</link>
      <guid>https://forem.com/joro550/hackathon-update-2-progress-a-plenty-2378</guid>
      <description>&lt;p&gt;Okay so first things first, sorry these updates ave not been as plentiful as other people doing the challenge, but damn I hope you enjoy this progress update:&lt;/p&gt;

&lt;p&gt;I am pleased to announce that the application has &lt;em&gt;most&lt;/em&gt; of the functionality I want it to have so I'm just going to show off the screen shots and talk about some things.&lt;/p&gt;

&lt;p&gt;CRUD Organizations:&lt;/p&gt;

&lt;p&gt;View (not logged in)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dzol4DCY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b783i1sr9cv2c107yuf2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dzol4DCY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b783i1sr9cv2c107yuf2.png" alt="Organizations"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;View (logged in)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pVhSUloN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m4cu969a2mmwc66si637.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pVhSUloN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m4cu969a2mmwc66si637.png" alt="Organizations authed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Events:&lt;/p&gt;

&lt;p&gt;View (not logged in):&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8iFSd9wJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/s6sd0qp4w3jk44rhlo7e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8iFSd9wJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/s6sd0qp4w3jk44rhlo7e.png" alt="Events"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;View (logged in)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8WOyGPk9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d18hz67hp5800olnary1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8WOyGPk9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d18hz67hp5800olnary1.png" alt="Events authed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Event updates:&lt;/p&gt;

&lt;p&gt;View (not logged in):&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hdBZpf7V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r66t6jtja4ahrchyp3r0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hdBZpf7V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r66t6jtja4ahrchyp3r0.png" alt="Updates"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;View (logged in)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oqu2-u1E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3eypt0finu1jwyuexx6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oqu2-u1E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3eypt0finu1jwyuexx6p.png" alt="Updates authed"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Use case:
&lt;/h1&gt;

&lt;p&gt;You know whilst developing this a use case hit me that didn't before so i wanted to share with you a thought I had:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FJwDQNkC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g72mf4r5ttvisg68aq4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FJwDQNkC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/g72mf4r5ttvisg68aq4u.png" alt="Use case"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I know right, use my website to advertise my repository, madness, the updates could range from releases to up and coming features etc.&lt;/p&gt;
&lt;h1&gt;
  
  
  Does it work?
&lt;/h1&gt;

&lt;p&gt;Yes! I'm hoping to get this deployed &lt;em&gt;very&lt;/em&gt; soon (this week) just need to figure some things out and then boom, people will be able to have a play&lt;/p&gt;
&lt;h1&gt;
  
  
  Some concerns?
&lt;/h1&gt;

&lt;p&gt;Yeah...... I've been thinking a lot about the responsibility I have as a developer to allow people to post events and updates and what I've named "call to actions" (links to external sites) and I've been recently afraid of people abusing their power on the site, I've introduced an idea of an "isPublished" flag that is set to false. There is nowhere on the front end and no api to allow for publishing an organization, or event. The only way you can see this information is if you are logged in and are a part of that company.&lt;/p&gt;

&lt;p&gt;I need to think aboutthis one a little because obviously people could potentially post spam and link people to malicious websites, I was thinking some kind of url reputation check before the published flag is set.&lt;/p&gt;

&lt;p&gt;Don't know, need to think about this more I think but until then signing off&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qF2jUiUG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-6a5bca60a4ebf959a6df7f08217acd07ac2bc285164fae041eacb8a148b1bab9.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/joro550"&gt;
        joro550
      &lt;/a&gt; / &lt;a href="https://github.com/joro550/Artemis"&gt;
        Artemis
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Volunteer for events in your area
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;Artemis&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/joro550/Artemis"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>twiliohackathon</category>
    </item>
  </channel>
</rss>
