<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Muhammad Azeez</title><link>https://mazeez.dev/</link><description>Recent content on Muhammad Azeez</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sat, 15 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://mazeez.dev/index.xml" rel="self" type="application/rss+xml"/><item><title>Meta &amp; TikTok APIs: my castle is on someone else's land</title><link>https://mazeez.dev/posts/my-castle-is-on-someone-elses-land/</link><pubDate>Sat, 15 Aug 2026 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/my-castle-is-on-someone-elses-land/</guid><description>&lt;p&gt;From the first day I started &lt;a href="http://message24.net/"&gt;Message24&lt;/a&gt;, one of my biggest worries was what happens when the platforms I depend on change their rules? what happens when they decide to enter the game and compete with their partners?&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t have to wait long.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;October 2025.&lt;/strong&gt; Meta &lt;a href="https://dig.watch/updates/meta-changes-whatsapp-terms-to-block-third-party-ai-assistants"&gt;bans general-purpose AI assistants&lt;/a&gt; from the WhatsApp Business API. ChatGPT, Perplexity, anything where the AI itself is the product. New providers immediately, everyone already on the platform gets until January 15, 2026. Officially it was about server load and unintended use of the API. What those bots also happened to be was enormous volumes of traffic that fit none of Meta&amp;rsquo;s billing categories.&lt;/p&gt;</description></item><item><title>Agent Harness: How I keep my LLM honest</title><link>https://mazeez.dev/posts/agent-harness-hallucinations/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/agent-harness-hallucinations/</guid><description>&lt;p&gt;One of the biggest problems my customers kept hitting on &lt;a href="https://message24.net"&gt;Message24&lt;/a&gt; was hallucination. A shopper asks about a product that doesn&amp;rsquo;t exist; the LLM invents a price. Someone asks if an item is in stock; the LLM swears it is.&lt;/p&gt;
&lt;p&gt;Some LLMs find it really hard to say &amp;ldquo;I don&amp;rsquo;t know&amp;rdquo; (or in our case, escalate the conversation). LLMs are golden retrievers; they want to please, even if it costs them their honesty.&lt;/p&gt;</description></item><item><title>Claude Code from Your Phone</title><link>https://mazeez.dev/posts/claude-code-from-phone/</link><pubDate>Thu, 11 Dec 2025 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/claude-code-from-phone/</guid><description>&lt;p&gt;I use &lt;a href="https://docs.anthropic.com/en/docs/claude-code"&gt;Claude Code&lt;/a&gt; a lot. Sometimes I kick off a task on my machine, then want to check on it from my phone while I&amp;rsquo;m out (Why let the precious tokens expire, amirite?). Here&amp;rsquo;s my setup for accessing the same Claude Code session from anywhere.&lt;/p&gt;
&lt;h2 id="the-stack"&gt;The stack&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;tmux&lt;/strong&gt; - one session, attach from multiple devices at once&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;zsh&lt;/strong&gt; - nice autocomplete makes phone typing less painful&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tailscale&lt;/strong&gt; - VPN to access my machine from anywhere. Huge fan of Tailscale, I also use it for managing my personal servers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Termius&lt;/strong&gt; - SSH client on iOS/Android with a good keyboard&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tmux-config"&gt;tmux config&lt;/h2&gt;
&lt;p&gt;In &lt;code&gt;~/.tmux.conf&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Claude Code Dev Loop for Grug Brained Developer</title><link>https://mazeez.dev/posts/claude-code-dev-loop-grug/</link><pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/claude-code-dev-loop-grug/</guid><description>&lt;p&gt;&lt;a href="https://grugbrain.dev/"&gt;Grug&lt;/a&gt; brain small. Claude brain also small. This collection of thoughts on using AI coding agents gathered by grug brain developer.&lt;/p&gt;
&lt;h2 id="grug-think-of-one-thing"&gt;Grug think of one thing&lt;/h2&gt;
&lt;p&gt;One user story. One bug. One feature. Not ten thing. Grug brain hold one thing.&lt;/p&gt;
&lt;h2 id="grug-give-claude-context"&gt;Grug give Claude context&lt;/h2&gt;
&lt;p&gt;Open Plan Mode. Tell Claude what want. Reference relevant files. Paste official doc for libraries/services. Screenshot if help. Grug not make Claude guess.&lt;/p&gt;
&lt;h2 id="claude-ask-grug-answer"&gt;Claude ask. Grug answer.&lt;/h2&gt;
&lt;p&gt;Claude ask question about design. About edge case. About what mean.&lt;/p&gt;</description></item><item><title>Comparing PlanetScale PostgreSQL with Hetzner Local Postgres</title><link>https://mazeez.dev/posts/planetscale-vs-hetzner-postgres/</link><pubDate>Thu, 13 Nov 2025 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/planetscale-vs-hetzner-postgres/</guid><description>&lt;p&gt;PlanetScale’s new $5 single-node PostgreSQL tier (PS-5) promises the same observability/maintenance story you get from their Vitess-backed MySQL side. I wanted to see how it feels next to the very boring Postgres instance I already pay for: a Hetzner CPX11 (2 vCPU / 2 GB RAM for €3.85) running in their eu-central region (Nuremberg). This isn’t even LAN vs internet—it’s literally local disk vs a remote region—so the goal is to get a sanity check, not crown a winner.&lt;/p&gt;</description></item><item><title>A more useful `tree`</title><link>https://mazeez.dev/posts/a-more-useful-tree/</link><pubDate>Thu, 25 Sep 2025 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/a-more-useful-tree/</guid><description>&lt;p&gt;While Linux does have the &lt;code&gt;tree&lt;/code&gt; command, if you&amp;rsquo;re doing programming, you probably don&amp;rsquo;t want results in folders like &lt;code&gt;node_modules&lt;/code&gt;, &lt;code&gt;dist&lt;/code&gt;, etc&amp;hellip;, so here is a useful little alias I have in my &lt;code&gt;~/.bash_aliases&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style="color:#60a0b0;font-style:italic"&gt;# tree alias that excludes common directories&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 2&lt;/span&gt;&lt;span&gt;treen&lt;span style="color:#666"&gt;()&lt;/span&gt; &lt;span style="color:#666"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 3&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020"&gt;local&lt;/span&gt; &lt;span style="color:#bb60d5"&gt;ignore&lt;/span&gt;&lt;span style="color:#666"&gt;=&lt;/span&gt;&lt;span style="color:#4070a0"&gt;&amp;#39;node_modules|__pycache__|*.pyc|.git|.next|dist|build|
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 4&lt;/span&gt;&lt;span&gt;&lt;span style="color:#4070a0"&gt; coverage|.cache|.venv|venv|bin|obj|packages|.vs|*.user|*.suo&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 5&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020"&gt;local&lt;/span&gt; &lt;span style="color:#bb60d5"&gt;args&lt;/span&gt;&lt;span style="color:#666"&gt;=(&lt;/span&gt;-I &lt;span style="color:#4070a0"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#bb60d5"&gt;$ignore&lt;/span&gt;&lt;span style="color:#4070a0"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#666"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 6&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#666"&gt;[&lt;/span&gt; &lt;span style="color:#bb60d5"&gt;$#&lt;/span&gt; -gt &lt;span style="color:#40a070"&gt;0&lt;/span&gt; &lt;span style="color:#666"&gt;]&lt;/span&gt;; &lt;span style="color:#007020;font-weight:bold"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 7&lt;/span&gt;&lt;span&gt; &lt;span style="color:#bb60d5"&gt;args&lt;/span&gt;&lt;span style="color:#666"&gt;+=(&lt;/span&gt;-P &lt;span style="color:#4070a0"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#bb60d5"&gt;$1&lt;/span&gt;&lt;span style="color:#4070a0"&gt;&amp;#34;&lt;/span&gt; --prune&lt;span style="color:#666"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 8&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020"&gt;shift&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 9&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;10&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020"&gt;command&lt;/span&gt; tree &lt;span style="color:#4070a0"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#70a0d0"&gt;${&lt;/span&gt;&lt;span style="color:#bb60d5"&gt;args&lt;/span&gt;[@]&lt;span style="color:#70a0d0"&gt;}&lt;/span&gt;&lt;span style="color:#4070a0"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#4070a0"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#bb60d5"&gt;$@&lt;/span&gt;&lt;span style="color:#4070a0"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;11&lt;/span&gt;&lt;span&gt;&lt;span style="color:#666"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can use it like so: &lt;code&gt;treen **/*.ts&lt;/code&gt;&lt;/p&gt;</description></item><item><title>The Agent Builder's Reading List: What Actually Matters</title><link>https://mazeez.dev/posts/essential-llm-resources/</link><pubDate>Mon, 25 Aug 2025 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/essential-llm-resources/</guid><description>&lt;p&gt;Building AI agents? Here are the resources that actually taught me something useful, beyond the usual hype. If you&amp;rsquo;re tired of theoretical papers and want practical insights that work in the real world, start here.&lt;/p&gt;
&lt;h2 id="building-effective-agents-by-anthropic"&gt;Building effective agents by Anthropic&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What you&amp;rsquo;ll learn&lt;/strong&gt;: Stop overcomplicating things. The Anthropic team cuts through the noise and shows why the simplest agent often wins. They&amp;rsquo;re brutally honest about what doesn&amp;rsquo;t work - complex frameworks, over-engineered patterns, and agents that try to do everything. Instead, they advocate for boring solutions that actually ship: clear goals, simple tools, and relentless testing. The most valuable insight? Most &amp;ldquo;agent problems&amp;rdquo; are actually prompt engineering problems in disguise.&lt;/p&gt;</description></item><item><title>Migrating Extism Go SDK to Wazero</title><link>https://mazeez.dev/posts/migrating-extism-go-sdk-to-wazero/</link><pubDate>Fri, 29 Mar 2024 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/migrating-extism-go-sdk-to-wazero/</guid><description>&lt;p&gt;I gave a short talk at Wazero Party 2.0 about how we migrated the Extism Go SDK to use Wazero:&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/qI0kZxmxrUk?si=89Qikm2f-SDxAFeo&amp;amp;start=573" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;</description></item><item><title>Isomorphic .NET Support in Extism</title><link>https://mazeez.dev/posts/isomorphic-dotnet/</link><pubDate>Thu, 16 Nov 2023 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/isomorphic-dotnet/</guid><description>&lt;p&gt;In the early days of computing, software was pretty much locked into specific hardware setups. Then came operating systems, providing a layer of abstraction over the hardware. However, that still didn’t quite cut it. Businesses wanted to write their apps once and have them work on all sorts of platforms. This demand gave birth to higher-level languages that brought along their own runtimes, making it possible for software to run seamlessly on different operating systems.&lt;/p&gt;</description></item><item><title>Bringing WebAssembly to PostgreSQL using Extism</title><link>https://mazeez.dev/posts/pg-extism/</link><pubDate>Tue, 22 Aug 2023 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/pg-extism/</guid><description>&lt;p&gt;Database UDFs, or user-defined functions, are functions that are created by users to add custom functionality to a database. With UDFs, users can extend the capabilities of a database beyond its built-in functions and tailor it to their specific needs. UDFs are commonly used to perform complex calculations, manipulate data, or perform custom operations that are not natively supported by the database. They help to reduce the amount of code that needs to be written and improve performance by avoiding the need to move data outside of the database.&lt;/p&gt;</description></item><item><title>Generating C# bindings for native libraries by using ChatGPT</title><link>https://mazeez.dev/posts/chat-gpt-csharp-bindings/</link><pubDate>Sat, 17 Dec 2022 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/chat-gpt-csharp-bindings/</guid><description>&lt;p&gt;One of the most boring and tedious work in wrapping native libraries in C# is writing the DllImport functions.
Fortunatley, Large Language Models like ChatGPT has become powerful enough to be able to generate C# bindings from a C header file.
Or at the very least, they give you a good foundation that you can tweak and improve upon.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This post is part of the C# advent calendar 2022, for other articles in this collection see &lt;a href="https://csadvent.christmas/"&gt;C# Advent Calendar 2022&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Working remotely from Iraq as a Software Developer</title><link>https://mazeez.dev/posts/working-remotely-from-iraq/</link><pubDate>Sat, 08 Oct 2022 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/working-remotely-from-iraq/</guid><description>&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; I am writing about my personal experience here. Your mileage may vary.&lt;/p&gt;
&lt;p&gt;I have been working remotely for a European company since the beginning of the year. I have been through a lot of ups and downs since then, I want to document some of the insights I learned.&lt;/p&gt;
&lt;p&gt;Working remotely among the tech community is getting more and more common right now in Iraq. I have several friends who work for companies in Europe and other places. Most of the pre-requisites of working remotely are available in Iraq and Kurdistan, even though they are not as convenient as one might hope, so I think more software developers should consider it as an option.&lt;/p&gt;</description></item><item><title>Automatic periodic backups from PostgreSQL to S3 using Cron</title><link>https://mazeez.dev/posts/periodic-backups-potsgresql-s3-cron/</link><pubDate>Sat, 29 Jan 2022 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/periodic-backups-potsgresql-s3-cron/</guid><description>&lt;p&gt;If you&amp;rsquo;re managing your own databases you&amp;rsquo;ll need to make sure you database is backed up properly. A good option is to store your backups in an S3-compatible object storage.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;code&gt;s3cmd&lt;/code&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt install s3cmd
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;
&lt;li&gt;Configure it:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;s3cmd --configure
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It will ask you several questions, consult your S3 providers docs for more information.&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Write a bash script to create a postgresql dump and upload it to S3:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style="color:#bb60d5"&gt;DIR&lt;/span&gt;&lt;span style="color:#666"&gt;=&lt;/span&gt;&lt;span style="color:#007020;font-weight:bold"&gt;$(&lt;/span&gt;dirname &lt;span style="color:#4070a0"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#70a0d0"&gt;${&lt;/span&gt;&lt;span style="color:#bb60d5"&gt;BASH_SOURCE&lt;/span&gt;[0]&lt;span style="color:#70a0d0"&gt;}&lt;/span&gt;&lt;span style="color:#4070a0"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#007020;font-weight:bold"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 2&lt;/span&gt;&lt;span&gt;&lt;span style="color:#bb60d5"&gt;DB_NAME&lt;/span&gt;&lt;span style="color:#666"&gt;=&lt;/span&gt;my_db
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 3&lt;/span&gt;&lt;span&gt;&lt;span style="color:#bb60d5"&gt;DUMP_PATH&lt;/span&gt;&lt;span style="color:#666"&gt;=&lt;/span&gt;&lt;span style="color:#4070a0"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#bb60d5"&gt;$DIR&lt;/span&gt;&lt;span style="color:#4070a0"&gt;/&lt;/span&gt;&lt;span style="color:#bb60d5"&gt;$DB_NAME_&lt;/span&gt;&lt;span style="color:#007020;font-weight:bold"&gt;$(&lt;/span&gt;date +&lt;span style="color:#4070a0"&gt;&amp;#34;%Y-%m-%d@%H-%M&amp;#34;&lt;/span&gt;&lt;span style="color:#007020;font-weight:bold"&gt;)&lt;/span&gt;&lt;span style="color:#4070a0"&gt;.dump&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 4&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 5&lt;/span&gt;&lt;span&gt;&lt;span style="color:#60a0b0;font-style:italic"&gt;# DUMP the database&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 6&lt;/span&gt;&lt;span&gt;pg_dump --encoding utf8 --format c --compress &lt;span style="color:#40a070"&gt;9&lt;/span&gt; --file &lt;span style="color:#bb60d5"&gt;$DUMP_PATH&lt;/span&gt; &lt;span style="color:#bb60d5"&gt;$DB_NAME&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 7&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 8&lt;/span&gt;&lt;span&gt;&lt;span style="color:#bb60d5"&gt;DUMP_KEY&lt;/span&gt;&lt;span style="color:#666"&gt;=&lt;/span&gt;&lt;span style="color:#bb60d5"&gt;$DUMP_PATH&lt;/span&gt; | cut -c 3- &lt;span style="color:#60a0b0;font-style:italic"&gt;# Remove the ./ from the path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 9&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;10&lt;/span&gt;&lt;span&gt;&lt;span style="color:#60a0b0;font-style:italic"&gt;# Upload the dump file to S3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;11&lt;/span&gt;&lt;span&gt;s3cmd put &lt;span style="color:#bb60d5"&gt;$DUMP_PATH&lt;/span&gt; s3://&lt;span style="color:#bb60d5"&gt;$DB_NAME&lt;/span&gt;-db-backups/&lt;span style="color:#bb60d5"&gt;$DB_NAME&lt;/span&gt;/&lt;span style="color:#bb60d5"&gt;$DUMP_KEY&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;12&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;13&lt;/span&gt;&lt;span&gt;&lt;span style="color:#60a0b0;font-style:italic"&gt;# Remove the dump file from disk&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;14&lt;/span&gt;&lt;span&gt;rm &lt;span style="color:#bb60d5"&gt;$DUMP_PATH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For more information about taking PostgreSQL backups, checkout &lt;a href="https://mazeez.dev/posts/backup-and-restore-in-postgres"&gt;my previous post&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Supporting Bi-directional text in Html TextArea</title><link>https://mazeez.dev/posts/textarea-bidi/</link><pubDate>Thu, 13 Jan 2022 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/textarea-bidi/</guid><description>&lt;p&gt;A &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt; is an HTML element used to capture multiline user input. By default, it&amp;rsquo;s direction is either &lt;code&gt;right to left&lt;/code&gt; or &lt;code&gt;left to right&lt;/code&gt;. But what if we want each paragraph to have it&amp;rsquo;s own direction. This is very useful when the text is a mix of multiple languages. For example: Kurdish and English.&lt;/p&gt;
&lt;p&gt;I asked the quesiton on Twitter and my good friend &lt;a href="https://twitter.com/AkamFoad"&gt;Akam Foad&lt;/a&gt; came to the rescue:&lt;/p&gt;</description></item><item><title>Why public google user content images return 403</title><link>https://mazeez.dev/posts/why-google-oauth-profile-picture-returns-403/</link><pubDate>Sun, 09 Jan 2022 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/why-google-oauth-profile-picture-returns-403/</guid><description>&lt;p&gt;When using Google as your OIDC provider you can ask for the &lt;code&gt;picture&lt;/code&gt; claim which contains the user&amp;rsquo;s profile picture. It&amp;rsquo;s usually a url like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;https://lh3.googleusercontent.com/erjNVzk6nPUaUZuOTg2ObT12EzWWIokbuRdyuTkxRGR1nXQ5vhYk34twIt05FmaBNt7_yB3J
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I wanted to show the user profile in an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag, but Google was responding with 403. I searched around for an answer and I stumbled upon &lt;a href="https://stackoverflow.com/a/61042200/7003797"&gt;this stackoverflow answer&lt;/a&gt; which had the solution:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;img src=&amp;#34;https://lh3.googleusercontent.com/erjNVzk6nPUaUZuOTg2ObT12EzWWIokbuRdyuTkxRGR1nXQ5vhYk34twIt05FmaBNt7_yB3J&amp;#34; referrerpolicy=&amp;#34;no-referrer&amp;#34;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By setting the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-referrerpolicy"&gt;&lt;code&gt;referrerpolicy&lt;/code&gt;&lt;/a&gt; attribute to &lt;code&gt;no-referrer&lt;/code&gt;, the browser will not send the &lt;code&gt;referrer&lt;/code&gt; header and this seems to solve the issue.&lt;/p&gt;</description></item><item><title>Mocking Authentication and Authorization in ASP.NET Core Integration Tests</title><link>https://mazeez.dev/posts/auth-in-integration-tests/</link><pubDate>Sun, 12 Dec 2021 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/auth-in-integration-tests/</guid><description>&lt;p&gt;ASP.NET Core makes writing integration tests very easy and even fun. One aspect that might be a bit tough to figure out is authentication and authorization. We might want to run integration tests under different users and different roles.&lt;/p&gt;
&lt;p&gt;To get started, let&amp;rsquo;s assume we have an endpoint like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1&lt;/span&gt;&lt;span&gt;app.MapGet(&lt;span style="color:#4070a0"&gt;&amp;#34;hi&amp;#34;&lt;/span&gt;, (HttpContext httpContext) =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2&lt;/span&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3&lt;/span&gt;&lt;span&gt; &lt;span style="color:#902000"&gt;var&lt;/span&gt; userId = httpContext.User?.Claims?.FirstOrDefault(c =&amp;gt; c.Type == ClaimTypes.NameIdentifier)?.Value;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;return&lt;/span&gt; &lt;span style="color:#4070a0"&gt;$&amp;#34;Hello #{userId}&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;6&lt;/span&gt;&lt;span&gt;}).RequireAuthorization();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s a very simple endpoint. It gets the currently logged in user&amp;rsquo;s ID and says hello to them.&lt;/p&gt;</description></item><item><title>Testing Email Templates in ASP.NET Core</title><link>https://mazeez.dev/posts/email-snapshot-testing/</link><pubDate>Thu, 09 Dec 2021 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/email-snapshot-testing/</guid><description>&lt;blockquote&gt;
&lt;p&gt;This post is my annual contribution to the 2021 &lt;a href="https://www.csadvent.christmas/"&gt;C# Advent Calendar&lt;/a&gt;. Please check out all the great posts from our wonderful community!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Many systems require sending emails to notify users. And testing these notifications manually is a pain. So it&amp;rsquo;s one of the best use cases for integration testing. First, let&amp;rsquo;s create strongly typed model for our &lt;code&gt;Welcome&lt;/code&gt; email:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style="color:#007020;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#0e84b5;font-weight:bold"&gt;Welcome&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2&lt;/span&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;public&lt;/span&gt; &lt;span style="color:#902000"&gt;string&lt;/span&gt; FullName { &lt;span style="color:#007020;font-weight:bold"&gt;get&lt;/span&gt;; &lt;span style="color:#007020;font-weight:bold"&gt;set&lt;/span&gt;; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And we create a Razor template for the email in &lt;code&gt;EmailTemplates/Welcome.cshtml&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Securing ASP.NET Core APIs using Auth0</title><link>https://mazeez.dev/posts/asp-net-core-api-auth0/</link><pubDate>Sat, 09 Oct 2021 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/asp-net-core-api-auth0/</guid><description>&lt;h1 id="introduction"&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Modern applications are complex and take many different forms: Web apps, mobile apps, desktop apps, CLI apps, other APIs, Bots, IoT apps, and so on. In this blog post we discuss what it takes for your API to let any app communicate with it securely via the OAuth 2.0 and OpenID Connect protocols.&lt;/p&gt;
&lt;p&gt;By utilizing these standards, you can have a single Identity Provider protecting all of your apps. Allowing your users to sign into all of your apps using the same account, providing a seamless SSO (Single Sign On and Single Sign Out) experience. Another great benefit is you can easily allow 3rd party apps to connect to your APIs without compromising security.&lt;/p&gt;</description></item><item><title>Beware of HTTP Redirects!</title><link>https://mazeez.dev/posts/beware-of-http-redirects/</link><pubDate>Wed, 08 Sep 2021 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/beware-of-http-redirects/</guid><description>&lt;p&gt;Today, I spent an hour debugging why an http call was getting 401 as a response. I was setting the Authorization header properly and the token was valid. This was the call I was making:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1&lt;/span&gt;&lt;span&gt;&lt;span style="color:#902000"&gt;var&lt;/span&gt; httpClient = &lt;span style="color:#007020;font-weight:bold"&gt;new&lt;/span&gt; HttpClient();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2&lt;/span&gt;&lt;span&gt;httpClient.DefaultRequestHeaders.Authorization = &lt;span style="color:#007020;font-weight:bold"&gt;new&lt;/span&gt; AuthenticationHeaderValue(&lt;span style="color:#4070a0"&gt;&amp;#34;Bearer&amp;#34;&lt;/span&gt;, &lt;span style="color:#4070a0"&gt;&amp;#34;...&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4&lt;/span&gt;&lt;span&gt;&lt;span style="color:#902000"&gt;var&lt;/span&gt; response = &lt;span style="color:#007020;font-weight:bold"&gt;await&lt;/span&gt; httpClient.GetAsync(&lt;span style="color:#4070a0"&gt;&amp;#34;api/endpoint?parameter=true&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When I inspected the &lt;code&gt;Request&lt;/code&gt; property of the &lt;code&gt;HttpResponse&lt;/code&gt;, I saw that there was no &lt;code&gt;Authorization&lt;/code&gt; header. It was the first clue. For some reason, somewhere in the http pipeline, the header was not being forwarded properly.&lt;/p&gt;</description></item><item><title>Why my console app gets stuck</title><link>https://mazeez.dev/posts/quick-edit-mode/</link><pubDate>Mon, 09 Aug 2021 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/quick-edit-mode/</guid><description>&lt;p&gt;In my current project, we have a console app that runs in the background and sends data to a frontend application. The app works great but sometimes it stops working and we need to press a key for it to continue. It turned out it was because of Windows Console&amp;rsquo;s &lt;code&gt;Quick Mode&lt;/code&gt; feature. &lt;a href="https://stackoverflow.com/a/30517482"&gt;When a user clicks on the console window, it hangs the app execution to allow the user to select the text.&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>ASP.NET Core API Checklist</title><link>https://mazeez.dev/posts/asp-net-core-api-checklist/</link><pubDate>Sun, 13 Jun 2021 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/asp-net-core-api-checklist/</guid><description>&lt;p&gt;Building modern APIs require a lot of things to make them reliable, observable, and scalable. In no particular order, here are some of them that help you build better APIs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you have any other points in mind, you can send me &lt;a href="https://github.com/mhmd-azeez/website/blob/master/content/posts/asp-net-core-api-checklist.md"&gt;a PR here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="1-healthchecks"&gt;1. Healthchecks&lt;/h2&gt;
&lt;p&gt;Healthchecks are important in making sure that we know when anything happens to our APIs. We can setup dashboards to monitor them and setup alerting to let us know when one of the APIs is unhealthy. They are also important when deploying your apps to kubernetes. Kubernetes can monitor healthchecks of your APIs and automatically try to kill the unhealthy instances and create new instances to take their place.&lt;/p&gt;</description></item><item><title>String similarity search and fast LIKE operator using pg_trgm</title><link>https://mazeez.dev/posts/pg-trgm-similarity-search-and-fast-like/</link><pubDate>Wed, 12 May 2021 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/pg-trgm-similarity-search-and-fast-like/</guid><description>&lt;p&gt;SQL supports wildcard search on strings using &lt;code&gt;LIKE&lt;/code&gt; operator which accepts &lt;code&gt;%&lt;/code&gt; and &lt;code&gt;_&lt;/code&gt; wildcards. The problem with &lt;code&gt;LIKE&lt;/code&gt; is it&amp;rsquo;s not very fast if you have a lot of rows and the query is &lt;a href="https://en.wikipedia.org/wiki/Sargable"&gt;non-sargable&lt;/a&gt;. And in some cases you need to provide fuzzy search capabilities where the results don&amp;rsquo;t have to exactly match the query.&lt;/p&gt;
&lt;p&gt;PostgreSQL has the &lt;a href="https://www.postgresql.org/docs/9.6/pgtrgm.html"&gt;&lt;code&gt;pg_trgm&lt;/code&gt; extension&lt;/a&gt; that solves both problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It has &lt;code&gt;gin&lt;/code&gt; and &lt;code&gt;gist&lt;/code&gt; indexes for speeding up &lt;code&gt;LIKE&lt;/code&gt; and other string operators&lt;/li&gt;
&lt;li&gt;It has &lt;code&gt;similarity&lt;/code&gt; function and &lt;code&gt;%&lt;/code&gt; operator for string similarity search using trigrams.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s assume we have this table:&lt;/p&gt;</description></item><item><title>Backing up and restoring databases in Postgres</title><link>https://mazeez.dev/posts/backup-and-restore-in-postgres/</link><pubDate>Thu, 01 Apr 2021 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/backup-and-restore-in-postgres/</guid><description>&lt;p&gt;To get a dump of a database you can use &lt;code&gt;pg_dump&lt;/code&gt; or &lt;code&gt;pg_dumpall&lt;/code&gt; for dumping an entire cluster. It &lt;a href="https://www.postgresql.org/docs/9.1/app-pgdump.html"&gt;supports 4 formats&lt;/a&gt;:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Format&lt;/th&gt;
 &lt;th&gt;Description&lt;/th&gt;
 &lt;th&gt;Restore via&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;plain&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Output a plain-text SQL script file (the default).&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;psql&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;custom&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Output a custom-format archive suitable for input into pg_restore. Together with the directory output format, this is the most flexible output format in that it allows manual selection and reordering of archived items during restore. This format is also compressed by default.&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;pg_restore&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;directory&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Output a directory-format archive suitable for input into pg_restore. This will create a directory with one file for each table and blob being dumped, plus a so-called Table of Contents file describing the dumped objects in a machine-readable format that pg_restore can read. A directory format archive can be manipulated with standard Unix tools; for example, files in an uncompressed archive can be compressed with the gzip tool. This format is compressed by default.&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;pg_restore&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;tar&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;Output a &lt;code&gt;tar&lt;/code&gt;-format archive suitable for input into pg_restore. The tar format is compatible with the directory format: extracting a tar-format archive produces a valid directory-format archive. However, the tar format does not support compression. Also, when using tar format the relative order of table data items cannot be changed during restore.&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;pg_restore&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="how-to-backup-a-database"&gt;How to backup a database&lt;/h3&gt;
&lt;p&gt;To create a dump of &lt;code&gt;sample-db&lt;/code&gt; in &lt;code&gt;custom&lt;/code&gt; format and save it to &lt;code&gt;sample-db.dump&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Why I love Powershell as a scripting language</title><link>https://mazeez.dev/posts/why-i-love-powershell/</link><pubDate>Sun, 14 Mar 2021 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/why-i-love-powershell/</guid><description>&lt;p&gt;Every once in a while, I have to write a script to automate a task. Maybe it&amp;rsquo;s part of a CI/CD pipeline, or it&amp;rsquo;s part of my dev workflow. My favorite language for writing scripts is PowerShell. Here is why:&lt;/p&gt;
&lt;h1 id="1-powershell-has-an-object-pipeline"&gt;1. Powershell has an object pipeline&lt;/h1&gt;
&lt;p&gt;When you pass data (or pipe them) from one command to the next, the data is treated as an object, not as a string. Which means the data can have different properties and it retains these properties.&lt;/p&gt;</description></item><item><title>Background Job Scheduling using Hangfire</title><link>https://mazeez.dev/posts/background-job-scheduling-using-hangfire/</link><pubDate>Sat, 05 Dec 2020 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/background-job-scheduling-using-hangfire/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This post is part of C# &lt;a href="https://www.csadvent.christmas/"&gt;Advent Calendar 2020&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sometimes you&amp;rsquo;ve tasks that would take too much time to do in the request-response model. For example sending multiple emails. So you have to send the emails asynchronously (i.e. in the background) and returning a response before the jobs are done. Or maybe you want to do some task periodically. For example generating a resource-intensive report at midnight or sending monthly invoices to customers. In short, you want to be able to schedule jobs and be able to track their progress and see their results.&lt;/p&gt;</description></item><item><title>How to include folders as link recursively in csproj files</title><link>https://mazeez.dev/posts/csproj-include-folders-recursively/</link><pubDate>Tue, 13 Oct 2020 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/csproj-include-folders-recursively/</guid><description>&lt;p&gt;Suppose we have a folder called &lt;code&gt;dependencies&lt;/code&gt; with this structure:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; - dependencies
 - child-folder
 - file.txt
 - file2.txt
 - file3.txt
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you want to add the entire folder as link and preserve the directory structure, you can use this inside your &lt;code&gt;.csproj&lt;/code&gt; file:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;ItemGroup&amp;gt;
 &amp;lt;None Include=&amp;#34;..\dependencies\**\*&amp;#34;&amp;gt;
 &amp;lt;Link&amp;gt;dependencies\%(RecursiveDir)/%(FileName)%(Extension)&amp;lt;/Link&amp;gt;
 &amp;lt;CopyToOutputDirectory&amp;gt;PreserveNewest&amp;lt;/CopyToOutputDirectory&amp;gt;
 &amp;lt;/None&amp;gt;
&amp;lt;/ItemGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will include &lt;code&gt;dependencies&lt;/code&gt; folder inside your project along with all of its child folder and files.&lt;/p&gt;</description></item><item><title>GitHub Party Trick</title><link>https://mazeez.dev/posts/github-party-trick/</link><pubDate>Tue, 25 Aug 2020 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/github-party-trick/</guid><description>&lt;p&gt;GitHub associates commits with people via email addresses. Each commit is signed with a commit and a name. So when you push a repo to GitHub, it looks for a user with that email address and associates the commit with that user. This allows some cool tricks!&lt;/p&gt;
&lt;p&gt;You can commit as your favorite programmer in your repositories! &lt;a href="https://github.com/encrypt0r/trick/graphs/contributors"&gt;Example&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mazeez.dev/assets/images/posts/github-party-trick/contributors.png" alt="List of contributors contains Rhyan Dhall, Rich Harris, and Linus Torvalds"&gt;&lt;/p&gt;
&lt;p&gt;In a repository, change your email address to their email address:&lt;/p&gt;</description></item><item><title>Use C# Source Generators to make all of your methods async!</title><link>https://mazeez.dev/posts/csharp-source-generators/</link><pubDate>Tue, 05 May 2020 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/csharp-source-generators/</guid><description>&lt;p&gt;C# Source Generators is a C# 9 feature that lets your generate source code during build. For more information read the &lt;a href="https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/"&gt;announcement blog post&lt;/a&gt; on .NET blog.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: If it&amp;rsquo;s not clear, this post is satire. Don&amp;rsquo;t use any of the code or suggestions in production.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Have you ever had problems with app speed? Well, the easiest way to speed up your app is to make your methods async. And the easiest way of making your methods async is by using &lt;code&gt;Task.Run&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>'Enabling automatic updates for sideloaded UWP apps: Multiple update channels'</title><link>https://mazeez.dev/posts/update-sideloaded-uwp-2/</link><pubDate>Sat, 25 Apr 2020 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/update-sideloaded-uwp-2/</guid><description>&lt;p&gt;In a &lt;a href="https://mazeez.dev/posts/update-sideloaded-uwp"&gt;previous&lt;/a&gt; post we talked about getting more control over the update process in sideloaded UWP apps. And in &lt;a href="https://mazeez.dev/posts/uwp-devops"&gt;another post&lt;/a&gt; we talked about setting up CI/CD pipelines for UWP apps. This time we will talk about how to create multiple update channels, i.e. alpha, beta, stable, for our UWP app.&lt;/p&gt;
&lt;p&gt;The idea is very simple, and although I am going to use Azure Blob Storage, nothing stops you from using a normal web host.&lt;/p&gt;</description></item><item><title>Getting a code signing certificate for a company in Iraq</title><link>https://mazeez.dev/posts/code-signing-certificate-iraq/</link><pubDate>Thu, 16 Apr 2020 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/code-signing-certificate-iraq/</guid><description>&lt;p&gt;If your company is based in one of the developed countries, chances are you won&amp;rsquo;t have much of a problem. It would take a week at most to get a code signing certificate. However, If your company is based in a country like Iraq, which doesn&amp;rsquo;t have an up-to-date online-accessible list of its companies, then you are going to have a harder time. Fortunately, this guide makes the process much easier and faster. The documents might vary by country, but the certificate authority support team will help you go through the process.&lt;/p&gt;</description></item><item><title>Running ASP.NET Core on Linux Part 1</title><link>https://mazeez.dev/posts/aspnet-on-linux-1/</link><pubDate>Tue, 07 Apr 2020 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/aspnet-on-linux-1/</guid><description>&lt;p&gt;In the last couple of weeks, I have been busy setting up a CI/CD pipeline for one of my side projects and getting it to run on Linux. I&amp;rsquo;ll try to write about what I have learned in the process.&lt;/p&gt;
&lt;p&gt;This will be a series of blog posts because I don&amp;rsquo;t want it to become too long. This is the first part. We will create a new ASP.NET Core application and manually run it on Linux and configure Nginx and systemd.&lt;/p&gt;</description></item><item><title>Debugging native library dependencies on Linux</title><link>https://mazeez.dev/posts/debugging-native-library-dependencies-linux/</link><pubDate>Sat, 04 Apr 2020 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/debugging-native-library-dependencies-linux/</guid><description>&lt;p&gt;.NET Core apps can run on a number of operating systems. When using purely .NET libraries, deployment is a breeze. However, if you&amp;rsquo;re using a library that wraps a native (C/C++) library, then you might have come across this error message when trying to run your app on Linux:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;System.TypeInitializationException: The type initializer for &amp;#39;DlibDotNet.NativeMethods&amp;#39; threw an exception.
 ---&amp;gt; System.DllNotFoundException: Unable to load shared library &amp;#39;DlibDotNetNativeDnn&amp;#39; or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libDlibDotNetNativeDnn: cannot open shared object file: No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This tells us that either &lt;code&gt;libDlibDotNetNativeDnn.so&lt;/code&gt; doesn&amp;rsquo;t exist (which in my case it did), or it has some other native dependencies that are missing.&lt;/p&gt;</description></item><item><title>How do Object Relational Mappers (like Entity Framework) work?</title><link>https://mazeez.dev/posts/how-orms-work/</link><pubDate>Sat, 21 Dec 2019 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/how-orms-work/</guid><description>&lt;p&gt;When connecting an app or website to a database, most of the time you&amp;rsquo;re querying the database and mapping the result to strongly typed objects. If you&amp;rsquo;ve been using an ORM like Enitity Framework or a Micro-ORM like Dapper, they handle the mapping of the objects and translation of the queries between C# and SQL.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This article is a part of the &lt;a href="https://crosscuttingconcerns.com/The-Third-Annual-csharp-Advent"&gt;3rd annual C# advent calendar&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The idea of ORMs is simple, since most of the code mapping code is mechanical and repetitive, it&amp;rsquo;s a very good candidate for automation. Lets assume we have a &lt;code&gt;Person&lt;/code&gt; table with this schema:&lt;/p&gt;</description></item><item><title>Setting up automated build and release pipeline for side-loaded UWP apps using Azure DevOps</title><link>https://mazeez.dev/posts/uwp-devops/</link><pubDate>Sun, 27 Oct 2019 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/uwp-devops/</guid><description>&lt;p&gt;This week we set up a CI/CD pipeline for one of our UWP apps that needs to be sideloaded because we don&amp;rsquo;t publish it through the Microsoft Store. &lt;a href="https://docs.microsoft.com/en-us/windows/uwp/packaging/auto-build-package-uwp-apps"&gt;This article&lt;/a&gt; was super useful in getting me started. Microsoft has made things quite easy with Azure DevOps, but there were a few things that took us a little bit of time to figure out.&lt;/p&gt;
&lt;h2 id="a-little-bit-of-context"&gt;A little bit of context&lt;/h2&gt;
&lt;p&gt;We have an enterprise UWP application that we publish via an http server. We also have a custom auto-update mechanism that updates the apps whenever an update is available. You can learn more about the &lt;a href="https://mazeez.dev/posts/update-sideloaded-uwp"&gt;auto-updater here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>How to get an instance of a page when you navigate to it in UWP</title><link>https://mazeez.dev/posts/how-to-get-an-instance-of-a-page-when-you-navigate-to-it-in-uwp/</link><pubDate>Sun, 26 May 2019 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/how-to-get-an-instance-of-a-page-when-you-navigate-to-it-in-uwp/</guid><description>&lt;p&gt;By default when navigating a frame to a page, UWP doesn&amp;rsquo;t give you back a page instance. So the only way of passing parameters is to use the &lt;code&gt;parameter&lt;/code&gt; parameter. But having an instance to the page can have many other benefits: For example it allows the child page to have custom events and the parent page can subscribe to them.&lt;/p&gt;
&lt;p&gt;However &lt;code&gt;Frame&lt;/code&gt; has an event called &lt;code&gt;Navigated&lt;/code&gt; that can help us to write an extension method to get a reference to the actual instance:&lt;/p&gt;</description></item><item><title>Why you should read on topics that you might not need right now?</title><link>https://mazeez.dev/posts/why-you-should-read-on-topics-that-you-might-not-need-right-now/</link><pubDate>Thu, 23 May 2019 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/why-you-should-read-on-topics-that-you-might-not-need-right-now/</guid><description>&lt;p&gt;I was browsing web once when I stumbled upon an article about &lt;a href="https://github.com/mono/SkiaSharp"&gt;SkiaSharp&lt;/a&gt;. It&amp;rsquo;s a C# wrapper around Google&amp;rsquo;s fast 2D rending engine. I was developing desktop apps in WPF at the time and didn&amp;rsquo;t feel the need to learn a low level library like that.&lt;/p&gt;
&lt;p&gt;A few weeks later, I found myself in a project that required building a fast layout designer. First, I tried to write it purely in WPF, and I did. It was super slow, on a decently fast computer, it took a few seconds to load a layout.&lt;/p&gt;</description></item><item><title>How the C# yield keyword works</title><link>https://mazeez.dev/posts/csharp-yield/</link><pubDate>Mon, 20 May 2019 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/csharp-yield/</guid><description>&lt;p&gt;The &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/yield"&gt;C# yield keyword&lt;/a&gt; is an interesting keyword, because when you use it, you can return an &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; without specifying any concrete implementation explicitly.&lt;/p&gt;
&lt;p&gt;Here is a code snippet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 1&lt;/span&gt;&lt;span&gt;&lt;span style="color:#007020;font-weight:bold"&gt;static&lt;/span&gt; IEnumerable&amp;lt;&lt;span style="color:#902000"&gt;int&lt;/span&gt;&amp;gt; GetNumbers()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 2&lt;/span&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 3&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;yield&lt;/span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;return&lt;/span&gt; &lt;span style="color:#40a070"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 4&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;yield&lt;/span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;return&lt;/span&gt; &lt;span style="color:#40a070"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 5&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;yield&lt;/span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;return&lt;/span&gt; &lt;span style="color:#40a070"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 6&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 7&lt;/span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 8&lt;/span&gt;&lt;span&gt;&lt;span style="color:#007020;font-weight:bold"&gt;static&lt;/span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;void&lt;/span&gt; Main(&lt;span style="color:#902000"&gt;string&lt;/span&gt;[] args)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt; 9&lt;/span&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;10&lt;/span&gt;&lt;span&gt; &lt;span style="color:#902000"&gt;var&lt;/span&gt; numbers = GetNumbers();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;11&lt;/span&gt;&lt;span&gt; &lt;span style="color:#007020;font-weight:bold"&gt;foreach&lt;/span&gt; (&lt;span style="color:#902000"&gt;var&lt;/span&gt; n &lt;span style="color:#007020;font-weight:bold"&gt;in&lt;/span&gt; numbers)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;12&lt;/span&gt;&lt;span&gt; Console.WriteLine(n);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;13&lt;/span&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is the output:&lt;/p&gt;</description></item><item><title>Writing Native Libraries in C# and using them in other languages</title><link>https://mazeez.dev/posts/writing-native-libraries-in-csharp/</link><pubDate>Fri, 03 May 2019 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/writing-native-libraries-in-csharp/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Note: Stefan Hausotte has ported &lt;a href="https://secanablog.wordpress.com/2020/02/01/writing-a-native-library-in-f-which-can-be-called-from-c/"&gt;this little experiment to F#&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Recently I stumbled upon &lt;a href="https://medium.com/@MStrehovsky/fight-the-global-warming-compile-your-c-apps-ahead-of-time-9997e953645b"&gt;this article&lt;/a&gt; from &lt;a href="https://twitter.com/MStrehovsky"&gt;Michal Strehovsky&lt;/a&gt;. It was a great introduction to CoreRT, it made me curious, can you write native libraries with CoreRT? and the answer was Yes!&lt;/p&gt;
&lt;?# Twitter 1123859217654460424 /?&gt;
&lt;p&gt;I have a little library that I want to be available for multiple languages, so I was quite interested in it. So I tried out the &lt;a href="https://github.com/dotnet/corert/tree/master/samples/NativeLibrary"&gt;official sample&lt;/a&gt; and was delighted with the results.&lt;/p&gt;</description></item><item><title>Enabling automatic updates for sideloaded UWP apps</title><link>https://mazeez.dev/posts/update-sideloaded-uwp/</link><pubDate>Fri, 28 Dec 2018 00:00:00 +0000</pubDate><guid>https://mazeez.dev/posts/update-sideloaded-uwp/</guid><description>&lt;p&gt;Recently we wanted to enable auto-updates for an app that we were developing for a client. The app is developed in UWP and it&amp;rsquo;s sideloaded into the client&amp;rsquo;s computers. Although Microsoft has added an auto-update functionality in the &lt;code&gt;1803&lt;/code&gt; build of Windows, we had a few issues with it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It was not very reliable&lt;/li&gt;
&lt;li&gt;We didn&amp;rsquo;t have much control over it beside a simple auto-update policy that specified how often it should check for updates.&lt;/li&gt;
&lt;li&gt;Troubleshooting was very hard as there were no clear way to find out why the auto-updater was not working properly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So I found &lt;a href="https://matthijs.hoekstraonline.net/2016/09/27/auto-updater-for-my-side-loaded-uwp-apps/"&gt;an article&lt;/a&gt; from 2016 and decided to improve upon it and put it a &lt;a href="http://nuget.org/packages/Dwrandaz.AutoUpdateComponent"&gt;nuget package&lt;/a&gt;. The library is open-source and is available on &lt;a href="https://github.com/dwrandaz/AutoUpdateComponent"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>About</title><link>https://mazeez.dev/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://mazeez.dev/about/</guid><description>&lt;p&gt;I&amp;rsquo;m Muhammad Azeez. I build apps, SDKs, distributed systems, and automate systems and workflows using AI. I have experience with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Langugages: Go, C#, TS&lt;/li&gt;
&lt;li&gt;Databases: PostgreSQL, MSSQL, and MongoDB&lt;/li&gt;
&lt;li&gt;Infra: Docker, Linux, RabbitMQ&lt;/li&gt;
&lt;li&gt;Cloud: Azure, AWS, GCP, Hetzner&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="get-in-touch"&gt;Get in touch&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="mailto:muhammad.y.azeez@gmail.com"&gt;Email&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mhmd-azeez"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/muhammad-azeez/"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/mhmd_azeez"&gt;X / Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>