<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>2024 on Funky Si's Test</title><link>https://blog-test.funkysi1701.com/2024/</link><description>Recent content in 2024 on Funky Si's Test</description><generator>Hugo -- gohugo.io</generator><language>en-gb</language><managingEditor>funkysi1701@gmail.com (Simon Foster)</managingEditor><webMaster>funkysi1701@gmail.com (Simon Foster)</webMaster><lastBuildDate>Mon, 30 Dec 2024 20:00:00 +0000</lastBuildDate><atom:link href="https://blog-test.funkysi1701.com/2024/index.xml" rel="self" type="application/rss+xml"/><item><title>Reflecting on 2024, goals for 2025</title><link>https://blog-test.funkysi1701.com/posts/2024/end-of-year/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 30 Dec 2024 20:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2024/end-of-year/</guid><category term="Reflection">Reflection</category><category term="Goals">Goals</category><category term="Learning">Learning</category><category term="Blogging">Blogging</category><category term="PersonalGrowth">PersonalGrowth</category><category term="Conferences">Conferences</category><category term="UserGroups">UserGroups</category><media:content medium="image" type="image/png" url="https://blog-test.funkysi1701.com/images/goals-for-2025.png"/><description>&lt;p&gt;It is that time of year again, time to reflect on the year that has passed and look forward to the year ahead. As with many years 2024 has been a mixed bag, some good stuff, and some not so good stuff. I did not make any goals at the start of 2024, but I am going to fix that for 2025.&lt;/p&gt;
&lt;p&gt;Goals for 2025&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Blog Posts&lt;/li&gt;
&lt;li&gt;More Learning&lt;/li&gt;
&lt;li&gt;Drink More Water and Do More Walks&lt;/li&gt;
&lt;li&gt;Attend Conferences and User Groups&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="blog-posts"&gt;Blog Posts&lt;a class="anchor ms-1" href="#blog-posts" aria-label="Permalink: Blog Posts"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For most of the year, I have &lt;strong&gt;not&lt;/strong&gt; been writing blog posts. However, the Scottish Summit conference reignited my blogging spark, and I have written seven posts since then. My goal is to write one post a week. I am sure I will miss the odd week, but the important thing is not to miss two in a row.&lt;/p&gt;
&lt;h2 id="more-learning"&gt;More Learning&lt;a class="anchor ms-1" href="#more-learning" aria-label="Permalink: More Learning"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Being a developer is a constant journey of learning, and I have not done enough of that this year. During December, I completed a few challenges from &lt;a href="https://adventofcode.com/" target="_blank" rel="noopener noreferrer"&gt;Advent of Code&lt;/a&gt;
, and I hope to do more of them. I have also discovered &lt;a href="https://exercism.org/" target="_blank" rel="noopener noreferrer"&gt;Exercism&lt;/a&gt;
and started working through the C# track. I am sure there will be more opportunities to learn new things in 2025.&lt;/p&gt;
&lt;h2 id="health"&gt;Health&lt;a class="anchor ms-1" href="#health" aria-label="Permalink: Health"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;2024 took an unusual turn. In June, I walked a &lt;a href="https://blog-test.funkysi1701.com/posts/2024/charity-hike"&gt;half marathon across the Peak District&lt;/a&gt;
, and since then, I have been doing lots of walks. Walking is good for my physical and mental health, so I intend to do more of it in 2025. I have a 5k scheduled for January, which should be lots of fun as it is around the wildlife park. On the same topic, I want to drink more water. Not sure how I am going to accomplish this as I am easily distracted by the current developer problem, instead of thinking about my health.&lt;/p&gt;
&lt;h2 id="conferences-and-user-groups"&gt;Conferences and User Groups&lt;a class="anchor ms-1" href="#conferences-and-user-groups" aria-label="Permalink: Conferences and User Groups"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I want to attend a conference or user group once a month in 2025. Conferences and user groups are great places to meet people, learn new things, and be encouraged by the community. I have signed up as a volunteer for NDC London in January, and DDD North is back in February. I am sure I will be able to fill the other months with events soon enough as well.&lt;/p&gt;
&lt;h2 id="what-happened-in-2024"&gt;What Happened in 2024&lt;a class="anchor ms-1" href="#what-happened-in-2024" aria-label="Permalink: What Happened in 2024"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I did something in 2024 that I thought I would never do. I signed up for a half marathon hike across the Peak District for charity. This was an amazing achievement for me, involving lots of training walks and raising over £600 for charity.&lt;/p&gt;
&lt;p&gt;My attendance at conferences and user groups has been a bit light this year. However, I did attend the Scottish Summit in October, which rekindled my blogging. I also attended DDD North with a couple of my work colleagues, which was great as usual.&lt;/p&gt;
&lt;p&gt;Family life has kept me busy this year and has been my focus for much of the year. Next year, I want the focus to shift more to my work and career. I attended a couple of code club sessions with my eldest son, and it was great to see his skills develop. Like me, he wanted to help others with the coding exercise.&lt;/p&gt;</description></item><item><title>Automate develop to main pull requests</title><link>https://blog-test.funkysi1701.com/posts/2024/automatic-pull-requests/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 16 Dec 2024 20:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2024/automatic-pull-requests/</guid><category term="AzureDevOps">AzureDevOps</category><category term="PullRequests">PullRequests</category><category term="Automation">Automation</category><category term="PowerShell">PowerShell</category><category term="CI/CD">CI/CD</category><category term="DevOps">DevOps</category><media:content medium="image" type="image/png" url="https://blog-test.funkysi1701.com/images/automatic-pull-requests.png"/><description>&lt;p&gt;Creating pull requests is part of day-to-day Git work: you propose changes, review them, and merge. Long-lived integration branches make that tedious if someone has to open the release PR by hand every time.&lt;/p&gt;
&lt;p&gt;Automatic pull requests keep a develop → main (or master) PR open and refreshed when develop moves. Below are two patterns I use: GitHub Actions with the GitHub CLI, and Azure DevOps with a PowerShell script against the REST API.&lt;/p&gt;
&lt;h2 id="github"&gt;GitHub&lt;a class="anchor ms-1" href="#github" aria-label="Permalink: GitHub"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;GitHub Actions can run whenever code is pushed to &lt;code&gt;develop&lt;/code&gt;. Prefer &lt;strong&gt;create or update&lt;/strong&gt; so a second push does not fail when the PR already exists — the same idea this site uses in &lt;a href="https://github.com/funkysi1701/funkysi1701.github.io/blob/main/.github/workflows/auto-pr.yml" target="_blank" rel="noopener noreferrer"&gt;&lt;code&gt;.github/workflows/auto-pr.yml&lt;/code&gt;&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Auto PR&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;push&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;branches&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;develop&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;workflow_dispatch&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;permissions&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;contents&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;read&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;pull-requests&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;write&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;jobs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;create-pr&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ubuntu-latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;steps&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Check out repository code&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/checkout@v4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;fetch-depth&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;ref&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;develop&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Create or update pull request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;env&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;GITHUB_TOKEN&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: |&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; TITLE=&amp;#39;Merge develop into main&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; BODY=&amp;#39;Created by GitHub Actions.&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; if gh pr create -B main -H develop --title &amp;#34;$TITLE&amp;#34; --body &amp;#34;$BODY&amp;#34;; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; exit 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; PR=$(gh pr list --head develop --base main --state open --json number -q &amp;#39;.[0].number&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; if [ -n &amp;#34;$PR&amp;#34; ] &amp;amp;&amp;amp; [ &amp;#34;$PR&amp;#34; != &amp;#34;null&amp;#34; ]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; gh pr edit &amp;#34;$PR&amp;#34; --title &amp;#34;$TITLE&amp;#34; --body &amp;#34;$BODY&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; echo &amp;#34;No open PR found to update.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; exit 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This runs on push to &lt;code&gt;develop&lt;/code&gt;, checks out that branch, then creates a PR into &lt;code&gt;main&lt;/code&gt; or edits the existing open develop → main PR. Pin &lt;code&gt;actions/checkout&lt;/code&gt; to a major tag (or a full commit SHA in production workflows) and grant &lt;code&gt;pull-requests: write&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The workflow uses the &lt;a href="https://cli.github.com/" target="_blank" rel="noopener noreferrer"&gt;GitHub CLI&lt;/a&gt;
. &lt;code&gt;gh pr create&lt;/code&gt; opens the PR; &lt;code&gt;gh pr edit&lt;/code&gt; refreshes title and body when create fails because one already exists. You can also fold create-or-edit into a one-liner if you prefer:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;run&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;gh pr create -B main -H develop --title &amp;#39;Merge develop into main&amp;#39; --body &amp;#39;Created by GitHub action&amp;#39; || gh pr edit -B main --title &amp;#34;Merge develop into main&amp;#34; --body &amp;#39;Created by GitHub action&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="azure-devops"&gt;Azure DevOps&lt;a class="anchor ms-1" href="#azure-devops" aria-label="Permalink: Azure DevOps"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Azure DevOps has a similar feature to GitHub Actions called Azure Pipelines. You can create pipelines that run on specific triggers, such as when code is pushed to a specific branch. For Azure DevOps I have a PowerShell script that does most of the work; let’s have a look at it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;param&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [Parameter(&lt;span style="color:#a6e22e"&gt;Mandatory&lt;/span&gt;=$true)][&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;]$repoName,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [Parameter(&lt;span style="color:#a6e22e"&gt;Mandatory&lt;/span&gt;=$true)][&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;]$sourceBranch,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [Parameter(&lt;span style="color:#a6e22e"&gt;Mandatory&lt;/span&gt;=$true)][&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;]$targetBranch,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [Parameter(&lt;span style="color:#a6e22e"&gt;Mandatory&lt;/span&gt;=$true)][&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;]$prTitle,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [Parameter(&lt;span style="color:#a6e22e"&gt;Mandatory&lt;/span&gt;=$true)][&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;]$prDescription
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Construct base URLs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$collectionUri = $env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI.TrimEnd(&lt;span style="color:#e6db74"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$projectName = $env:SYSTEM_TEAMPROJECT
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$apisUrl = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$collectionUri&lt;span style="color:#e6db74"&gt;/&lt;/span&gt;$projectName&lt;span style="color:#e6db74"&gt;/_apis&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$apiVersionQs = &lt;span style="color:#e6db74"&gt;&amp;#34;?api-version=7.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Create common headers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$headers = @{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Authorization&amp;#34;&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;Bearer &lt;/span&gt;$env:SYSTEM_ACCESSTOKEN&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;application/json&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Step 1: Fetch the repository GUID using its name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$repositoryUrl = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$apisUrl&lt;span style="color:#e6db74"&gt;/git/repositories/&lt;/span&gt;$repoName$apiVersionQs&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$repositoryResponse = Invoke-RestMethod -Uri $repositoryUrl -Method GET -Headers $headers
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$repoGuid = $repositoryResponse.id &lt;span style="color:#75715e"&gt;# Extract the repository GUID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-not&lt;/span&gt; $repoGuid) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Failed to retrieve repository GUID for repository &amp;#39;&lt;/span&gt;$repoName&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Now construct the project URL using the repository GUID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$projectUrl = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$apisUrl&lt;span style="color:#e6db74"&gt;/git/repositories/&lt;/span&gt;$repoGuid&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Construct full ref names&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$sourceBranchRef = &lt;span style="color:#e6db74"&gt;&amp;#34;refs/heads/&lt;/span&gt;$sourceBranch&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$targetBranchRef = &lt;span style="color:#e6db74"&gt;&amp;#34;refs/heads/&lt;/span&gt;$targetBranch&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Step 2: Prepare the body for the commit comparison using GetCommitsBatch API&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$body = @{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;itemVersion&amp;#34;&lt;/span&gt; = @{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;version&amp;#34;&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$targetBranch&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;versionType&amp;#34;&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;compareVersion&amp;#34;&lt;/span&gt; = @{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;version&amp;#34;&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$sourceBranch&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;versionType&amp;#34;&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} | ConvertTo-Json
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Step 3: Call the Azure DevOps API to compare the branches using GetCommitsBatch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$diffUrl = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$projectUrl&lt;span style="color:#e6db74"&gt;/commitsBatch&lt;/span&gt;$apiVersionQs&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$commitResponse = Invoke-RestMethod -Uri $diffUrl -Method POST -Headers $headers -Body $body
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Step 4: Check if there are any changes between the branches&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; ($commitResponse.count &lt;span style="color:#f92672"&gt;-gt&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Write-Output &lt;span style="color:#e6db74"&gt;&amp;#34;There are changes between &lt;/span&gt;$sourceBranch&lt;span style="color:#e6db74"&gt; and &lt;/span&gt;$targetBranch&lt;span style="color:#e6db74"&gt;.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Write-Output &lt;span style="color:#e6db74"&gt;&amp;#34;No changes between &lt;/span&gt;$sourceBranch&lt;span style="color:#e6db74"&gt; and &lt;/span&gt;$targetBranch&lt;span style="color:#e6db74"&gt;.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Check for existing active pull requests between source and target branches&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$encodedSourceBranchRef = [&lt;span style="color:#66d9ef"&gt;System.Web.HttpUtility&lt;/span&gt;]::UrlEncode($sourceBranchRef)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$encodedTargetBranchRef = [&lt;span style="color:#66d9ef"&gt;System.Web.HttpUtility&lt;/span&gt;]::UrlEncode($targetBranchRef)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$checkPrUrl = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$projectUrl&lt;span style="color:#e6db74"&gt;/pullrequests&lt;/span&gt;$apiVersionQs&lt;span style="color:#e6db74"&gt;&amp;amp;searchCriteria.sourceRefName=&lt;/span&gt;$encodedSourceBranchRef&lt;span style="color:#e6db74"&gt;&amp;amp;searchCriteria.targetRefName=&lt;/span&gt;$encodedTargetBranchRef&lt;span style="color:#e6db74"&gt;&amp;amp;searchCriteria.status=active&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Write-Output &lt;span style="color:#e6db74"&gt;&amp;#34;Checking for existing active pull requests between &lt;/span&gt;$sourceBranch&lt;span style="color:#e6db74"&gt; and &lt;/span&gt;$targetBranch&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$existingPrs = Invoke-RestMethod -Method GET -Headers $headers -Uri $checkPrUrl
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; ($existingPrs.count &lt;span style="color:#f92672"&gt;-gt&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# An active pull request already exists&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $existingPr = $existingPrs.value[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#75715e"&gt;# Assuming we take the first one if multiple exist&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $pullRequestId = $existingPr.pullRequestId
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Write-Output &lt;span style="color:#e6db74"&gt;&amp;#34;An active pull request already exists between &lt;/span&gt;$sourceBranch&lt;span style="color:#e6db74"&gt; and &lt;/span&gt;$targetBranch&lt;span style="color:#e6db74"&gt;.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Write-Output &lt;span style="color:#e6db74"&gt;&amp;#34;Pull Request ID: &lt;/span&gt;$pullRequestId&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Write-Output &lt;span style="color:#e6db74"&gt;&amp;#34;##vso[task.setvariable variable=prId]&lt;/span&gt;$pullRequestId&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Create a Pull Request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$pullRequestUrl = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$projectUrl&lt;span style="color:#e6db74"&gt;/pullrequests&lt;/span&gt;$apiVersionQs&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$pullRequest = @{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;sourceRefName&amp;#34;&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$sourceBranchRef&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;targetRefName&amp;#34;&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$targetBranchRef&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;title&amp;#34;&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$prTitle&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;description&amp;#34;&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$prDescription&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$pullRequestJson = ($pullRequest | ConvertTo-Json -Depth &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Write-Output &lt;span style="color:#e6db74"&gt;&amp;#34;Sending a REST call to create a new pull request from &lt;/span&gt;$sourceBranch&lt;span style="color:#e6db74"&gt; to &lt;/span&gt;$targetBranch&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# REST call to create a Pull Request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$pullRequestResult = Invoke-RestMethod -Method POST -Headers $headers -Body $pullRequestJson -Uri $pullRequestUrl
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Ensure the pull request ID exists&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-not&lt;/span&gt; $pullRequestResult.pullRequestId) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Pull request creation failed. No pull request ID returned.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$pullRequestId = $pullRequestResult.pullRequestId
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Write-Output &lt;span style="color:#e6db74"&gt;&amp;#34;Pull request created. Pull Request Id: &lt;/span&gt;$pullRequestId&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Write-Output &lt;span style="color:#e6db74"&gt;&amp;#34;##vso[task.setvariable variable=prId]&lt;/span&gt;$pullRequestId&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This uses the Azure DevOps REST API to create a PR. The script takes the repository name, source branch, target branch, PR title, and PR description. It compares the branches, creates a PR when there are commits to merge, and reuses an existing active PR when one is already open. Run it as a pipeline step.&lt;/p&gt;
&lt;p&gt;My pipeline has a step that looks a bit like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;task&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;PowerShell@2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;displayName&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Create PR&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;condition&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;eq(variables[&amp;#39;Build.SourceBranch&amp;#39;], &amp;#39;refs/heads/develop&amp;#39;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;inputs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;targetType&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;inline&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;script&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;build/CreatePR.ps1 -repoName ProjectX -sourceBranch develop -targetBranch main -prTitle &amp;#34;Release $(Build.Number.Major).$(Build.Number.Minor).x&amp;#34; -prDescription &amp;#34;Dev to Prod&amp;#34;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;env&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;SYSTEM_ACCESSTOKEN&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;$(System.AccessToken)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I only run this step on the develop branch, and you can see I supply all the parameters that are defined in my PowerShell script. I include the &lt;code&gt;System.AccessToken&lt;/code&gt; so the step can call the REST APIs for the project.&lt;/p&gt;
&lt;h3 id="related-on-this-blog"&gt;Related on this blog&lt;a class="anchor ms-1" href="#related-on-this-blog" aria-label="Permalink: Related on this blog"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For combining repositories before you automate promotion, see &lt;a href="https://blog-test.funkysi1701.com/posts/2025/merge-two-projects-into-one/"&gt;merge two projects into one&lt;/a&gt;
. For a broader GitHub Actions walkthrough, start with &lt;a href="https://blog-test.funkysi1701.com/posts/2022/using-github-actions/"&gt;using GitHub Actions&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;If you have enjoyed this article and want to get a monthly email with all my latest articles, please sign up for my &lt;a href="https://blog-test.funkysi1701.com/newsletter"&gt;newsletter&lt;/a&gt;
. If you have any questions or comments, please feel free to reach out or leave a comment below.&lt;/p&gt;</description></item><item><title>Common AI and Copilot Terms</title><link>https://blog-test.funkysi1701.com/posts/2024/common-ai-copilot-terms/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 09 Dec 2024 20:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2024/common-ai-copilot-terms/</guid><category term="AI">AI</category><category term="Copilot">Copilot</category><category term="RAG">RAG</category><category term="LLM">LLM</category><category term="GPT">GPT</category><category term="MachineLearning">MachineLearning</category><category term="NaturalLanguageProcessing">NaturalLanguageProcessing</category><media:content medium="image" type="image/jpeg" url="https://blog-test.funkysi1701.com/images/ai.jpeg"/><description>&lt;p&gt;AI is everywhere at the moment, from chatbots to code completion tools like GitHub Copilot. Here are some common AI and Copilot terms with explanations.&lt;/p&gt;
&lt;h2 id="common-ai-and-copilot-terms"&gt;Common AI and Copilot Terms&lt;a class="anchor ms-1" href="#common-ai-and-copilot-terms" aria-label="Permalink: Common AI and Copilot Terms"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="artificial-intelligence-ai"&gt;Artificial Intelligence (AI)&lt;a class="anchor ms-1" href="#artificial-intelligence-ai" aria-label="Permalink: Artificial Intelligence (AI)"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Artificial Intelligence (AI) refers to the simulation of human intelligence in machines that are programmed to think and learn like humans. AI can be used for various applications, including natural language processing, image recognition, and decision-making. AI systems are designed to perform tasks that typically require human intelligence, such as visual perception, speech recognition, decision-making, and language translation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Artificial_intelligence" target="_blank" rel="noopener noreferrer"&gt;Wikipedia: Artificial Intelligence&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="machine-learning-ml"&gt;Machine Learning (ML)&lt;a class="anchor ms-1" href="#machine-learning-ml" aria-label="Permalink: Machine Learning (ML)"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Machine Learning (ML) is a subset of AI that involves the use of algorithms and statistical models to enable machines to improve their performance on a specific task through experience. ML algorithms learn from data and make predictions or decisions without being explicitly programmed. Machine learning is used in a variety of applications, such as email filtering, fraud detection, and recommendation systems.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Machine_learning" target="_blank" rel="noopener noreferrer"&gt;Wikipedia: Machine Learning&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="natural-language-processing-nlp"&gt;Natural Language Processing (NLP)&lt;a class="anchor ms-1" href="#natural-language-processing-nlp" aria-label="Permalink: Natural Language Processing (NLP)"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Natural Language Processing (NLP) is a field of AI that focuses on the interaction between computers and humans through natural language. NLP enables machines to understand, interpret, and generate human language, making it possible for AI systems to communicate with users in a more natural way.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Natural_language_processing" target="_blank" rel="noopener noreferrer"&gt;Wikipedia: Natural Language Processing&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="github-copilot"&gt;GitHub Copilot&lt;a class="anchor ms-1" href="#github-copilot" aria-label="Permalink: GitHub Copilot"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Copilot is an AI-powered code completion tool developed by GitHub in collaboration with OpenAI. It uses machine learning models to provide code suggestions and autocompletions based on the context of the code being written. Copilot helps developers write code faster and with fewer errors by offering relevant code snippets and completing lines of code as they type. It supports a wide range of programming languages and can be integrated into popular code editors like Visual Studio Code.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/about-github-copilot" target="_blank" rel="noopener noreferrer"&gt;GitHub Copilot: Docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/features/copilot" target="_blank" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="retrieval-augmented-generation-rag"&gt;Retrieval-Augmented Generation (RAG)&lt;a class="anchor ms-1" href="#retrieval-augmented-generation-rag" aria-label="Permalink: Retrieval-Augmented Generation (RAG)"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Retrieval-Augmented Generation (RAG) is a technique that combines retrieval-based and generation-based approaches to improve the performance of AI models in tasks such as question answering and text generation. RAG involves retrieving relevant documents or information from a large corpus and using that information to generate more accurate and contextually relevant responses.&lt;/p&gt;
&lt;h3 id="large-language-models-llm"&gt;Large Language Models (LLM)&lt;a class="anchor ms-1" href="#large-language-models-llm" aria-label="Permalink: Large Language Models (LLM)"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Large Language Models (LLM) are a type of AI model that is trained on vast amounts of text data to understand and generate human language. These models, such as GPT-3, are capable of performing a wide range of language tasks, including translation, summarization, and question answering. LLMs leverage deep learning techniques to capture the nuances of language and provide highly accurate and contextually relevant outputs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Language_model" target="_blank" rel="noopener noreferrer"&gt;Wikipedia: Language Models&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="generative-pre-trained-transformer-gpt"&gt;Generative Pre-trained Transformer (GPT)&lt;a class="anchor ms-1" href="#generative-pre-trained-transformer-gpt" aria-label="Permalink: Generative Pre-trained Transformer (GPT)"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Generative Pre-trained Transformer (GPT) is a type of large language model developed by OpenAI. GPT models, such as GPT-3, are pre-trained on a diverse range of internet text and fine-tuned for specific tasks. GPT models are known for their ability to generate coherent and contextually relevant text, making them useful for applications such as chatbots, content creation, and code generation.&lt;/p&gt;
&lt;h3 id="deep-learning"&gt;Deep Learning&lt;a class="anchor ms-1" href="#deep-learning" aria-label="Permalink: Deep Learning"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Deep Learning is a subset of machine learning that involves the use of neural networks with many layers (deep neural networks) to model complex patterns in data. Deep learning has been particularly successful in tasks such as image and speech recognition, natural language processing, and game playing.&lt;/p&gt;
&lt;h3 id="neural-networks"&gt;Neural Networks&lt;a class="anchor ms-1" href="#neural-networks" aria-label="Permalink: Neural Networks"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Neural Networks are a series of algorithms that attempt to recognize underlying relationships in a set of data through a process that mimics the way the human brain operates. Neural networks consist of layers of interconnected nodes (neurons) that process input data and generate output.&lt;/p&gt;
&lt;h3 id="reinforcement-learning-rl"&gt;Reinforcement Learning (RL)&lt;a class="anchor ms-1" href="#reinforcement-learning-rl" aria-label="Permalink: Reinforcement Learning (RL)"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Reinforcement Learning (RL) is a type of machine learning where an agent learns to make decisions by taking actions in an environment to maximize a cumulative reward. RL is commonly used in applications such as robotics, game playing, and autonomous systems.&lt;/p&gt;
&lt;h3 id="computer-vision"&gt;Computer Vision&lt;a class="anchor ms-1" href="#computer-vision" aria-label="Permalink: Computer Vision"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Computer Vision is a field of AI that enables machines to interpret and understand visual information from the world, such as images and videos. Computer vision techniques are used in applications such as facial recognition, object detection, and image classification.&lt;/p&gt;
&lt;h3 id="generative-adversarial-networks-gans"&gt;Generative Adversarial Networks (GANs)&lt;a class="anchor ms-1" href="#generative-adversarial-networks-gans" aria-label="Permalink: Generative Adversarial Networks (GANs)"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Generative Adversarial Networks (GANs) are a class of neural networks used for generating new data samples that are similar to a given training dataset. GANs consist of two networks: a generator that creates new data samples and a discriminator that evaluates the authenticity of the generated samples. GANs are used in applications such as image synthesis, data augmentation, and style transfer.&lt;/p&gt;
&lt;h3 id="positronic-brain"&gt;Positronic Brain&lt;a class="anchor ms-1" href="#positronic-brain" aria-label="Permalink: Positronic Brain"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The Positronic Brain is a fictional technological concept created by science fiction writer Isaac Asimov. It is a highly advanced artificial brain used in robots, enabling them to process information, make decisions, and exhibit behaviors similar to human intelligence. The concept of the Positronic Brain is central to Asimov&amp;rsquo;s Robot series, where it serves as the foundation for the robots&amp;rsquo; cognitive functions and adherence to the Three Laws of Robotics. Star Trek&amp;rsquo;s Commander Data had a positronic brain as well.&lt;/p&gt;
&lt;p&gt;For more information on the Positronic Brain, you can refer to the following sources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Positronic_brain" target="_blank" rel="noopener noreferrer"&gt;Wikipedia: Positronic Brain&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Robot_series" target="_blank" rel="noopener noreferrer"&gt;Isaac Asimov&amp;rsquo;s Robot Series&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Top electricity-consuming devices</title><link>https://blog-test.funkysi1701.com/posts/2024/top-electricity-devices/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 02 Dec 2024 20:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2024/top-electricity-devices/</guid><category term="Electricity">Electricity</category><category term="SmartPlugs">SmartPlugs</category><category term="HomeAssistant">HomeAssistant</category><category term="EnergyMonitoring">EnergyMonitoring</category><category term="PowerConsumption">PowerConsumption</category><media:content medium="image" type="image/png" url="https://blog-test.funkysi1701.com/images/elec-usage.png"/><description>&lt;p&gt;I have been wondering what devices in my house use the most electricity. I have a smart meter which tells me how much electricity I am using, but it doesn&amp;rsquo;t tell me what devices are using the most electricity.&lt;/p&gt;
&lt;p&gt;Recently I purchased 12 of these &lt;a href="https://www.amazon.co.uk/dp/B09VP5KNWM?ref=ppx_yo2ov_dt_b_fed_asin_title" target="_blank" rel="noopener noreferrer"&gt;ANTELA Smart Plugs&lt;/a&gt;
(they come in packs of 4 so it hasn&amp;rsquo;t broken the bank). They are straightforward to set up, you plug them into your power socket and plug your device you want to monitor into them, after that you connect to the wifi and can turn the device off/on and see how much power/current/voltage they are using. I have integrated them into Home Assistant and after about a day of usage I can reveal the following findings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2 x Monitors attached to my Laptop. As I write this they are only using about 30W of power between them.&lt;/li&gt;
&lt;li&gt;Microwave - I cooked a potato and it used 1.2kWh of power.&lt;/li&gt;
&lt;li&gt;Washing Machine - Peaks at about 2kW of power, plus the cycle takes some time to complete.&lt;/li&gt;
&lt;li&gt;Laptop - Laptop charger, looks to be using about 37W of power.&lt;/li&gt;
&lt;li&gt;Kettle - A massive electricity hog, only runs for a short time but reaches 2.9kW of power.&lt;/li&gt;
&lt;li&gt;My Routers/Switches/Servers - My home network has a few devices on it like Raspberry Pi&amp;rsquo;s, a linux and windows server and a network switch etc. Between them they are using about 32W of power. Not a lot but it is on 24-7.&lt;/li&gt;
&lt;li&gt;Fridge - I have a fridge freezer, it uses about 72W of power.&lt;/li&gt;
&lt;li&gt;TV (and firestick) - This is a surprisingly large amount of power. TV is on quite a lot and is using 110W of power. There are other devices which contribute to this value, however when off the TV is still using 10W of power. I am assuming its age is a big factor.&lt;/li&gt;
&lt;li&gt;Tumble Dryer - Again no surprises that this is a big electricity user, it peaks at 2.3kW of power and as it runs for a good couple of hours or so, is a big contributor to my electricity.&lt;/li&gt;
&lt;li&gt;Dishwasher - I have put the dishwasher on a few times today and it peaks at 2.2kW of power.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Electricity Usage" src="https://blog-test.funkysi1701.com/images/elec-usage.png" loading="lazy"
width="701" height="445"
/&gt;
&lt;/p&gt;
&lt;p&gt;I am not able to monitor 100% of my electricity usage, things like lights, my boiler and anything else wired directly in, won&amp;rsquo;t have a plug and I can&amp;rsquo;t monitor in this way. However over the last month or so I can see what is using the most electricity.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Electricity Usage" src="https://blog-test.funkysi1701.com/images/elec-usage2.png" loading="lazy"
width="1537" height="435"
/&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="https://octopus.energy/" target="_blank" rel="noopener noreferrer"&gt;Octopus Energy&lt;/a&gt;
who supply my energy have an agile tariff, which means the price of electricity changes every half hour depending on demand. I want to move the heavy usage of electricity to cheaper parts of the day, so I can save money.&lt;/p&gt;
&lt;p&gt;If you want to support me do check out my &lt;a href="https://blog-test.funkysi1701.com/tools-and-resources/"&gt;referral links&lt;/a&gt;
we could both get £50 if you sign up with Octopus Energy to supply your energy.&lt;/p&gt;
&lt;h2 id="now-how-did-i-get-this-all-setup"&gt;Now how did I get this all setup?&lt;a class="anchor ms-1" href="#now-how-did-i-get-this-all-setup" aria-label="Permalink: Now how did I get this all setup?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1 - Plug a smart plug into a power socket and start measuring power. The app &amp;ldquo;Smart Life&amp;rdquo; is used to connect to the smart plug and get the power readings and is available in the Android store.&lt;/p&gt;
&lt;p&gt;2 - Integrate each smart plug into Home Assistant. The integration you need is the &lt;a href="https://www.home-assistant.io/integrations/tuya" target="_blank" rel="noopener noreferrer"&gt;Tuya&lt;/a&gt;
integration. A User Code from the Smart Life app is needed to add to Home Assistant.&lt;/p&gt;
&lt;p&gt;3 - The Voltage, Power and Current sensors are all defaulted to off in Home Assistant, so you need to go and enable these, once that is done you can see the power usage in Home Assistant.&lt;/p&gt;
&lt;p&gt;4 - Now you have Watts, Amps and Volts in Home Assistant but the Energy section of Home Assistant requires Wh or KWh. To get this you need to use the Integral helper to get the amount of time that the device is on for. Go to Add Integration and search for Integral (helper)&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Electricity Usage" src="https://blog-test.funkysi1701.com/images/elec-usage3.png" loading="lazy"
width="611" height="917"
/&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Name is the user friendly name of the device.&lt;/li&gt;
&lt;li&gt;Metric prefix is the unit of measurement, in this case KWh.&lt;/li&gt;
&lt;li&gt;Time of Unit is Hours&lt;/li&gt;
&lt;li&gt;Entity is the sensor that is measuring the power usage.&lt;/li&gt;
&lt;li&gt;Integration method use Left Riemann sum&lt;/li&gt;
&lt;li&gt;Precision is the number of decimal places, so fine to use 0 here.&lt;/li&gt;
&lt;li&gt;Max Sub Interval is 5 minutes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This gives you an extra sensor in Home Assistant which is the energy usage of the device. In my case in kWh.&lt;/p&gt;
&lt;p&gt;5 - Go to your Energy Dashboard in Home Assistant and go to Energy Configuration. Add the new sensor to the Individual Devices section and you can see the energy usage of the device over time.&lt;/p&gt;
&lt;p&gt;The accuracy is not brilliant, sometimes it looks like I have used more energy in my devices than my smart meter says I have used in total. However it is a good indicator of what is using the most electricity in your house. Leave it running for a few days, you may have to tweak the Integral helper settings to get the best results.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://community.home-assistant.io/t/added-tuya-smart-plugs-where-is-the-energy-monitoring/356746/16" target="_blank" rel="noopener noreferrer"&gt;Home Assistant Forums&lt;/a&gt;
are great for getting this sort of thing setup, I have found a lot of useful information on there.&lt;/p&gt;</description></item><item><title>Getting started with .Net Aspire</title><link>https://blog-test.funkysi1701.com/posts/2024/aspire/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 25 Nov 2024 20:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2024/aspire/</guid><category term="DotNet">DotNet</category><category term="Blazor">Blazor</category><category term="C-Sharp">C-Sharp</category><category term="VisualStudio">VisualStudio</category><category term="Aspire">Aspire</category><category term="OpenTelemetry">OpenTelemetry</category><category term=".NET9">.NET9</category><category term="Microsoft">Microsoft</category><media:content medium="image" type="image/png" url="https://blog-test.funkysi1701.com/images/aspire-ga-what-is-aspire.png"/><description>&lt;h2 id="what-is-net-aspire"&gt;What is .Net Aspire?&lt;a class="anchor ms-1" href="#what-is-net-aspire" aria-label="Permalink: What is .Net Aspire?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;.Net Aspire is a comprehensive set of tools, templates, and packages designed to simplify the development of cloud-native applications using .Net. It focuses on building observable, production-ready apps by providing a consistent and opinionated set of &lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/get-started/aspire-overview" target="_blank" rel="noopener noreferrer"&gt;tools and patterns&lt;/a&gt;
.&lt;/p&gt;
&lt;p&gt;The key features of .Net Aspire:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Orchestration: Enhances the local development experience by simplifying the management of your app&amp;rsquo;s configuration and interconnections. It helps with app composition, service discovery, and connection string management.&lt;/li&gt;
&lt;li&gt;Integrations: Offers NuGet packages for commonly used services like Redis and Postgres, ensuring they connect consistently and seamlessly with your app.&lt;/li&gt;
&lt;li&gt;Tooling: Comes with project templates and tooling experiences for Visual Studio, Visual Studio Code, and the .Net CLI to help you create and interact with .Net Aspire projects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Overall, &lt;a href="https://devblogs.microsoft.com/dotnet/introducing-dotnet-aspire-simplifying-cloud-native-development-with-dotnet-8/" target="_blank" rel="noopener noreferrer"&gt;.Net Aspire&lt;/a&gt;
aims to improve the experience of building .Net cloud-native apps by providing a robust framework for developing distributed applications.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Aspire" src="https://blog-test.funkysi1701.com/images/aspire-ga-what-is-aspire.png" loading="lazy"
width="1400" height="895"
/&gt;
&lt;/p&gt;
&lt;h2 id="getting-started-with-net-aspire"&gt;Getting started with .Net Aspire&lt;a class="anchor ms-1" href="#getting-started-with-net-aspire" aria-label="Permalink: Getting started with .Net Aspire"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I touched on .Net Aspire last week, when I talked about what was new in &lt;a href="https://blog-test.funkysi1701.com/posts/2024/dotnet9"&gt;dotnet 9&lt;/a&gt;
, but let&amp;rsquo;s walk through an example.&lt;/p&gt;
&lt;p&gt;Lets say you have a simple application. It has a Blazor web front end, it communicates with a .Net API and that API retrieves data from a SQL Server database. Before Aspire came along I would create a docker compose file and configure ports so the FE could call the API, and add connection strings so the API could access the database.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-docker-compose.yml" data-lang="docker-compose.yml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;services&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;Api&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;${DOCKER_REGISTRY-}api&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;container_name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;api&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;12345&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;44338&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;networks&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;my-network&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;build&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;context&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;dockerfile&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;API/Dockerfile&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;depends_on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;sqlserver&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;Ui&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;${DOCKER_REGISTRY-}ui&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;container_name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ui&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;44330&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;networks&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;my-network&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;build&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;context&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;dockerfile&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;UI/Dockerfile&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;environment&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;APIPath=http://Api:80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;sqlserver&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;${DOCKER_REGISTRY-}sql&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;container_name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;sql&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;sqlvol:/var/opt/mssql&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;5432:1433&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;networks&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;my-network&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;build&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;context&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;dockerfile&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Database/Dockerfile&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see from this docker compose file, there is a lot of specifying ports and other plumbing to get these three parts of my system to work together.&lt;/p&gt;
&lt;p&gt;Now in Visual Studio, right-click on the API project and select add &lt;strong&gt;.Net Aspire Orchestrator Support&lt;/strong&gt; this will add two new Visual Studio projects to the solution, AppHost and ServiceDefaults.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AppHost is where you configure what service depends on what, you can configure all sorts of different dependencies, like databases (sql server, mysql, postgres etc), rabbitmq, redis and many others.&lt;/li&gt;
&lt;li&gt;ServiceDefaults is where you configure the defaults for your services, like how opentelemetry should be configured, or how logging should work.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now right click on the Blazor project and select the same option to get that wired up as well.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-program.cs" data-lang="program.cs"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; builder = DistributedApplication.CreateBuilder(args);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;builder.AddProject&amp;lt;Projects.UI&amp;gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;ui&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;builder.AddProject&amp;lt;Projects.API&amp;gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;api&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;builder.Build().Run();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Your Program.cs file inside your AppHost project will look something like this now, with both your API and UI/Blazor projects referenced.&lt;/p&gt;
&lt;p&gt;There is one more component we need to wire up, but we don&amp;rsquo;t have a project to right click on for the database. It is fairly straightforward to do, update it to look like the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-program.cs" data-lang="program.cs"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; builder = DistributedApplication.CreateBuilder(args);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; sqldb = builder.AddSqlServer(&lt;span style="color:#e6db74"&gt;&amp;#34;sql&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithDataVolume(&lt;span style="color:#e6db74"&gt;&amp;#34;sql-data&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .AddDatabase(&lt;span style="color:#e6db74"&gt;&amp;#34;Context&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;Project&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; api = builder.AddProject&amp;lt;Projects.API&amp;gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;api&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WaitFor(sqldb)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithReference(sqldb);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;builder.AddProject&amp;lt;Projects.UI&amp;gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;ui&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WaitFor(api)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithReference(api);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; builder.Build().RunAsync();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You also need to install a couple of nuget packages. &lt;strong&gt;Aspire.Hosting.SqlServer&lt;/strong&gt; and &lt;strong&gt;Aspire.Microsoft.EntityFrameworkCore.SqlServer&lt;/strong&gt; the second one is because my project is using Entity Framework. Lets look at what we have, we are defining a SQL Server called sql, with a data volume called sql-data, and a database called Project, which we can refer to as Context. We then configure API to reference the sql server we have just configured, and wait for sql server to be ready before starting the API. Next the Blazor project depends on the API and will wait for that to be ready before starting. Pretty powerful stuff.&lt;/p&gt;
&lt;p&gt;OK lets look at the API project, what do I need to configure in my connectionstrings? Not much, Aspire will fill all of this in for you.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-appsettings.json" data-lang="appsettings.json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;ConnectionStrings&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;Context&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In your API project, your Program.cs will need a nuget package &lt;strong&gt;Aspire.Microsoft.EntityFrameworkCore.SqlServer&lt;/strong&gt; and the following line, and no need for any pulling config and passing in connection strings.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-program.cs" data-lang="program.cs"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;builder.AddSqlServerDbContext&amp;lt;Context&amp;gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Context&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One more clever thing we can do with Aspire is seed some data into my database before starting the project. Update the code that sets up your database in the AppHost project as follows.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-program.cs" data-lang="program.cs"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; sqldb = builder.AddSqlServer(&lt;span style="color:#e6db74"&gt;&amp;#34;sql&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithBindMount(&lt;span style="color:#e6db74"&gt;&amp;#34;./sqlserverconfig&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;/usr/config&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithBindMount(&lt;span style="color:#e6db74"&gt;&amp;#34;../API/data/sqlserver&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;/docker-entrypoint-initdb.d&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithEntrypoint(&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/config/entrypoint.sh&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .WithDataVolume(&lt;span style="color:#e6db74"&gt;&amp;#34;sql-data&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .AddDatabase(&lt;span style="color:#e6db74"&gt;&amp;#34;Context&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;Project&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add a sqlserverconfig folder inside your AppHost project and add the following two files. I have found entrypoint.sh being a bit picky with its line endings (windows vs linux)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-entrypoint.sh" data-lang="entrypoint.sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Adapted from: https://github.com/microsoft/mssql-docker/blob/80e2a51d0eb1693f2de014fb26d4a414f5a5add5/linux/preview/examples/mssql-customize/entrypoint.sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Start the script to create the DB and user&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/usr/config/configure-db.sh &amp;amp;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Start SQL Server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/opt/mssql/bin/sqlservr
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-configure-db.sh" data-lang="configure-db.sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# set -x&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Adapted from: https://github.com/microsoft/mssql-docker/blob/80e2a51d0eb1693f2de014fb26d4a414f5a5add5/linux/preview/examples/mssql-customize/configure-db.sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Wait 60 seconds for SQL Server to start up by ensuring that&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# calling SQLCMD does not return an error code, which will ensure that sqlcmd is accessible&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# and that system and user databases return &amp;#34;0&amp;#34; which means all databases are in an &amp;#34;online&amp;#34; state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-databases-transact-sql?view=sql-server-2017&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dbstatus&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;errcode&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;start_time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;$SECONDS
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;end_by&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$((&lt;/span&gt;start_time &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;60&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;Starting check for SQL Server start-up at &lt;/span&gt;$start_time&lt;span style="color:#e6db74"&gt;, will end at &lt;/span&gt;$end_by&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; &lt;span style="color:#f92672"&gt;[[&lt;/span&gt; $SECONDS -lt $end_by &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt; $errcode -ne &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt; -z &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$dbstatus&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; $dbstatus -ne &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;]]&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dbstatus&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;/opt/mssql-tools18/bin/sqlcmd -h -1 -t &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; -U sa -P &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$MSSQL_SA_PASSWORD&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; -C -Q &lt;span style="color:#e6db74"&gt;&amp;#34;SET NOCOUNT ON; Select SUM(state) from sys.databases&amp;#34;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; errcode&lt;span style="color:#f92672"&gt;=&lt;/span&gt;$?
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sleep &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;elapsed_time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$((&lt;/span&gt;SECONDS &lt;span style="color:#f92672"&gt;-&lt;/span&gt; start_time&lt;span style="color:#66d9ef"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;Stopped checking for SQL Server start-up after &lt;/span&gt;$elapsed_time&lt;span style="color:#e6db74"&gt; seconds (dbstatus=&lt;/span&gt;$dbstatus&lt;span style="color:#e6db74"&gt;,errcode=&lt;/span&gt;$errcode&lt;span style="color:#e6db74"&gt;,seconds=&lt;/span&gt;$SECONDS&lt;span style="color:#e6db74"&gt;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;[[&lt;/span&gt; $dbstatus -ne &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;]]&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#f92672"&gt;[[&lt;/span&gt; $errcode -ne &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;]]&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;SQL Server took more than 60 seconds to start up or one or more databases are not in an ONLINE state&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;dbstatus = &lt;/span&gt;$dbstatus&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;errcode = &lt;/span&gt;$errcode&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; exit &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Loop through the .sql files in the /docker-entrypoint-initdb.d and execute them with sqlcmd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; f in /docker-entrypoint-initdb.d/*.sql
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;Processing &lt;/span&gt;$f&lt;span style="color:#e6db74"&gt; file...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$MSSQL_SA_PASSWORD&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; -C -d master -i &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$f&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The second BindMount line mounts a folder inside your API project, so add a data folder with a subfolder called sqlserver. Inside that add a sql script called init.sql. Put all your CREATE DATABASE and CREATE TABLES sql commands inside this. And if everything works you will have a seeded DB ready to test your application with.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;a class="anchor ms-1" href="#conclusion" aria-label="Permalink: Conclusion"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is just a few things I have done with Aspire. Go check out the docs on &lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/get-started/aspire-overview" target="_blank" rel="noopener noreferrer"&gt;MS learn&lt;/a&gt;
or the some of the sessions from &lt;a href="https://www.youtube.com/watch?v=fiePiEc1qcU&amp;amp;list=PLdo4fOcmZ0oXeSG8BgCVru3zQtw_K4ANY&amp;amp;index=2" target="_blank" rel="noopener noreferrer"&gt;dotnet conf&lt;/a&gt;
.&lt;/p&gt;</description></item><item><title>Version 9 of .Net is here</title><link>https://blog-test.funkysi1701.com/posts/2024/dotnet9/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 18 Nov 2024 20:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2024/dotnet9/</guid><category term="DotNet">DotNet</category><category term="Blazor">Blazor</category><category term="EFCore">EFCore</category><category term="C-Sharp">C-Sharp</category><category term="VisualStudio">VisualStudio</category><category term="Aspire">Aspire</category><category term="AI">AI</category><category term="OpenTelemetry">OpenTelemetry</category><category term=".NET9">.NET9</category><category term="Microsoft">Microsoft</category><media:content medium="image" type="image/png" url="https://blog-test.funkysi1701.com/images/bot-01.png"/><description>&lt;p&gt;Every November it is like Christmas for .NET developers, as Microsoft releases the next version of .NET. This year is no different, and we have version 9 of .NET to play with. This release is packed with new features and improvements across the board.&lt;/p&gt;
&lt;p&gt;If you haven&amp;rsquo;t already head on over to the &lt;a href="https://dotnet.microsoft.com/download/dotnet/9.0" target="_blank" rel="noopener noreferrer"&gt;dotnet website&lt;/a&gt;
and download the latest version.&lt;/p&gt;
&lt;p&gt;Also we get a brand new version of Visual Studio, which is always a good thing, so head on over to the Visual Studio &lt;a href="https://visualstudio.microsoft.com/downloads/" target="_blank" rel="noopener noreferrer"&gt;website&lt;/a&gt;
and download the latest version (or the Preview version if you want to test what is coming out next).&lt;/p&gt;
&lt;p&gt;Back when .Net 7 came out I wrote a &lt;a href="https://blog-test.funkysi1701.com/posts/2022/dotnet7/"&gt;post&lt;/a&gt;
about what you needed to fix to get the latest version working with your existing code. However this time around the upgrade is really smooth.&lt;/p&gt;
&lt;h2 id="nuget-audit"&gt;NuGet Audit&lt;a class="anchor ms-1" href="#nuget-audit" aria-label="Permalink: NuGet Audit"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Back in .Net 8 NuGet Audit was introduced which told you if any of your packages had security vulnerabilities. This has been improved in .Net 9, and now defaults to tell you about transitive dependencies. This is a great feature, but if you would prefer to keep .Net 8&amp;rsquo;s functionality you can add the following to your project (*.csproj) file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;NuGetAuditMode&amp;gt;&lt;/span&gt;direct&lt;span style="color:#f92672"&gt;&amp;lt;/NuGetAuditMode&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="net-aspire"&gt;.Net Aspire&lt;a class="anchor ms-1" href="#net-aspire" aria-label="Permalink: .Net Aspire"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Released just after .Net 8 .Net Aspire is a suite of tools to help develop microservices. Gone are the days of specifying ports and connection strings for your services, Aspire can handle this all programmatically.&lt;/p&gt;
&lt;p&gt;Aspire adds two new projects to your solution. AppHost and ServiceDefaults.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AppHost is where you configure what service depends on what, you can configure all sorts of different dependencies, like databases (sql server, mysql, postgres etc), rabbitmq, redis and many others. It is open source so the community are busy adding everything you could possibly need.&lt;/li&gt;
&lt;li&gt;ServiceDefaults is where you configure the defaults for your services, like how opentelemetry should be configured, or how logging should work. Microsoft have thought hard about this and come up with some opinionated defaults, but you can change these to suit your needs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Starting the AppHost project will start up the Aspire Dashboard where you can start/stop containers, view logs and see the health of your services. This is primarily a devlopment tool, but there are some deployment tools, however I have not explored these much yet. More details about Aspire can be found &lt;a href="https://learn.microsoft.com/en-us/dotnet/aspire/get-started/aspire-overview" target="_blank" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;h2 id="blazor"&gt;Blazor&lt;a class="anchor ms-1" href="#blazor" aria-label="Permalink: Blazor"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I have been using Blazor since the first previews in the .Net 3.1 days. It has come a long way since then, and now with .Net 9 it is even better.&lt;/p&gt;
&lt;p&gt;There has been some optimization of the delivery of static assets. To take advantage of this improvement, replace the following line in your Program.cs file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; app.MapStaticAssets(); &lt;span style="color:#75715e"&gt;//Add this line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; app.UseStaticFiles(); &lt;span style="color:#75715e"&gt;//Remove this line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;.Net 9 will then cache your static assets ang give them a unique filename. This will allow the browser to cache the files for longer, and only download them when they have changed. This will speed up your site and reduce the amount of data transferred.&lt;/p&gt;
&lt;p&gt;In your razor pages use code similar to this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;@Assets[&amp;#34;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;bootstrap&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;bootstrap&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;min&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;css&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#34;]&amp;#34;&lt;/span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;@Assets[&amp;#34;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;css&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#34;]&amp;#34;&lt;/span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;@Assets[&amp;#34;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;BlazorSample&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;styles&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;css&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#34;]&amp;#34;&lt;/span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="ai"&gt;AI&lt;a class="anchor ms-1" href="#ai" aria-label="Permalink: AI"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It will have not escaped your notice that AI is everywhere, and it is no different with .Net. I saw some very impressive demos at the &lt;a href="https://www.dotnetconf.net/" target="_blank" rel="noopener noreferrer"&gt;.Net Conf&lt;/a&gt;
online conference. I encourage you to check our the videos. But to summarize Microsoft have added a bunch of abstractions to make it easier to write code to talk to the different AI models, I haven&amp;rsquo;t played about with AI much yet, but I am tempted to give it a go.&lt;/p&gt;
&lt;h2 id="sql-management-studio"&gt;SQL Management Studio&lt;a class="anchor ms-1" href="#sql-management-studio" aria-label="Permalink: SQL Management Studio"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I have not used SQL Management Studio for a while as I have trying out Azure Data Studio. However a new Preview of SQL Server Management Studio is now &lt;a href="https://learn.microsoft.com/en-us/ssms/ssms-21/release-notes-21?view=sql-server-ver16" target="_blank" rel="noopener noreferrer"&gt;avaliable&lt;/a&gt;
. This version is 64bit and is based on Visual Studio engine, it even shares the same installer.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;a class="anchor ms-1" href="#conclusion" aria-label="Permalink: Conclusion"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is only a small taste of the new features in .Net 9. Go check out .Net Conf to learn more or check out some of the links I have shared above.&lt;/p&gt;</description></item><item><title>Strategy Design Pattern</title><link>https://blog-test.funkysi1701.com/posts/2024/strategy-pattern/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 11 Nov 2024 20:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2024/strategy-pattern/</guid><category term="DesignPatterns">DesignPatterns</category><category term="Architecture">Architecture</category><category term="C-Sharp">C-Sharp</category><media:content medium="image" type="image/jpeg" url="https://blog-test.funkysi1701.com/images/flying-machine-blueprint-patent-john-malone.jpg"/><description>&lt;h2 id="understanding-the-strategy-design-pattern"&gt;Understanding the Strategy Design Pattern.&lt;a class="anchor ms-1" href="#understanding-the-strategy-design-pattern" aria-label="Permalink: Understanding the Strategy Design Pattern."&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the world of software development, design patterns are essential tools that help developers solve common problems in a standardized way. One such pattern is the &lt;strong&gt;Strategy Design Pattern&lt;/strong&gt;. This pattern is particularly useful when you need to define a family of algorithms, encapsulate each one, and make them interchangeable. Let&amp;rsquo;s dive into what the Strategy Design Pattern is, why it&amp;rsquo;s useful, and how you can implement it in your projects.&lt;/p&gt;
&lt;h3 id="what-is-the-strategy-design-pattern"&gt;What is the Strategy Design Pattern?&lt;a class="anchor ms-1" href="#what-is-the-strategy-design-pattern" aria-label="Permalink: What is the Strategy Design Pattern?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The Strategy Design Pattern falls under the category of behavioural design patterns. It enables an algorithm&amp;rsquo;s behaviour to be selected at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.&lt;/p&gt;
&lt;h3 id="why-use-the-strategy-design-pattern"&gt;Why Use the Strategy Design Pattern?&lt;a class="anchor ms-1" href="#why-use-the-strategy-design-pattern" aria-label="Permalink: Why Use the Strategy Design Pattern?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The primary benefits of using the Strategy Design Pattern include:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;: It allows you to change the algorithm or strategy being used without altering the code that uses the algorithm.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reusability&lt;/strong&gt;: By encapsulating algorithms separately, you can reuse them across different parts of your application.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maintainability&lt;/strong&gt;: It promotes cleaner code by adhering to the Single Responsibility Principle, making your code easier to maintain and extend.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="how-to-implement-the-strategy-design-pattern"&gt;How to Implement the Strategy Design Pattern&lt;a class="anchor ms-1" href="#how-to-implement-the-strategy-design-pattern" aria-label="Permalink: How to Implement the Strategy Design Pattern"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s break down the implementation of the Strategy Design Pattern with a simple example. Suppose we are developing a flight simulator that supports multiple flying methods (e.g., Flapping like a bird, Jet Engine powered, and Warp Speed).&lt;/p&gt;
&lt;h4 id="step-1-define-the-strategy-interface"&gt;Step 1: Define the Strategy Interface&lt;a class="anchor ms-1" href="#step-1-define-the-strategy-interface" aria-label="Permalink: Step 1: Define the Strategy Interface"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;First, we define an interface that all payment strategies will implement.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;interface&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;IFlyingStrategy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; Fly();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-2-implement-concrete-strategies"&gt;Step 2: Implement Concrete Strategies&lt;a class="anchor ms-1" href="#step-2-implement-concrete-strategies" aria-label="Permalink: Step 2: Implement Concrete Strategies"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Next, we create concrete classes that implement the IPaymentStrategy interface.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Bird&lt;/span&gt; : IFlyingStrategy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; Fly()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Console.WriteLine(&lt;span style="color:#e6db74"&gt;&amp;#34;Flying like a bird&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Plane&lt;/span&gt; : IFlyingStrategy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; Fly()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Console.WriteLine(&lt;span style="color:#e6db74"&gt;&amp;#34;Flying using 21st century aviation fuel&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;StarShip&lt;/span&gt; : IFlyingStrategy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; Fly()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Console.WriteLine(&lt;span style="color:#e6db74"&gt;&amp;#34;Flying using warp engines&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-3-create-the-context-class"&gt;Step 3: Create the Context Class&lt;a class="anchor ms-1" href="#step-3-create-the-context-class" aria-label="Permalink: Step 3: Create the Context Class"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The context class uses a IFlyingStrategy to perform the payment.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;FlyContext&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; IFlyingStrategy _flyingStrategy;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; SetPaymentStrategy(IFlyingStrategy flyingStrategy)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; _flyingStrategy = flyingStrategy;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; Fly()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; _flyingStrategy.Fly();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="step-4-use-the-strategy-pattern"&gt;Step 4: Use the Strategy Pattern&lt;a class="anchor ms-1" href="#step-4-use-the-strategy-pattern" aria-label="Permalink: Step 4: Use the Strategy Pattern"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Finally, we use the FlyContext to fly with different strategies.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Program&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; Main(&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;[] args)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; FlyContext context = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; FlyContext();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; context.SetPaymentStrategy(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; StarShip());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; context.Fly();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; context.SetPaymentStrategy(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Plane());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; context.Fly();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; context.SetPaymentStrategy(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Bird());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; context.Fly();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="conclusion"&gt;Conclusion&lt;a class="anchor ms-1" href="#conclusion" aria-label="Permalink: Conclusion"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The Strategy Design Pattern is a powerful tool that promotes flexibility, reusability, and maintainability in your code. By encapsulating algorithms and making them interchangeable, you can easily extend and modify your application without disrupting existing functionality. Whether you’re dealing with payment processing, flying machines, sorting algorithms, or any other scenario requiring dynamic behaviour, the Strategy Design Pattern can help you write cleaner and more efficient code.&lt;/p&gt;</description></item><item><title>How to start a code club for kids</title><link>https://blog-test.funkysi1701.com/posts/2024/codeclub/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Sat, 02 Nov 2024 18:00:45 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2024/codeclub/</guid><category term="youth">youth</category><category term="codeclub">codeclub</category><category term="Community">Community</category><media:content medium="image" type="image/jpeg" url="https://blog-test.funkysi1701.com/images/Pnb-NvNJ_400x400.jpg"/><description>&lt;p&gt;Code Clubs are free, welcoming spaces designed to introduce young people to the exciting world of programming and digital skills. Today, I had the pleasure of taking my son—an absolute coding enthusiast—to one of these sessions, held at Leeds Central Library.&lt;/p&gt;
&lt;p&gt;The club was hosted in a cozy room on the top floor of the library. Walking in, I expected rows of computers set up for traditional coding exercises. Instead, we found mysterious white lines taped onto the floor. Curious to find out what they were for, we soon learned they were meant to guide robots that the children would be programming. The instructor handed out iPads and small spherical robots known as Spheros, and the children were tasked with programming the robots to follow the lines.&lt;/p&gt;
&lt;p&gt;The iPads were preloaded with easy-to-use software that felt familiar to those who&amp;rsquo;ve used Scratch, a popular block-based coding language. By simply dragging and dropping blocks of code, the kids controlled the robots’ movements. Each &amp;ldquo;move&amp;rdquo; block had three variables—direction, speed, and duration—that the children could adjust to guide the robot along the lines.&lt;/p&gt;
&lt;p&gt;It was a great hands-on learning experience. My son and I faced a bit of trial and error to figure out which way the robot saw as &amp;ldquo;forward,&amp;rdquo; but soon enough, our Sphero was gliding smoothly along the first line. As we went along, we added &amp;ldquo;pause&amp;rdquo; blocks between movements, which made the robot stop before changing direction, adding a nice rhythm to its journey along the lines.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Children programming Sphero robots to follow taped lines on the floor at Leeds Central Library Code Club" src="https://blog-test.funkysi1701.com/images/20241102_104220.jpg" loading="lazy"
width="854" height="384"
/&gt;
&lt;/p&gt;
&lt;p&gt;Once the main task was completed, there was time for the kids to explore other features. We experimented with different commands, making a smile or frown appear on the robot’s LED display, while others programmed their Spheros to zip around the room, flashing lights and making playful noises.&lt;/p&gt;
&lt;p&gt;The club meets every two weeks, and both my son and I left feeling thrilled with the experience. We’re already looking forward to the next session!&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re interested in finding a Code Club near you check out &lt;a href="https://codeclub.org/en/find" target="_blank" rel="noopener noreferrer"&gt;https://codeclub.org/en/find&lt;/a&gt;
, alternatively, &lt;a href="https://codeclub.org" target="_blank" rel="noopener noreferrer"&gt;https://codeclub.org&lt;/a&gt;
has lots of resources to explain what code clubs are all about.&lt;/p&gt;</description></item><item><title>Scottish Summit 2024</title><link>https://blog-test.funkysi1701.com/posts/2024/scottishsummit/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 28 Oct 2024 18:00:45 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2024/scottishsummit/</guid><category term="Conference">Conference</category><category term="Microsoft">Microsoft</category><category term="Community">Community</category><media:content medium="image" type="image/jpeg" url="https://blog-test.funkysi1701.com/images/scottishsummit.jpg"/><description>&lt;p&gt;Scottish Summit 2024 took place in Aberdeen on October 18th and 19th at the P&amp;amp;J Live Arena, and I was fortunate enough to attend.&lt;/p&gt;
&lt;h2 id="friday"&gt;Friday&lt;a class="anchor ms-1" href="#friday" aria-label="Permalink: Friday"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The first full day of the conference, Friday the 18th, began with the unmistakable sound of bagpipers welcoming attendees at the venue—an echo of the 2022 event that reminded us all of the conference&amp;rsquo;s Scottish roots. Registration was quick and seamless; all I needed was my QR code ticket to receive a unique lanyard made of seed paper—perfect for planting flowers in the spring.&lt;/p&gt;
&lt;p&gt;Scott Hanselman was the keynote speaker, and I spotted him mingling with other attendees. I almost asked him for a selfie but decided against it. His keynote, titled &amp;ldquo;AI: Hero or Villain,&amp;rdquo; was compelling. He demystified ChatGPT, explaining that it’s not magic but rather a product of machine learning, using mathematics to predict the next word in a sentence.&lt;/p&gt;
&lt;p&gt;Next, MVP Vesa Nopanen delivered his talk on &amp;ldquo;Supercharge Your Teams Meetings.&amp;rdquo; I picked up some valuable tips, particularly the importance of adding notes and agendas to enhance meeting effectiveness.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog-test.funkysi1701.com/images/GaKpRZ3WIAAFsIW.jpg" style="padding-right: 7px; float: left; margin-bottom: 0.5rem;" alt="Scottish Summit organizers presenting how they built event registration and payments with Stripe and Power Platform" /&gt; Following that, a couple of the Scottish Summit organizers discussed the technology behind the event. They explained how they used Stripe for payments, integrating it with Power Automate and Power Pages. I found this particularly interesting for a charity event; it demonstrated a commitment to learning while keeping costs manageable.&lt;/p&gt;
&lt;p&gt;The next session explored what it means to be a modern full-stack software developer, focusing on integrating Power Apps with traditional web development. As someone new to Power Apps, I learned that starting with it can be beneficial, filling gaps with .NET or conventional web development as needed.&lt;/p&gt;
&lt;p&gt;I then attended a session on public speaking. Although I’ve never given a talk at a conference, hearing about others&amp;rsquo; journeys was encouraging and prompted me to consider my own potential in this area.&lt;/p&gt;
&lt;p&gt;The final session of Friday featured Microsoft’s Sarah Lean, who shared how her hobbies—specifically curling—have influenced her work life. This talk made me reflect on my own hobbies and their impact on my professional journey.&lt;/p&gt;
&lt;p&gt;The evening wrapped up with a drag cabaret, which exceeded my expectations. Several brave community members dressed up and participated in the show, all in support of the conference&amp;rsquo;s charity, TIE.&lt;/p&gt;
&lt;h2 id="saturday"&gt;Saturday&lt;a class="anchor ms-1" href="#saturday" aria-label="Permalink: Saturday"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Saturday kicked off with a dive into the world of wizards and D&amp;amp;D in a session titled &amp;ldquo;Securing the Realm: DM-less D&amp;amp;D with Azure AI.&amp;rdquo; This practical talk demonstrated how AI can be utilized in running D&amp;amp;D games, discussing essential guardrails and effective AI prompts.&lt;/p&gt;
&lt;p&gt;Another engaging talk, &amp;ldquo;Community - It Just Makes Sense,&amp;rdquo; highlighted the tech community&amp;rsquo;s role in career development. I realized that I’ve only just scratched the surface of community involvement, and I’m eager to explore it further.&lt;/p&gt;
&lt;img src="https://blog-test.funkysi1701.com/images/GaP4xTOW0AA6VHI.jpg" style="padding-left: 7px; float: right; margin-bottom: 0.5rem;" alt="Speaker presenting at Scottish Summit 2024" /&gt;
&lt;p&gt;Sarah Lean returned to discuss KQL (Kusto Query Language), which Application Insights uses for querying data. Although I&amp;rsquo;ve encountered KQL before, learning more about it was fascinating.&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;Ask the Azure Experts&amp;rdquo; panel featured four Azure MVPs and Sarah Lean, who answered questions about Azure migration and cost management, sharing numerous helpful insights.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Who&amp;rsquo;s Afraid of a Little Ole Copilot?&amp;rdquo; presented by Dona Sarkar and her colleagues, was a captivating exploration of how Copilots function within the Microsoft ecosystem. It featured various speakers I had encountered throughout the conference, demonstrating the interactivity of Microsoft’s services, from Purview to Responsible AI. It was a fun and enlightening way to close the conference.&lt;/p&gt;
&lt;p&gt;Saturday evening featured a pub quiz and the UK Community Awards ceremony, where dedicated community members were recognized for their hard work. Our quiz team, led by MVP Vesa Nopanen and humorously named &amp;ldquo;Vogon Poets,&amp;rdquo; finished 14th—complete with silly hats. It was a delightful opportunity to socialize with teammates and was one of the highlights of the conference.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;a class="anchor ms-1" href="#conclusion" aria-label="Permalink: Conclusion"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In summary, Scottish Summit 2024 was an exceptionally well-organized conference. As a .NET developer, I found a limited number of directly relevant sessions, but the true value lay in the community. I reconnected with familiar faces and met new friends, especially during the pub quiz.&lt;/p&gt;
&lt;p&gt;I left feeling inspired to become more involved in the community and participate in future events. The sessions on public speaking, community engagement, and hobbies underscored the importance of soft skills in the tech world.&lt;/p&gt;
&lt;p&gt;And yes, I caught a glimpse of Scott Hanselman, which was quite a thrill!&lt;/p&gt;
&lt;img src="https://blog-test.funkysi1701.com/images/GaKSNJeXwAA-xyr.jpg" style="padding-right: 7px; float: left; margin-bottom: 0.5rem;" alt="Scott Hanselman at Scottish Summit 2024" /&gt;</description></item><item><title>Funky Si walks a half marathon</title><link>https://blog-test.funkysi1701.com/posts/2024/charity-hike/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Sun, 18 Feb 2024 11:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2024/charity-hike/</guid><media:content medium="image" type="image/jpeg" url="https://blog-test.funkysi1701.com/images/fsi-hike.jpg"/><description>&lt;p&gt;On June 8th I will walk 13 miles near Bakewell in the Peak District to raise £250 (or more) for Cancer Research. To sponsor me click &lt;a href="https://fundraise.cancerresearchuk.org/page/funkysi1701" target="_blank" rel="noopener noreferrer"&gt;fundraise.cancerresearchuk.org/page/funkysi1701&lt;/a&gt;
, to find out more about the event go &lt;a href="https://www.cancerresearchuk.org/get-involved/find-an-event/big-hike/big-hike-peak-district" target="_blank" rel="noopener noreferrer"&gt;www.cancerresearchuk.org/get-involved/find-an-event/big-hike/big-hike-peak-district&lt;/a&gt;
&lt;/p&gt;
&lt;h2 id="so-why-am-i-doing-this"&gt;So why am I doing this?&lt;a class="anchor ms-1" href="#so-why-am-i-doing-this" aria-label="Permalink: So why am I doing this?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;img src="https://blog-test.funkysi1701.com/images/fsi-hike-route.png" alt="Hike Route" width="400px" style="float:left;padding-right:8px" /&gt;
I am a Software Developer in my day to day life, which does not involve a lot of physical activity. I have become very lazy. Doing a half marathon is completely outside of my comfort zone and is not at all a me thing to do.
&lt;p&gt;However last year I realised my mental health was starting to degrade. I have a family which keeps me very busy, I am facing lots of challenges with this, other members of my family have mental health issues which is starting to have a knock on affect on me.&lt;/p&gt;
&lt;p&gt;I mentioned some of these challenges to a friend who suggested I join a walking group which was helping people with mental health problems. I went along and to my surprise I really enjoyed myself, the people were friendly and I enjoyed the walk in the countryside. After this I went out and bought some proper walking shoes&lt;/p&gt;
&lt;p&gt;I went to the next one, and the next one and each time I enjoyed myself. I must admit that after these walks it tired me out due to my unfit nature, but it was worth it as for a few hours I wasn&amp;rsquo;t thinking about the 101 problems that I had no solutions for.&lt;/p&gt;
&lt;p&gt;Fast forward to about a week ago, an advert for this charity walk popped up on facebook. I took a look at it and I started thinking. The 10k was a similar distance I had done on one of my walks, so I could easily do that. What if I could raise some money for a charity and go for a fun walk? For the next few days I kept thinking about it. Eventually I booked it. My thinking was if I am going to do something for charity I need to push myself outside of my comfort zone. I would never manage a full marathon, but what about a half marathon?&lt;/p&gt;
&lt;p&gt;So tomorrow I start training, every day or so I walk for about 40 minutes, I will probably post some updates on my &lt;a href="https://fundraise.cancerresearchuk.org/page/funkysi1701" target="_blank" rel="noopener noreferrer"&gt;charity page&lt;/a&gt;
as no doubt I will struggle to keep going.&lt;/p&gt;
&lt;p&gt;Please if you can think about donating, and give me some encouragement I think I am going to need it.&lt;/p&gt;</description></item><item><title>TrekRanks #174</title><link>https://blog-test.funkysi1701.com/posts/2024/trekranks/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Fri, 05 Jan 2024 20:00:00 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2024/trekranks/</guid><category term="StarTrek">StarTrek</category><category term="Podcast">Podcast</category><category term="TrekRanks">TrekRanks</category><media:content medium="image" type="image/jpeg" url="https://blog-test.funkysi1701.com/images/TrekRanks-ep174.jpg"/><description>&lt;h2 id="trek-ranks-174-top-5-ensemble-episodes"&gt;Trek Ranks #174: Top 5 Ensemble Episodes&lt;a class="anchor ms-1" href="#trek-ranks-174-top-5-ensemble-episodes" aria-label="Permalink: Trek Ranks #174: Top 5 Ensemble Episodes"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I was recently invited onto the &lt;a href="https://www.trekranks.com/" target="_blank" rel="noopener noreferrer"&gt;TrekRanks&lt;/a&gt;
podcast. I had a great time talking Trek with Jim Moorhouse and fellow guest Anika Dane. If Trek is your thing, do take a listen.&lt;/p&gt;
&lt;p&gt;Everyone contributes in this episode of TrekRanks as we break down the &amp;ldquo;Top 5 Ensemble Episodes.&amp;rdquo; Our panel highlight those episodes in which the entire cast play important roles and help portray the group as a whole, rather than as individuals. From heavy hitters to deep cuts and everything in between, this one quite appropriately covers it all.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.thetricordertransmissions.com/episode.php?ep=TR174" target="_blank" rel="noopener noreferrer"&gt;Listen here&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="TrekRanks episode 174 artwork for Top 5 Ensemble Episodes with Jim Moorhouse, Anika Dane and Simon Foster" src="https://blog-test.funkysi1701.com/images/TrekRanks-ep174.jpg" loading="lazy"
width="1920" height="1080"
/&gt;
&lt;/p&gt;</description></item></channel></rss>