<?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>2022 on Funky Si's Blog (Dev)</title><link>https://blog-dev.funkysi1701.com/2022/</link><description>Recent content in 2022 on Funky Si's Blog (Dev)</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>Sat, 31 Dec 2022 22:00:00 +0000</lastBuildDate><atom:link href="https://blog-dev.funkysi1701.com/2022/index.xml" rel="self" type="application/rss+xml"/><item><title>2022 What Happened?</title><link>https://blog-dev.funkysi1701.com/posts/2022/2022-what-happened/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Sat, 31 Dec 2022 22:00:00 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/2022-what-happened/</guid><category term="Goals">Goals</category><media:content medium="image" type="image/jpeg" url="https://blog-dev.funkysi1701.com/images/goals.jpeg"/><description>&lt;p&gt;As 2022 draws to a close its time to do my annual look back at what happened.&lt;/p&gt;
&lt;p&gt;I am going to talk a bit about my personal life as well as tech things, so if that is not your bag feel free to skip this post and read my more technical articles.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;January - I started the year &lt;a href="https://www.funkysi1701.com/posts/2021/back-to-basic/" target="_blank" rel="noopener noreferrer"&gt;teaching my son to code&lt;/a&gt;
.&lt;/li&gt;
&lt;li&gt;February - I did some work on my website this year, and it is now using Hugo instead of wordpress.&lt;/li&gt;
&lt;li&gt;March - I was guest on a Star Trek &lt;a href="https://www.funkysi1701.com/posts/2022/temporal-trek-podcast/" target="_blank" rel="noopener noreferrer"&gt;podcast&lt;/a&gt;
, hopefully a repeat appearance in the works very soon. I also passed an &lt;a href="https://www.funkysi1701.com/posts/2022/aws-cloud-practitioner/" target="_blank" rel="noopener noreferrer"&gt;AWS exam&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;April - Lots of work with &lt;a href="https://www.funkysi1701.com/posts/2022/scratch/" target="_blank" rel="noopener noreferrer"&gt;Scratch&lt;/a&gt;
with my boy&lt;/li&gt;
&lt;li&gt;June - &lt;a href="https://www.funkysi1701.com/posts/2022/scottishsummit/" target="_blank" rel="noopener noreferrer"&gt;Scottish Summit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;August - My boys birthday so some coding activities with his &lt;a href="https://www.funkysi1701.com/posts/2022/microbit/" target="_blank" rel="noopener noreferrer"&gt;Microbit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;October - I bought a second hand car and less than a week later it burst into flames, a scary event but no one hurt and everything has since been replaced/repaired.&lt;/li&gt;
&lt;li&gt;November - I lost my job&lt;/li&gt;
&lt;li&gt;December - Extended time with family for Christmas with a new job starting in January. I sat and narrowly missed passing AZ-204 (Developing Solutions for Azure). I attended &lt;a href="https://www.funkysi1701.com/posts/2022/ddd-north/" target="_blank" rel="noopener noreferrer"&gt;DDD North&lt;/a&gt;
, I attended LeedsSharp and went on a virtual tour of a Microsoft Datacenter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don&amp;rsquo;t know what is in store for 2023 but I am sure it will be equally interesting. The first thing to get my head around is my new job.&lt;/p&gt;
&lt;p&gt;So onto my goals for 2023&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;New job and get my head around all the new stuff I need to learn&lt;/li&gt;
&lt;li&gt;Celebrate 10 years of marriage and concentrate on family things&lt;/li&gt;
&lt;li&gt;Pass AZ-204 - It was such a close miss that I need to retry this&lt;/li&gt;
&lt;li&gt;More coding with my son, he got a laptop for Christmas and would be great to build on what he has learnt so far.&lt;/li&gt;
&lt;li&gt;Blog regularly - I doubled the number of blog posts from 2021, but it would be great to keep up the momentum with regular posts of what I am up to.&lt;/li&gt;
&lt;li&gt;I recently added an events page, so I need to go to some events. Events like DDD North and Scottish Summit are great, but so are local user groups so a mix of these would be great.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Last year I had the following &lt;a href="https://www.funkysi1701.com/posts/2022/2022-goals/" target="_blank" rel="noopener noreferrer"&gt;goals&lt;/a&gt;
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Video - Not used my green screen yet, would be good to make some time to use this in 2023&lt;/li&gt;
&lt;li&gt;Conference - I attended Scottish Summit and DDD North, would be great to go to more like these this year as well&lt;/li&gt;
&lt;li&gt;Blog More - Yeah I achieved this, but lets keep doing this.&lt;/li&gt;
&lt;li&gt;Metrics - I have done little bits with this over the last year, but not a huge amount.&lt;/li&gt;
&lt;li&gt;My personal brand has improved this year as my blog relaunched on the Hugo platform, and I am very happy with its look, probably more I can do.&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>DDD North</title><link>https://blog-dev.funkysi1701.com/posts/2022/ddd-north/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 05 Dec 2022 18:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/ddd-north/</guid><category term="DotNet">DotNet</category><category term="Azure">Azure</category><category term="Community">Community</category><category term="Conference">Conference</category><category term="DDDNorth">DDDNorth</category><media:content medium="image" type="image/jpeg" url="https://blog-dev.funkysi1701.com/images/dddnorth-hull-developers-conference-2022.jpg"/><description>&lt;p&gt;On Saturday 3rd December I attended &lt;a href="https://www.dddnorth.co.uk/" target="_blank" rel="noopener noreferrer"&gt;DDD North&lt;/a&gt;
. It is a community run conference for Developers (the D&amp;rsquo;s stand for Developer) and I had a fab time there. Many conferences are going online which is great, however there is nothing quite like chatting over coffee or lunch with fellow Developers about the tech you are learning about, this was probably my favourite thing about the conference.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="DDD North" src="https://blog-dev.funkysi1701.com/images/dddnorth-hull-developers-conference-2022.jpg" loading="lazy"
width="800" height="600"
/&gt;
&lt;/p&gt;
&lt;p&gt;The first talk I attended was &amp;lsquo;.Net Minimal APIs&amp;rsquo; by &lt;a href="https://twitter.com/kev_bite" target="_blank" rel="noopener noreferrer"&gt;Kevin Smith&lt;/a&gt;
. Kevin runs .Net user groups in York and Sheffield so I have heard him speak before. He went through some of the features of minimal APIs. I have briefly experimented with them in .Net 6, however from the sound of things the tech is much improved in .Net 7, with lots of improvements, so this is something I want to give another try.&lt;/p&gt;
&lt;p&gt;During the coffee break I managed to have a quick conversation with &lt;a href="https://www.youtube.com/c/Elfocrash" target="_blank" rel="noopener noreferrer"&gt;Nick Chapsas&lt;/a&gt;
. Nick has a YouTube channel that my colleagues at work have been sharing during our weekly knowledge share sessions. It was great to chat with someone that I have been watching on YouTube.&lt;/p&gt;
&lt;p&gt;The second talk was &amp;lsquo;When microservices go bad&amp;rsquo; by &lt;a href="https://twitter.com/TechyChap" target="_blank" rel="noopener noreferrer"&gt;Andy Clark&lt;/a&gt;
. This talk was a discussion of the different ways you can use &lt;a href="https://github.com/App-vNext/Polly" target="_blank" rel="noopener noreferrer"&gt;Polly&lt;/a&gt;
, Carl Franklin of .NetRocks fame has mentioned Polly a few times on the show, so this was a good talk to explain the different ways it can be used.&lt;/p&gt;
&lt;p&gt;The third talk was &amp;lsquo;Don&amp;rsquo;t put your messages in a bottle; Implement messaging patterns&amp;rsquo; by &lt;a href="https://twitter.com/egrootenboer" target="_blank" rel="noopener noreferrer"&gt;Eldert Grootenboer&lt;/a&gt;
, he should have been joined by &lt;a href="https://twitter.com/borzenko_lena" target="_blank" rel="noopener noreferrer"&gt;Olena Borzenko&lt;/a&gt;
however she was unable to travel (didn&amp;rsquo;t catch exactly why, I think she was from Ukraine or working in Ukraine and Visa&amp;rsquo;s from that part of the world are a problem at the moment). This was a talk all about message queues and the patterns and practises you should implement. I don&amp;rsquo;t know much about queues, having only recently started using AWS SQS messages recently so this was useful to put that work into context. The slides from this talk are available &lt;a href="https://eldertnet-my.sharepoint.com/:p:/g/personal/eldert_eldert_net/EXbVxQpSzzNJmtvKNPjzSvYBSGfnLI7qC5U5Ia-PYCqioA?rtime=fIdK6wHX2kg" target="_blank" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Lunch was next and the food was excellent. I found myself sitting with Jamie Taylor (from the Tabs and Spaces podcast), &lt;a href="https://twitter.com/YorkshireTechy" target="_blank" rel="noopener noreferrer"&gt;Craig Pickles&lt;/a&gt;
, &lt;a href="https://twitter.com/chris_sainty" target="_blank" rel="noopener noreferrer"&gt;Chris Sainty&lt;/a&gt;
and a few others. There was a fascinating discussion on Blazor, .Net and how Microsoft introduces new stuff. Really appreciate being able to listen in on such an interesting discussion.&lt;/p&gt;
&lt;p&gt;The fourth talk was &amp;lsquo;Why don&amp;rsquo;t people seem to be able to diagnose problems these days?&amp;rsquo; by &lt;a href="https://twitter.com/richardfennell" target="_blank" rel="noopener noreferrer"&gt;Richard Fennell&lt;/a&gt;
. This was a fascinating walk through computer history and the challenges of finding where the problem is. The slides from this talk are available &lt;a href="https://github.com/rfennell/Presentations/blob/main/Why%20don%27t%20people%20seem%20to%20be%20able%20to%20diagnose%20problems%20these%20days.pptx" target="_blank" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;The last talk was &amp;lsquo;Empathy, Sympathy, and Compassion&amp;rsquo; by &lt;a href="https://twitter.com/podcasterJay" target="_blank" rel="noopener noreferrer"&gt;Jamie Taylor&lt;/a&gt;
who I had met at lunch. This was a fascinating look at how we place barriers between ourselves as Developers and the users of the software. It expanded into ethics, code of conduct and doing good.&lt;/p&gt;
&lt;p&gt;It was a great event so thank you &lt;a href="https://twitter.com/dddnorth" target="_blank" rel="noopener noreferrer"&gt;DDD North&lt;/a&gt;
for all your hard work, I look forward to the next one. I have lots to go away and think about.&lt;/p&gt;</description></item><item><title>Expiring Azure AD Client Secrets</title><link>https://blog-dev.funkysi1701.com/posts/2022/expiring-azuread-client-secrets/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Tue, 18 Oct 2022 18:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/expiring-azuread-client-secrets/</guid><category term="DotNet">DotNet</category><category term="Azure">Azure</category><category term="ActiveDirectory">ActiveDirectory</category><category term="Secret">Secret</category><media:content medium="image" type="image/png" url="https://blog-dev.funkysi1701.com/images/AzureADSecret.png"/><description>&lt;p&gt;This morning the client complains that the website is not working. I do some checking and I confirm that there is indeed an error.&lt;/p&gt;
&lt;p&gt;The error they are seeing is:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;An unhandled exception occurred while processing the request.
MsalServiceException: A configuration issue is preventing authentication
- check the error message from the server for details.
You can modify the configuration in the application registration portal.
See https://aka.ms/msal-net-invalid-client for details.
Original exception: AADSTS7000222: The provided client secret keys for
app &amp;#39;00000000-0000-0000-0000-000000000000&amp;#39; are expired.
Visit the Azure portal to create new keys for your app: https://aka.ms/NewClientSecret,
or consider using certificate credentials for added security: https://aka.ms/certCreds.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The fix for this is relatively simple, generate a new client secret in Azure AD and update the website config to make use of it.&lt;/p&gt;
&lt;p&gt;The problem is that this problem will reoccur in 3, 6, 12, 18 or 24 months, depending on what expiry date you set on the secret.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Add a client secret" src="https://blog-dev.funkysi1701.com/images/AzureADSecret.png" loading="lazy"
width="572" height="350"
/&gt;
&lt;/p&gt;
&lt;p&gt;A suggestion from twitter is that Logic Apps and Event Grid might help solve this problem. Lets see how this might work.&lt;/p&gt;
&lt;p&gt;Logic Apps have a consumption plan, so this kind of solution shouldn&amp;rsquo;t break the bank as will only cost per run eg daily/weekly etc&lt;/p&gt;
&lt;p&gt;But first here is a powershell script that lists all the secrets that are due to expire in the next 30 days.&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:#75715e"&gt;#secret expiration date filter (for example 30 days)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$LimitExpirationDays = &lt;span style="color:#ae81ff"&gt;30&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;#Retrieving the list of secrets that expires in the above range of days&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$SecretsToExpire = Get-AzureADApplication -All:$true | ForEach-Object {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $app = $_
&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; Get-AzureADApplicationPasswordCredential -ObjectId $_.ObjectId
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Get-AzureADApplicationKeyCredential -ObjectId $_.ObjectId
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ) | Where-Object {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $_.EndDate &lt;span style="color:#f92672"&gt;-lt&lt;/span&gt; (Get-Date).AddDays($LimitExpirationDays)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } | ForEach-Object {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $id = &lt;span style="color:#e6db74"&gt;&amp;#34;Not set&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;if&lt;/span&gt;($_.CustomKeyIdentifier) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $id = [&lt;span style="color:#66d9ef"&gt;System.Text.Encoding&lt;/span&gt;]::UTF8.GetString($_.CustomKeyIdentifier)
&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;PSCustomObject&lt;/span&gt;] @{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; App = $app.DisplayName
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ObjectID = $app.ObjectId
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; AppId = $app.AppId
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Type = $_.GetType().name
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KeyIdentifier = $id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; EndDate = $_.EndDate
&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&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#Printing the list of secrets that are near to expire&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;($SecretsToExpire.Count &lt;span style="color:#f92672"&gt;-EQ&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;No secrets found that will expire in this range&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;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;Secrets that will expire in this range:&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Write-Output $SecretsToExpire.Count
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Write-Output $SecretsToExpire
&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;This works quite well, but I have to manually run it every so often. I have not found a way to automate this as I don&amp;rsquo;t know how to get past the MFA that is configured on my Azure AD tenant.&lt;/p&gt;
&lt;p&gt;Now lets look at how a Logic App might help us. First of all we need somewhere to query the expiry dates, and Azure Key Vault is the ideal place to store them.&lt;/p&gt;
&lt;p&gt;Create a Key Vault if you don&amp;rsquo;t already have one and add a new Secret. Manually add the Client Secret from Azure AD and give it a name you can identify it with. Tick the Set expiration date and save the expiry date of your secret.&lt;/p&gt;
&lt;p&gt;Now Create a Logic App, I am going to use Consumption, so it only costs you when it runs.&lt;/p&gt;
&lt;p&gt;Using the Logic Apps Designer, start with a Recurrence trigger. This lets you queue up your logic app on a schedule, I&amp;rsquo;ve set mine to run every 30 days.&lt;/p&gt;
&lt;p&gt;Next run a Get Secret command from your Key Vault. Select the identifying name you saved the secret with earlier. This will retrieve the secret from the Key Vault, if you go into the settings you can hide the output as you are only really interested in the expiry date.&lt;/p&gt;
&lt;p&gt;I am doing a low tech solution for now, and just emailing myself the expiry date. It is easy to add the expiry date of the secret to an email.&lt;/p&gt;
&lt;p&gt;Later on I might add a bit more logic to only email myself when the expiry is less than 30 days, a reminder to create a new secret. When creating a new secret in Azure AD, I also need to add the secret and expiry date into Key Vault.&lt;/p&gt;
&lt;p&gt;At the very least this solution will give me an early warning of when my secrets are about to expire. It is possible to get my website to read information from Key Vault directly which I may well investigate.&lt;/p&gt;</description></item><item><title>Upgrading to .Net 7</title><link>https://blog-dev.funkysi1701.com/posts/2022/dotnet7/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Sat, 01 Oct 2022 18:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/dotnet7/</guid><category term="DotNet">DotNet</category><category term="Blazor">Blazor</category><category term="EFCore">EFCore</category><media:content medium="image" type="image/png" url="https://blog-dev.funkysi1701.com/images/coverage.png"/><description>&lt;p&gt;I have a Blazor application that was built with .Net Core 3, and I have updated it to .Net 5 and later .Net 6 when those versions of were released. In November .Net 7 is released so I have been testing it with the .Net 7 previews.&lt;/p&gt;
&lt;p&gt;However for this update I encountered a few more issues than I remember from the other updates.&lt;/p&gt;
&lt;h2 id="automapper"&gt;Automapper&lt;a class="anchor ms-1" href="#automapper" aria-label="Permalink: Automapper"&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 issue I encountered was with Automapper. My Unit tests failed with the following error&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Error Message:
System.ArgumentException : GenericArguments[0], &amp;#39;System.Char&amp;#39;, on &amp;#39;T MaxFloat[T](System.Collections.Generic.IEnumerable`1[T])&amp;#39; violates the constraint of type &amp;#39;T&amp;#39;.
---- System.Security.VerificationException : Method System.Linq.Enumerable.MaxFloat: type argument &amp;#39;System.Char&amp;#39; violates the constraint of type parameter &amp;#39;T&amp;#39;.
Stack Trace:
at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)
at AutoMapper.Internal.TypeDetails.&amp;lt;&amp;gt;c__DisplayClass25_1.&amp;lt;GetPublicNoArgExtensionMethods&amp;gt;b__10(MethodInfo extensionMethod)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
at System.Linq.Enumerable.SelectManyIterator[TSource,TCollection,TResult](IEnumerable`1 source, Func`2 collectionSelector, Func`3 resultSelector)+MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.UnionIterator`1.GetNext()
at System.Linq.Enumerable.UnionIterator`1.MoveNext()
at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
at AutoMapper.Internal.TypeDetails.PossibleNames()
at AutoMapper.Internal.TypeDetails.GetMember(String name)
at AutoMapper.Configuration.Conventions.DefaultName.GetMatchingMemberInfo(TypeDetails sourceTypeDetails, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Configuration.Conventions.ParentSourceToDestinationNameMapper.GetMatchingMemberInfo(TypeDetails sourceTypeDetails, Type destType, Type destMemberType, String nameToSearch)
at AutoMapper.Configuration.Conventions.DefaultMember.MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceTypeDetails, Type destType, Type destMemberType, String nameToSearch, List`1 resolvers, IMemberConfiguration parent, Boolean isReverseMap)
at AutoMapper.Configuration.Conventions.MemberConfiguration.MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceType, Type destType, Type destMemberType, String nameToSearch, List`1 resolvers, Boolean isReverseMap)
at AutoMapper.Configuration.Conventions.NameSplitMember.MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceType, Type destType, Type destMemberType, String nameToSearch, List`1 resolvers, IMemberConfiguration parent, Boolean isReverseMap)
at AutoMapper.Configuration.Conventions.MemberConfiguration.MapDestinationPropertyToSource(ProfileMap options, TypeDetails sourceType, Type destType, Type destMemberType, String nameToSearch, List`1 resolvers, Boolean isReverseMap)
at AutoMapper.ProfileMap.MapDestinationPropertyToSource(TypeDetails sourceTypeDetails, Type destType, Type destMemberType, String destMemberName, List`1 members, Boolean reverseNamingConventions)
at AutoMapper.TypeMap..ctor(Type sourceType, Type destinationType, ProfileMap profile, Boolean isReverseMap)
at AutoMapper.ProfileMap.BuildTypeMap(IGlobalConfiguration configurationProvider, ITypeMapConfiguration config)
at AutoMapper.ProfileMap.Register(IGlobalConfiguration configurationProvider)
at AutoMapper.MapperConfiguration.Seal()
at AutoMapper.MapperConfiguration..ctor(MapperConfigurationExpression configurationExpression)
at AutoMapper.MapperConfiguration..ctor(Action`1 configure)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)
----- Inner Stack Trace -----
at System.RuntimeMethodHandle.GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[] methodInstantiation)
at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At first I didn&amp;rsquo;t realise it was an issue with Automapper and I started searching for breaking changes in dotnet 7. Eventually this lead to finding that a change to .Net had created an issue with version 11 of Automapper. The following github issues explains more about what was involved in fixing this.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/dotnet/runtime/issues/69119" target="_blank" rel="noopener noreferrer"&gt;https://github.com/dotnet/runtime/issues/69119&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/AutoMapper/AutoMapper/pull/3999" target="_blank" rel="noopener noreferrer"&gt;https://github.com/AutoMapper/AutoMapper/pull/3999&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;This week &lt;a href="https://github.com/AutoMapper/AutoMapper/releases/tag/v12.0.0" target="_blank" rel="noopener noreferrer"&gt;version 12&lt;/a&gt;
of Automapper was released and it fixed this issue for me.&lt;/p&gt;
&lt;h2 id="code-coverage"&gt;Code Coverage&lt;a class="anchor ms-1" href="#code-coverage" aria-label="Permalink: Code Coverage"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My build includes the calculation of code coverage of my unit tests. For some reason this step was failing.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; - task: DotNetCoreCLI@2
displayName: &amp;#39;Running API Tests&amp;#39;
inputs:
command: &amp;#39;test&amp;#39;
arguments: &amp;#39;--no-restore --no-build --configuration $(buildConfiguration) --runtime win-x64 /p:CollectCoverage=true /p:CoverletOutputFormat=opencover&amp;#39;
projects: &amp;#39;Path To csproj file&amp;#39;
nobuild: true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For .Net 6 this step would run my unit tests and include a section that looked a bit like this.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Calculating coverage result...
Generating report &amp;#39;D:\a\1\s\WhatEver\coverage.opencover.xml&amp;#39;
+---------------------------+--------+--------+--------+
| Module | Line | Branch | Method |
+---------------------------+--------+--------+--------+
| Something | 50.91% | 48.77% | 65.44% |
+---------------------------+--------+--------+--------+
| Something.Core | 41.79% | 6.92% | 47.2% |
+---------------------------+--------+--------+--------+
| Something.Core.Email | 96.55% | 50% | 100% |
+---------------------------+--------+--------+--------+
+---------+--------+--------+--------+
| | Line | Branch | Method |
+---------+--------+--------+--------+
| Total | 49.46% | 44.2% | 53.55% |
+---------+--------+--------+--------+
| Average | 63.08% | 35.22% | 70.88% |
+---------+--------+--------+--------+
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;However for .Net 7 the unit tests would pass but the coverage bit above would not run, and no visible errors to help me.&lt;/p&gt;
&lt;p&gt;Testing dotnet test locally I discovered that if I included the path and filename to the csproj file the coverage would not run, if I removed this it would work as per .Net 6. No idea why this was happening.&lt;/p&gt;
&lt;p&gt;I did some testing with the DotNetCoreCLI@2 task, but I couldn&amp;rsquo;t get the coverage to work. However I was testing this locally via the command line so it was a simple thing to swap DotNetCoreCLI@2 for a command line step. After I did that the coverage started working again!&lt;/p&gt;
&lt;p&gt;Here is the command line step I added&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; - task: CmdLine@2
displayName: &amp;#39;Running API Tests&amp;#39;
inputs:
script: |
&amp;#34;C:\Program Files\dotnet\dotnet.exe&amp;#34; test --logger trx --results-directory D:\a\_temp --no-restore --no-build --configuration Release --runtime win-x64 /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
workingDirectory: &amp;#39;$(Build.SourcesDirectory)/PathToWhereEver&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="sql-server-tables-with-triggers"&gt;SQL Server tables with triggers&lt;a class="anchor ms-1" href="#sql-server-tables-with-triggers" aria-label="Permalink: SQL Server tables with triggers"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My build was all working so now time to test the application was working. But an error was being thrown if I tried to save any data to the SQL Server database.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Could not save changes because the target table has database triggers. Please configure your entity type accordingly, see https://aka.ms/efcore-docs-sqlserver-save-changes-and-triggers for more information. The target table &amp;#39;Something&amp;#39; of the DML statement cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO clause.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A nice error, as it gives me a link to the change and what to do to fix.&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;protected&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;override&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
&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; configurationBuilder.Conventions.Add(_ =&amp;gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; BlankTriggerAddingConvention());
&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;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;BlankTriggerAddingConvention&lt;/span&gt; : IModelFinalizingConvention
&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;virtual&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; ProcessModelFinalizing(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IConventionModelBuilder modelBuilder,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IConventionContext&amp;lt;IConventionModelBuilder&amp;gt; context)
&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;foreach&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; entityType &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; modelBuilder.Metadata.GetEntityTypes())
&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; table = StoreObjectIdentifier.Create(entityType, StoreObjectType.Table);
&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; (table != &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;amp;&amp;amp; entityType.GetDeclaredTriggers().All(t =&amp;gt; t.GetDatabaseName(table.Value) == &lt;span style="color:#66d9ef"&gt;null&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; entityType.Builder.HasTrigger(table.Value.Name + &lt;span style="color:#e6db74"&gt;&amp;#34;_Trigger&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:#66d9ef"&gt;foreach&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; fragment &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; entityType.GetMappingFragments(StoreObjectType.Table))
&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; (entityType.GetDeclaredTriggers().All(t =&amp;gt; t.GetDatabaseName(fragment.StoreObject) == &lt;span style="color:#66d9ef"&gt;null&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; entityType.Builder.HasTrigger(fragment.StoreObject.Name + &lt;span style="color:#e6db74"&gt;&amp;#34;_Trigger&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&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;Adding the following to my DBContext allowed data to be saved even if triggers existed on my database.&lt;/p&gt;
&lt;p&gt;A longer term fix, should be to investigate if the triggers on the database are still needed and remove if not. From reading the docs, it sounds like a performance gain would be had after doing this!&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;These are the issues I have encountered so far updating to .Net 7. A few more than for .Net 5 or 6. However so far I have managed to find a solution for all issues. I expect one more release candidate, with the final version of .Net 7 coming out in November.&lt;/p&gt;</description></item><item><title>MakeCode and the BBC micro:bit</title><link>https://blog-dev.funkysi1701.com/posts/2022/microbit/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Sun, 21 Aug 2022 18:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/microbit/</guid><category term="Scratch">Scratch</category><category term="kids">kids</category><category term="MakeCode">MakeCode</category><category term="Microbit">Microbit</category><media:content medium="image" type="image/png" url="https://blog-dev.funkysi1701.com/images/blocks.png"/><description>&lt;p&gt;Programming is in my DNA, so when I had children it was obvious that I would attempt to share my passion. It has taken a while, for some reason for loops don&amp;rsquo;t interest toddlers! However my 7 year old son has got a taste for it now.&lt;/p&gt;
&lt;img src="https://blog-dev.funkysi1701.com/images/getcoding.jpg" style="float:left; padding-right: 15px;" alt="Cover of the book Get Coding! for young programmers" /&gt;
&lt;p&gt;It was his birthday the other day and he got quite a few tech related things. First off he got some programming books. &lt;a href="https://www.amazon.co.uk/gp/product/1406366846/ref=ppx_yo_dt_b_asin_title_o02_s01?ie=UTF8&amp;amp;psc=1" target="_blank" rel="noopener noreferrer"&gt;Get Coding!&lt;/a&gt;
, &lt;a href="https://www.amazon.co.uk/gp/product/1641522453/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&amp;amp;psc=1" target="_blank" rel="noopener noreferrer"&gt;Coding for Kids: Scratch:&lt;/a&gt;
and &lt;a href="https://www.amazon.co.uk/gp/product/1641521759/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&amp;amp;psc=1" target="_blank" rel="noopener noreferrer"&gt;Coding for Kids: Python:&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;He has been reading an old Javascript book, so I wanted to get him something a bit more up to date, so the Get Coding book should give him the basics of creating webpages and doing things with Javascript. He has been also been playing with &lt;a href="https://blog-dev.funkysi1701.com/posts/2022/scratch/"&gt;Scratch&lt;/a&gt;
for a while so the second book will definitely interest him. He also keeps mentioning Python, which I know nothing about, so even if he never reads it, I have something new to learn!&lt;/p&gt;
&lt;p&gt;As well as the books he got a BBC micro:bit (with some accessories!) from his grandparents. He has been playing with &lt;a href="https://makecode.microbit.org/#" target="_blank" rel="noopener noreferrer"&gt;MakeCode&lt;/a&gt;
which features a simulator of a micro:bit, so I thought he might like having a physical device in his hands.&lt;/p&gt;
&lt;p&gt;He has loved playing with it so far, and I have loved working with him. Already we are at the point where he knows where to find some of the blocks he needs to write the programs, and is telling me I am looking in the wrong place!&lt;/p&gt;
&lt;p&gt;In case you are not familiar with MakeCode it is a block based programming language similar to Scratch. You drag blocks onto the screen which represent if statements or variables or loops etc. The micro:bit section of the site, simulates a &lt;a href="https://microbit.org/new-microbit/" target="_blank" rel="noopener noreferrer"&gt;BBC micro:bit&lt;/a&gt;
and allows you to write programs for it. There is a download feature which allows you to download the program you have written and run it on a physical device. The process of downloading and running your code on the micro:bit is really straight forward. The micro:bit can be connected to your pc/laptop with a micro usb cable, which also powers the device. The device then shows up as a drive and the programs can be downloaded directly onto the device.&lt;/p&gt;
&lt;p&gt;The BBC micro:bit is a pocket-sized computer that introduces you to how software and hardware work together. It has an LED light display, buttons, sensors and many input/output features that, when programmed, let it interact with you and your world. There is a huge list of sensors from buttons, to accelerometer, to temperature and light. It really is an amazing device.&lt;/p&gt;
&lt;p&gt;The MakeCode website is full of help pages, tutorials and videos, so whatever level or experience you are, you will be able to get started. Also you can get a lot out of the site without having a physical device as the simulator is rather good. However me and my boy, have really enjoyed having a physical device in our hands, that we can move around the house with. We programmed up a simple light sensor, and we could move around the house finding where was dark and what happened if we moved our hands in front of it. The website allows the same thing, however moving a slider is not the same experience.&lt;/p&gt;
&lt;p&gt;Twenty five years ago (or so) my step father was getting me into electronics, by explaining capacitors, resistors and all the other components. So it is no surprise that he has loved setting things up for my boy. He has spent a great deal of time getting components that would work with the micro:bit and 3D printing boards and connectors (to make it easy to connect things up)&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="BBC micro:bit accessories including breadboards, cables, battery boxes, a joystick, a NeoPixel LED strip and an 8x8 LED matrix" src="https://blog-dev.funkysi1701.com/images/microbit-accessories.jpg" loading="lazy"
width="4000" height="3000"
/&gt;
&lt;/p&gt;
&lt;p&gt;Pictured are a selection of the components. We have a selection of breadboards which we haven&amp;rsquo;t tried yet, a selection of cables for connecting things up. Two battery boxes, (3V and 9V). A slider variable resistor, we experimented with using this as a volume control earlier. A board that makes it easy to connect components to the micro:bit. A joystick. A &lt;a href="https://makecode.microbit.org/pkg/microsoft/pxt-neopixel" target="_blank" rel="noopener noreferrer"&gt;NeoPixel&lt;/a&gt;
strip of ten colourful LEDs. A 8x8 LED &lt;a href="https://makecode.microbit.org/pkg/alankrantas/pxt-max7219_8x8" target="_blank" rel="noopener noreferrer"&gt;Matrix&lt;/a&gt;
for cool scrolling messages. The last two components, the NeoPixel and the Matrix require an extension to the standard controls but these are easily found on the MakeCode website.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="MakeCode blocks that move an LED around the micro:bit 5x5 display using joystick X and Y co-ordinates" src="https://blog-dev.funkysi1701.com/images/blocks.png" loading="lazy"
width="461" height="384"
/&gt;
&lt;/p&gt;
&lt;p&gt;I have featured on this page the code I helped write that uses the joystick to move a LED around the 5 x 5 grid that is on the micro:bit. To write this I started off by printing the X Co-ordinates to the screen. With the joystick in the centre position, it was about 500, when moved one way it was low teens, and the other way it was 1000+. Then I needed to figure out how to convert X, Y Co-ordinates for the joystick that could be 0 to 1000, to X, Y co-ordinates of the display that is 5 x 5. The Maths was a bit beyond my boy, but he just about understood what was going on. The clear screen step is needed so the previous position can be removed from the screen.&lt;/p&gt;
&lt;p&gt;I am really enjoying learning about the micro:bit and seeing my boy engage with it and learn programming. I have been very impressed with his ability to retain knowledge of ifs and other programming concepts (however I am a bit biased being his father)&lt;/p&gt;</description></item><item><title>A brief history of Source Control</title><link>https://blog-dev.funkysi1701.com/posts/2022/a-brief-history-of-source-control/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 25 Jul 2022 18:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/a-brief-history-of-source-control/</guid><category term="SourceControl">SourceControl</category><category term="History">History</category><category term="Bitbucket">Bitbucket</category><category term="AzureDevOps">AzureDevOps</category><category term="GitHub">GitHub</category><category term="Git">Git</category><category term="Subversion">Subversion</category><media:content medium="image" type="image/jpeg" url="https://blog-dev.funkysi1701.com/images/svn.jpg"/><description>&lt;p&gt;I have been thinking back to when I started using source control and some of the different tools I have used over the years.&lt;/p&gt;
&lt;p&gt;When I was learning to code it was some time after I had learned the basics that I learnt about source control. Back when I started writing webpages I would have a folder containing all my html, css, images etc and I would FTP these up to my web server. If I made a change to a file I would reupload the file I changed, or reupload all my files to make sure I didn&amp;rsquo;t miss anything.&lt;/p&gt;
&lt;p&gt;It was sometime later that I learnt about source control. I can&amp;rsquo;t remember exactly when, but I suspect it was after I had used it at work. (between 2006 and 2010 as a best guess, my oldest repo says it is 12 years old!)&lt;/p&gt;
&lt;p&gt;Source control (or version control) is the practice of tracking and managing changes to code. These tools provide a running history of code development and help to resolve conflicts when merging.&lt;/p&gt;
&lt;img src="https://blog-dev.funkysi1701.com/images/svn.jpg" width="400px" style="float: left; margin-right: 1rem; margin-bottom: 0.5rem;" alt="Apache Subversion (SVN) logo" /&gt;
&lt;p&gt;The first source control tool I remember using was subversion. The windows client for this was called &lt;a href="https://tortoisesvn.net/downloads.html" target="_blank" rel="noopener noreferrer"&gt;TortoiseSVN&lt;/a&gt;
and is still available today. I know this as my current job has some legacy code which still uses it.&lt;/p&gt;
&lt;p&gt;Back then, to use Subversion you needed to set up a linux server with subversion on it, and you would then connect over your LAN to it from your development machine. This was before the days of github, where everything was hosted on a SaaS service somewhere. I do not remember the process of getting everything setup, but with it being linux, there was no doubt a load of config files to edit, and different dependencies to install.&lt;/p&gt;
&lt;p&gt;Over the years I installed various web interfaces to allow &amp;ldquo;&lt;em&gt;browsing&lt;/em&gt;&amp;rdquo; of source code, some even had bug trackers built in. The ones I can remember are &lt;a href="https://trac.edgewall.org/" target="_blank" rel="noopener noreferrer"&gt;Trac&lt;/a&gt;
and &lt;a href="https://www.redmine.org/" target="_blank" rel="noopener noreferrer"&gt;Redmine&lt;/a&gt;
. Both look to still be available and you can probably install them if you want to remember way back when.&lt;/p&gt;
&lt;img src="https://blog-dev.funkysi1701.com/images/2022/github-octocat.png" width="400px" style="float: right; margin-left: 1rem; margin-bottom: 0.5rem;" alt="GitHub Octocat mascot" /&gt;
&lt;p&gt;The first hosted source control tool I remember using was &lt;a href="https://bitbucket.org/product/" target="_blank" rel="noopener noreferrer"&gt;bitbucket&lt;/a&gt;
and this as far as I can tell has only ever supported git. So I am guessing I imported my subversion repos into git ones at this point. The reason for bitbucket was chosen was it allowed private repositories for free, at that point github was probably available but only provided public repositories.&lt;/p&gt;
&lt;p&gt;After bitbucket the git repos where moved to Azure DevOps or Visual Studio Team Services as it was called back then. This move was mainly to take advantage of the builds and releases feature and to decommission some aging build servers.&lt;/p&gt;
&lt;img src="https://blog-dev.funkysi1701.com/images/azuredevops.png" width="400px" style="float: left; margin-right: 1rem; margin-bottom: 0.5rem;" alt="Azure DevOps logo" /&gt;
&lt;p&gt;This brings me to today where I have a mix of public repos on github and private repos on Azure DevOps. For building my code I use a mix of github actions and Azure Pipelines. As Microsoft own both services now, there is a fair amount of crossover between the two services, however it is far from certain which service is the future.&lt;/p&gt;
&lt;p&gt;Wow, my code has moved around a lot over the years. From no source control, to subversion, to git, to Bitbucket to Azure DevOps!&lt;/p&gt;</description></item><item><title>Visual Studio Keyboard Shortcuts</title><link>https://blog-dev.funkysi1701.com/posts/2022/keyboard-shortcuts/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Tue, 05 Jul 2022 21:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/keyboard-shortcuts/</guid><category term="VisualStudio">VisualStudio</category><category term="shortcuts">shortcuts</category><media:content medium="image" type="image/png" url="https://blog-dev.funkysi1701.com/images/shortcuts.png"/><description>&lt;p&gt;I use keyboard shortcuts all the time, mostly without thinking, but they can be quite a time saver especially for frequently used tasks.&lt;/p&gt;
&lt;p&gt;I recently came across this list of Visual Studio ones. &lt;a href="https://learn.microsoft.com/en-us/visualstudio/ide/default-keyboard-shortcuts-in-visual-studio?view=vs-2022" target="_blank" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/visualstudio/ide/default-keyboard-shortcuts-in-visual-studio?view=vs-2022&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I was going to do a top ten, but not really sure how you rank keyboard shortcuts, so instead I will mention some of my favourites.&lt;/p&gt;
&lt;h2 id="build-solution"&gt;Build solution&lt;a class="anchor ms-1" href="#build-solution" aria-label="Permalink: Build solution"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you are using Visual Studio you need to build your code. If you are anything like me, after even the smallest change I want to see what affect that has had so a rebuild is often needed.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ctrl + Shift + B / Build Solution&lt;/li&gt;
&lt;li&gt;F5 / Run&lt;/li&gt;
&lt;li&gt;Ctrl + F5 / Run with no debugging&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="cut-copy-paste-undo-redo"&gt;Cut, Copy, Paste, Undo, Redo&lt;a class="anchor ms-1" href="#cut-copy-paste-undo-redo" aria-label="Permalink: Cut, Copy, Paste, Undo, Redo"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Programming is sometimes refered to as copying and pasting from &lt;a href="https://stackoverflow.com/" target="_blank" rel="noopener noreferrer"&gt;StackOverflow&lt;/a&gt;
, but they are always times you want to copy and paste stuff so the standard keyboard shortcuts are all here.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ctrl + C / Copy&lt;/li&gt;
&lt;li&gt;Ctrl + X / Cut&lt;/li&gt;
&lt;li&gt;Ctrl + V / Paste&lt;/li&gt;
&lt;li&gt;Ctrl + Z / Undo&lt;/li&gt;
&lt;li&gt;Ctrl + Y / Redo (or Undo your Undo)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="comments-in-your-code"&gt;Comments in your code&lt;a class="anchor ms-1" href="#comments-in-your-code" aria-label="Permalink: Comments in your code"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Often we like to temporarily comment out a line of code to see what affect it has.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ctrl + K, Ctrl + C / Comment selection&lt;/li&gt;
&lt;li&gt;Ctrl + K, Ctrl + U /Uncomment selection&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="using-statements"&gt;Using statements&lt;a class="anchor ms-1" href="#using-statements" aria-label="Permalink: Using statements"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I like to keep my using statements tidy, and not clutered up with ones that aren&amp;rsquo;t used anymore.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ctrl + R, Ctrl + G / Remove and Sort Usings&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="go-to-implementation"&gt;Go to Implementation&lt;a class="anchor ms-1" href="#go-to-implementation" aria-label="Permalink: Go to Implementation"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I like to move quickly between methods that a class is calling to find out what is happening so the go to implementation and go to definition shortcuts are very useful. I tend to use the right click option more than the sortcut, but I would save myself a heap of time if I learnt these shortcuts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;F12 / Go to Definition&lt;/li&gt;
&lt;li&gt;Alt + F12 / Peek Definition&lt;/li&gt;
&lt;li&gt;Ctrl + F12 / Go to Implementation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="find-file-in-solution-explorer"&gt;Find file in Solution Explorer&lt;a class="anchor ms-1" href="#find-file-in-solution-explorer" aria-label="Permalink: Find file in Solution Explorer"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You are editing a file and you have no idea what folder it is in the Solution Explorer. There is a shortcut to find out where you are.&lt;/p&gt;
&lt;p&gt;Ctrl + [, S / Select Active File in Solution Explorer&lt;/p&gt;
&lt;h2 id="search"&gt;Search&lt;a class="anchor ms-1" href="#search" aria-label="Permalink: Search"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Finding references or a certain string is a common activity&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ctrl + F / Find in current file&lt;/li&gt;
&lt;li&gt;Ctrl + H / Replace&lt;/li&gt;
&lt;li&gt;Ctrl + Shift + F / Find in all files&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="visual-studio-tries-to-be-helpful"&gt;Visual Studio tries to be helpful&lt;a class="anchor ms-1" href="#visual-studio-tries-to-be-helpful" aria-label="Permalink: Visual Studio tries to be helpful"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Often Visual Studio will try and be helpful with a lightbulb or similar icon, instead of clicking you can press this shortcut to&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ctrl + . / Show Visual Studio suggestion&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="learn-some-more"&gt;Learn some more&lt;a class="anchor ms-1" href="#learn-some-more" aria-label="Permalink: Learn some more"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As I said before keyboard shortcuts are great time savers. Go check out the complete list and share with me the ones you found most useful.&lt;/p&gt;</description></item><item><title>Diagrams with Mermaid</title><link>https://blog-dev.funkysi1701.com/posts/2022/diagrams-with-mermaid/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Sun, 19 Jun 2022 18:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/diagrams-with-mermaid/</guid><category term="GitHub">GitHub</category><category term="mermaid">mermaid</category><category term="documentation">documentation</category><media:content medium="image" type="image/png" url="https://blog-dev.funkysi1701.com/images/mermaid2.png"/><description>&lt;p&gt;I have been wanting to produce a diagram of the architecture of my side project for some time, but I have put it off as never sure what the correct tools is for this job.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mermaid.js.org/" target="_blank" rel="noopener noreferrer"&gt;Mermaid&lt;/a&gt;
is a tool that lets you create diagrams from code and text. I first came across this tool about a year ago for use in a project. I had forgotten about this tool until the other day, when I was thinking about this problem again.&lt;/p&gt;
&lt;p&gt;Is it possible to embed a mermaid diagram in the markdown used in a github repo? Well the answer is yes, so lets look at how that works.&lt;/p&gt;
&lt;p&gt;A simple mermaid diagram looks like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;graph TD;
A[fff]---&amp;gt;B;
A---&amp;gt;C;
B---&amp;gt;D;
C---&amp;gt;D;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which renders like this:&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Mermaid" src="https://blog-dev.funkysi1701.com/images/mermaid.png" loading="lazy"
width="630" height="912"
/&gt;
&lt;/p&gt;
&lt;p&gt;Lets look at what it is doing.&lt;/p&gt;
&lt;p&gt;TD means the chart is top down.&lt;/p&gt;
&lt;p&gt;A is the name of a node in the chart, [fff] is a label being applied to it.&lt;/p&gt;
&lt;p&gt;Then we just define the relationships between the different nodes, you can have &amp;lt;&amp;mdash;, &amp;mdash;&amp;gt; or &amp;mdash;, or even&lt;br/&gt; &amp;lt;&amp;mdash;&amp;gt;&lt;/p&gt;
&lt;p&gt;Lets look at my architecture. I have a database (cosmosDB), I have a website running on Azure Static Web Apps, I have some Azure functions for getting data into and out of my database. I also have Application Insights monitoring the whole thing. I also have a console app for doing some data import stuff. This produces a diagram like this:&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Mermaid" src="https://blog-dev.funkysi1701.com/images/mermaid2.png" loading="lazy"
width="409" height="445"
/&gt;
&lt;/p&gt;
&lt;p&gt;The code to produce this and display it on my &lt;a href="https://github.com/funkysi1701/Blogv2/" target="_blank" rel="noopener noreferrer"&gt;github repo&lt;/a&gt;
is simply&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;```mermaid
graph TD
A[Azure Static Web App]---B[Http Fn]
B---D[Database]
C[Timer Fn]---D
D---E[Import Console App]
F[App Insights]---A
F---B
F---C
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pretty nice for a few lines of code to show what system talks with what.&lt;/p&gt;
&lt;p&gt;There are improvements that can be made to the diagram, for example changing the shapes of the different services.&lt;/p&gt;
&lt;p&gt;eg
&lt;img class="img-fluid" alt="Mermaid" src="https://blog-dev.funkysi1701.com/images/mermaid3.png" loading="lazy"
width="1034" height="253"
/&gt;
&lt;/p&gt;
&lt;p&gt;If you live in the AzureDevOps world you can add a mermaid diagram to your wiki pages (but I don&amp;rsquo;t think to your markdown files). Just use the following syntax&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;::: mermaid
sequenceDiagram
Alice-&amp;gt;&amp;gt;John: Hello John, how are you?
John--&amp;gt;&amp;gt;Alice: Great!
Alice-)John: See you later!
:::
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For more info see the docs &lt;a href="https://docs.microsoft.com/en-us/azure/devops/project/wiki/wiki-markdown-guidance?view=azure-devops" target="_blank" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;What diagrams are you going to build?&lt;/p&gt;</description></item><item><title>Scottish Summit 2022</title><link>https://blog-dev.funkysi1701.com/posts/2022/scottishsummit/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Tue, 14 Jun 2022 18:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/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-dev.funkysi1701.com/images/scottishsummit.jpg"/><description>&lt;p&gt;On the 10th and 11th June 2022 &lt;a href="https://scottishsummit.com/" target="_blank" rel="noopener noreferrer"&gt;Scottish Summit 2022&lt;/a&gt;
happened and I was there. It was an awesome event and I will attempt to summarise what happened.&lt;/p&gt;
&lt;h2 id="thursday-9th"&gt;Thursday 9th&lt;a class="anchor ms-1" href="#thursday-9th" aria-label="Permalink: Thursday 9th"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On Thursday 9th I travelled down on the train full of excitement about the event. Once I got to the hotel, I was immediately greeted by &lt;a href="https://twitter.com/OfficialCookJ" target="_blank" rel="noopener noreferrer"&gt;James Cook&lt;/a&gt;
, I was obviously in the right place, this weekend is going to be good.&lt;/p&gt;
&lt;h2 id="friday-10th"&gt;Friday 10th&lt;a class="anchor ms-1" href="#friday-10th" aria-label="Permalink: Friday 10th"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The hotel was less then 5 mins walk to the conference, which was being held at the Technology and Innovation Centre, University of Strathclyde. Registration was simple wave your tickets (which were free, apart from a contribution to charity), and you get your badge and a wrist band. (Pink for people contact, blue for hold back) I then got chatting to &lt;a href="https://twitter.com/MrKeithAtherton" target="_blank" rel="noopener noreferrer"&gt;Keith Atherton&lt;/a&gt;
, who amazingly lived in part of the world where I grew up. (Amazing what you learn at conferences!)&lt;/p&gt;
&lt;img src="https://blog-dev.funkysi1701.com/images/scottishsummit.jpg" style="float: left; margin-right: 1rem; margin-bottom: 0.5rem;" alt="Scottish Summit conference during the keynote, with bagpipers and attendees in the venue" /&gt;
&lt;p&gt;Time for the Keynote talk. Which of course because we are in scotland was introduced by bagpipes marching through the room! The talk was given by &lt;a href="https://twitter.com/cmcginley" target="_blank" rel="noopener noreferrer"&gt;Connell McGinley&lt;/a&gt;
and was titled Disability Awareness &amp;amp; Inclusivity. This talk was amazing. Connell is deaf and gave the entire talk with sign language and this was translated for the rest of us to hear. Connell talked about his career and the barriers he faced. Microsoft Teams was an amazing improvement to his work life, as the captioning allowed him to talk with customers for the first time!&lt;/p&gt;
&lt;p&gt;The purple pound is the amount of spending power people with some kind of disability (15% of the worlds population) have and it is approx $13 trillion. If businesses can open their products up to more people it is a win for everyone. This was a really powerful way to open up the conference.&lt;/p&gt;
&lt;p&gt;Next up was &lt;a href="https://twitter.com/davesmall28" target="_blank" rel="noopener noreferrer"&gt;David Small&lt;/a&gt;
talking about Azure DevOps pipelines and Power Platform. I don&amp;rsquo;t know much about Power Platform however all the DevOps stuff was great, some of it reinforced stuff I already knew, some was new.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/samcogan" target="_blank" rel="noopener noreferrer"&gt;Sam Cogan&lt;/a&gt;
was next talking about Infrastructure as Code. Resources for this talk are on his &lt;a href="https://github.com/sam-cogan/events/tree/main/Scottish%20Summit%202022" target="_blank" rel="noopener noreferrer"&gt;github&lt;/a&gt;
This was a great comparison of different tools for doing Infrastructure as Code. Terraform, Pulumi, Bicep, ARM templates where all covered. The difference between stateless and stateful tools. If you have a state file you need to look after it, so if you don&amp;rsquo;t need this think about using a stateless tool. If you are only using Azure consider Azure. If you are a C# (other languages are available) think about using Pulumi (which I have used and quite like)&lt;/p&gt;
&lt;p&gt;Getting Started with Static Web Apps was next with &lt;a href="https://twitter.com/PoornimaNayar" target="_blank" rel="noopener noreferrer"&gt;Poornima Nayar&lt;/a&gt;
this was a great overview of Static Web Apps but as I already use Static Web Apps this was mainly reinforcing what I already knew. However the Static Web App CLI was mentioned which I didn&amp;rsquo;t know about so I am going to spend some time looking at that! Another thing that was mentioned was GraphQL which is a language agnostic way of building APIs which I also want to learn more about. Resources for this talk can be found &lt;a href="https://poornimanayar.co.uk/community/resources-for-my-talk-at-azure-thursdays-july-2021/" target="_blank" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Next was Naming stuff in Azure with &lt;a href="https://twitter.com/Ba4bes" target="_blank" rel="noopener noreferrer"&gt;Barbara Forbes&lt;/a&gt;
, she went through the challenges of getting naming right, especially with all the exceptions Azure throws into the mix. Tagging your resources can really help. Also Azure Policy can help report on what you have (and even enforce it, if you are careful). Lots of interesting stuff, as my naming strategy is non existent at the moment!&lt;/p&gt;
&lt;p&gt;Defender for Cloud Apps with &lt;a href="https://twitter.com/getofmeland" target="_blank" rel="noopener noreferrer"&gt;Charlie Gough&lt;/a&gt;
. This was his first talk and he did really well despite technical problems. This was a security talk, I thought it was going to be about securing the apps you have built, but it was more about securing the apps that the users in your company are using. Still useful to know about, but not really my thing. Sorry Charlie!&lt;/p&gt;
&lt;p&gt;Last talk of the day was &amp;lsquo;What I didn&amp;rsquo;t know about Office 365&amp;rsquo; with &lt;a href="https://twitter.com/sharoneweaver" target="_blank" rel="noopener noreferrer"&gt;Sharon Weaver&lt;/a&gt;
Sharon went through Shifts, Planner and Forms all included in your Office 365 subscription.&lt;/p&gt;
&lt;h2 id="saturday-11th"&gt;Saturday 11th&lt;a class="anchor ms-1" href="#saturday-11th" aria-label="Permalink: Saturday 11th"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To start the second day I had &lt;a href="https://twitter.com/webmaxru" target="_blank" rel="noopener noreferrer"&gt;Maxim Salnikov&lt;/a&gt;
talk about Static Web apps, if I had know it was about Static Web Apps again I may have chosen a different talk but this was still a great talk. Again the CLI was mentioned which I really need to investigate further.&lt;/p&gt;
&lt;p&gt;Next up was James Cook&amp;rsquo;s talk Monitor Azure DevOps and GitHub with Sentinel. This was all about securing your code repositories with Sentinel and looking through the logs at what is happening. To use this tech you need either a GitHub Enterprise subscription or Azure DevOps using Azure AD Logins as it is designed more for the Enterprise than a one man band kind like me, however I will see if I can have a play around with it and see what I can learn.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/TechieLass" target="_blank" rel="noopener noreferrer"&gt;Sarah Lean&lt;/a&gt;
gave a talk about the state of IT Ops tools in the hybrid age. I enjoyed this talk, Sarah added extra fun elements like talking about the Scottish language and the highland cow. The first tool mentioned was Windows Admin Centre. I have heard about this but never used it, must have come out after I switched from Ops to Dev. Looks very Azure like. Azure Update Management was mentioned next, which I have used and works really well. This is the next generation of Update Management, a bit like WSUS from my server days. Azure Policy was mentioned again, a great tool for reporting and/or enforcing things. Azure Arc was mentioned, a way to bring Azure to you. With all these tools consider why you want to use them, what benefits do they bring, not just because it it shiny!&lt;/p&gt;
&lt;p&gt;Mental Health with &lt;a href="https://twitter.com/AzureRory" target="_blank" rel="noopener noreferrer"&gt;Rory Neary&lt;/a&gt;
. This was one of my favourite talks. Rory talked about his mental health problems, his challenges, some of his coping mechanisms some of which involved the power platform. He encouraged us all to be more open about talking about Mental Health. Lots of talks have a solution to a problem, this one didn&amp;rsquo;t, but that Ok. We are all on a journey complete with its ups and downs.&lt;/p&gt;
&lt;p&gt;Accessibility for Blazor with &lt;a href="https://twitter.com/DennieDeclercq" target="_blank" rel="noopener noreferrer"&gt;Dennie Declercq&lt;/a&gt;
. I wasn&amp;rsquo;t as keen on this talk as some of the others, while I agree Accessibility is very important the solutions presented felt very generic and not really specific to Blazor. However I do have some ideas to try now and the accessibility browser extension sounds like a great idea.&lt;/p&gt;
&lt;h2 id="after-hours"&gt;After Hours&lt;a class="anchor ms-1" href="#after-hours" aria-label="Permalink: After Hours"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of the best things about the conference was talking to people between sessions and afterwards. I am an introvert and tend to keep quiet but even I managed to talk to (for me) loads of people. Some of these I had previously connected to on twitter, and some were brand new on the day. I would encourage anyone reading this to reach out to the community, go to an event like this, you will be surprised how friendly and helpful people can be.&lt;/p&gt;</description></item><item><title>Getting started with Scratch coding</title><link>https://blog-dev.funkysi1701.com/posts/2022/scratch/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Tue, 26 Apr 2022 18:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/scratch/</guid><category term="Scratch">Scratch</category><category term="kids">kids</category><media:content medium="image" type="image/png" url="https://blog-dev.funkysi1701.com/images/scratch.png"/><description>&lt;p&gt;My 6 year old boy has been playing with Scratch, so here is a quick introduction to what we have learnt about it.&lt;/p&gt;
&lt;p&gt;Scratch is a website that allows you to &amp;ldquo;code&amp;rdquo; by combining blocks together.&lt;/p&gt;
&lt;p&gt;This is how the scratch website describes its self&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scratch is the world’s largest coding community for children and a coding language with a simple visual interface that allows young people to create digital stories, games, and animations. Scratch is designed, developed, and moderated by the Scratch Foundation, a nonprofit organization.
Scratch promotes computational thinking and problem solving skills; creative teaching and learning; self-expression and collaboration; and equity in computing.
Scratch is always free and is available in more than 70 languages.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Scratch can be found by going to &lt;a href="https://scratch.mit.edu/projects/editor/" target="_blank" rel="noopener noreferrer"&gt;https://scratch.mit.edu/projects/editor/&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;A lot of the blocks affect your character or &amp;ldquo;sprite&amp;rdquo;, the default is a cute looking cat which may also be the scratch logo.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Scratch editor showing the default cat sprite, block palette on the left and coding area in the centre" src="https://blog-dev.funkysi1701.com/images/scratch.png" loading="lazy"
width="905" height="835"
/&gt;
&lt;/p&gt;
&lt;p&gt;The left hand side of the screen consists of a list of the blocks of code you can use and your coding area where you can arrange them.&lt;/p&gt;
&lt;p&gt;The right hand side shows the results of your code, where you can run and test what your code does.&lt;/p&gt;
&lt;p&gt;It didn&amp;rsquo;t take my boy long to code something like this tonight.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Scratch project where the sprite moves towards the mouse pointer and displays a got you message" src="https://blog-dev.funkysi1701.com/images/scratch2.png" loading="lazy"
width="712" height="725"
/&gt;
&lt;/p&gt;
&lt;p&gt;This game moves the &amp;ldquo;sprite&amp;rdquo; towards the mouse pointer and a message &amp;ldquo;got you&amp;rdquo; appears on screen when it reaches your mouse pointer.&lt;/p&gt;
&lt;p&gt;I won&amp;rsquo;t go through all the different blocks you can choose from, but I will highlight some of the programming concepts being learnt here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;inputs&lt;/strong&gt; every computer program needs inputs and there are lots to choose from, things like moving the mouse or pressing a key on the keyboard.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;outputs&lt;/strong&gt; your code needs to do something, this code moves a sprite about the screen&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;variables&lt;/strong&gt; my boy hasn&amp;rsquo;t heard of algebra yet, but he is already grasping concepts like variables, where a value can be assigned and maths can be applied to. In this example the score increases&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;loops&lt;/strong&gt; this program keeps looping until it reaches the mouse pointer&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;logic&lt;/strong&gt; other logic commands are also available, like if / else statements, also &amp;lt;, &amp;gt; and = statements can be used&lt;/p&gt;
&lt;p&gt;There are lots of help and tutorials on the site to help you along, and you can customise the look and even record short sound clips to play in your code.&lt;/p&gt;</description></item><item><title>Temporal Trek Podcast</title><link>https://blog-dev.funkysi1701.com/posts/2022/temporal-trek-podcast/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Fri, 18 Mar 2022 18:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/temporal-trek-podcast/</guid><category term="StarTrek">StarTrek</category><category term="Podcast">Podcast</category><media:content medium="image" type="image/jpeg" url="https://blog-dev.funkysi1701.com/images/podcast.jpg"/><description>&lt;p&gt;Earlier this year I was a guest on the Temporal Trek Podcast.&lt;/p&gt;
&lt;blockquote class="twitter-tweet"&gt;&lt;p lang="en" dir="ltr"&gt;Your Inquiry is recognised.&lt;br&gt;Here is this weeks episode of The Temporal Trek.&lt;br&gt;“Dead Stop” part 2 of the unofficial Battle Damage two parter.&lt;br&gt;&lt;br&gt;Special Guest &lt;a href="https://twitter.com/funkysi1701?ref_src=twsrc%5Etfw"&gt;@funkysi1701&lt;/a&gt; who was paid with three containers of warp plasma. Bargain!&lt;a href="https://t.co/up4zAKOpZy"&gt;https://t.co/up4zAKOpZy&lt;/a&gt; &lt;a href="https://t.co/0EUTAWmqgl"&gt;pic.twitter.com/0EUTAWmqgl&lt;/a&gt;&lt;/p&gt;&amp;mdash; The Temporal Trek Podcast(s) (@rider_coattail) &lt;a href="https://twitter.com/rider_coattail/status/1504830089002897414?ref_src=twsrc%5Etfw"&gt;March 18, 2022&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;
&lt;p&gt;Here is the episode I recorded:
&lt;a href="https://podcasts.apple.com/gb/podcast/the-temporal-trek-podcast-season-3-episode-30-dead/id1499160640?i=1000554428633" target="_blank" rel="noopener noreferrer"&gt;Temporal Trek Podcast Season 3 episode 30 Dead Stop&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;This week &amp;ldquo;Dan Dan&amp;rdquo; are joined by long time friend of the show, formerly from The Ten Forward Podcast, Simon Foster.&lt;/p&gt;
&lt;p&gt;We discuss whether this is&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A part two of a two-parter, last of a four parter or a previosuly unseen part 5 to the Tessek Prime Quintology?&lt;/li&gt;
&lt;li&gt;Rogue full-AI or just a really super advanced computer?&lt;/li&gt;
&lt;li&gt;Station seen again in Voyager?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Oh and by the way has anyone seen the guy who flies the ship, you know the one, tall bloke, loves a good prank, Space Boomer, answers to &amp;lsquo;Travis&amp;rsquo;?&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Temporal Trek Podcast" src="https://blog-dev.funkysi1701.com/images/podcast.jpg" loading="lazy"
width="268" height="268"
/&gt;
&lt;/p&gt;
&lt;p&gt;It was great fun to record and I hope you enjoy giving it a listen.&lt;/p&gt;</description></item><item><title>AWS Cloud Practitioner</title><link>https://blog-dev.funkysi1701.com/posts/2022/aws-cloud-practitioner/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Thu, 17 Mar 2022 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/aws-cloud-practitioner/</guid><category term="AWS">AWS</category><category term="Certification">Certification</category><media:content medium="image" type="image/png" url="https://blog-dev.funkysi1701.com/images/aws.png"/><description>&lt;p&gt;So today I sat the AWS Cloud Practitioner Certification Exam and passed! This is my second certification exam I have sat after the Azure Fundamentals one I sat last year.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.credly.com/badges/3aab54c8-a109-4018-bcad-dbe0d6a1fc0c/public_url"&gt;&lt;img src="https://blog-dev.funkysi1701.com/images/awscp.png" alt="AWS Cloud Practitioner" width="150" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This time was different than the Azure one. Colleagues at work encouraged me to look into doing this particular exam and my employer is going to cover the cost of the exam itself. Last time I did the exam in my own time and didn&amp;rsquo;t really discuss it with anyone from work.&lt;/p&gt;
&lt;p&gt;The other difference was this time I went to a testing centre. The centre was a 5 minute walk from the office. So I decided to work from the office today and 20 minutes before the exam started I walked to the centre. I signed a couple of bits of paper, had my photo taken, had my passport and driving license laughed at, put my belongings in a locker and I was free to start the exam. No worrying about internet connectivity or kids making noise outside my room, or the endless photos at the prep stage of an exam from home. I think I prefer the exam centre experience.&lt;/p&gt;
&lt;p&gt;The other difference was the first exam was Azure, this one was AWS. Both exams cover similar concepts, they are both introductions to Cloud Computing. It&amp;rsquo;s ten months since I did the Azure one, however they both had multiple choice questions and gave you the results at the end. I feel overly familir with Azure, while I don&amp;rsquo;t feel that was with AWS yet. A lot of questions relied on you knowing what AWS services are called. eg AWS Pipeline, AWS CodeStar, AWS CodeBuild, Amazon CodeGuru are all AWS services and are easily mixed up, especially as I have only used a few AWS services, while I have used a lot more of the Azure ones.&lt;/p&gt;
&lt;p&gt;My memory is the Azure gave you a breakdown of your score at the end, while I am still waiting for that from todays exam. This difference may of course be due to it being in a testing centre.&lt;/p&gt;
&lt;p&gt;I still prefer Azure to AWS, however today has proven that I can learn AWS stuff as well. For my next exam I want to get more hands on with my learning, as most of the services I have learnt about so far I haven&amp;rsquo;t seen in action.&lt;/p&gt;</description></item><item><title>Updating SQL Server with Docker</title><link>https://blog-dev.funkysi1701.com/posts/2022/updating-sqlserver-with-docker/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Wed, 23 Feb 2022 00:00:00 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/updating-sqlserver-with-docker/</guid><category term="Docker">Docker</category><category term="SQL">SQL</category><media:content medium="image" type="image/png" url="https://blog-dev.funkysi1701.com/images/header-01.png"/><description>&lt;p&gt;This morning I was listening to a podcast where the new features coming out for SQL Server 2022 were being discussed. This starting me thinking about what would be involved in upgrading.&lt;/p&gt;
&lt;p&gt;Upgrading production environments is complex and there are licensing considerations to take into account. However for non production workloads like development this isn&amp;rsquo;t a problem so lets look at that first.&lt;/p&gt;
&lt;p&gt;In the past I have installed SQL Server Devloper Edition onto my laptop, this is fine but I have found that unless you are very careful you may end up with multiple different versions of SQL Server sitting around, and it is difficult to cleanly remove them without a fresh install of the OS.&lt;/p&gt;
&lt;p&gt;However in this day and age, Docker and Containers are king. My current development environment makes use of Docker and has a docker compose file which sets up SQL Server for this particular application, lets take a look.&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;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;mcr.microsoft.com/mssql/server:2019-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;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;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;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;sqlvolume:/var/opt/mssql&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This defines which docker image to use, in this case 2019-latest, sets up ports and the name and saves the data on a docker volume.&lt;/p&gt;
&lt;p&gt;If we then run SELECT @@VERSION on this instance of SQL Server we get told:&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-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Microsoft SQL Server 2019 (RTM-CU13) (KB5005679) - 15.0.4178.1 (X64) Sep 23 2021 16:47:49 Copyright (C) 2019 Microsoft Corporation Developer Edition (64-bit) on Linux (Ubuntu 20.04.3 LTS) &amp;lt;X64&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What if we change the docker-compose file to use 2022-latest?&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-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;manifest for mcr.microsoft.com/mssql/server:2022-latest not found: manifest unknown: manifest tagged by &amp;#34;2022-latest&amp;#34; is not found
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;SQL Server 2022 hasn&amp;rsquo;t been released yet so there is no docker image for it yet. Try this command again in a few months when it is available.&lt;/p&gt;
&lt;p&gt;OK so what else can we try? What about a downgrade to 2017-latest? Will that work?&lt;/p&gt;
&lt;p&gt;SQL Server 2017 starts but the following error gets logged.&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-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2022-02-23 21:41:15.30 Server Software Usage Metrics is disabled.
&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;2022-02-23 21:41:15.30 spid6s Starting up database &amp;#39;master&amp;#39;.
&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;2022-02-23 21:41:15.34 spid6s Error: 948, Severity: 20, State: 1.
&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;2022-02-23 21:41:15.34 spid6s The database &amp;#39;master&amp;#39; cannot be opened because it is version 904. This server supports version 869 and earlier. A downgrade path is not supported.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Doh we can&amp;rsquo;t downgrade the existing database we have. Probably a good thing really.&lt;/p&gt;
&lt;p&gt;Microsoft release regular updates for SQL Server called CU&amp;rsquo;s (Cumulative Updates), you can see above we are on CU13. Is there a CU14 or CU15 we could try?&lt;/p&gt;
&lt;p&gt;Update the docker compose to: mcr.microsoft.com/mssql/server:2019-CU14-ubuntu-20.04&lt;/p&gt;
&lt;p&gt;At this point I actually got an error&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-tct" data-lang="tct"&gt;2022-02-23 21:50:20.71 Server Error: 17058, Severity: 16, State: 1.
2022-02-23 21:50:20.71 Server initerrlog: Could not open error log file &amp;#39;/var/opt/mssql/log/errorlog&amp;#39;. Operating system error = 5(Access is denied.).
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is caused by trying to use SQL Server 2017 but it is easy to fix.&lt;/p&gt;
&lt;p&gt;In docker desktop there is a volumes section, find the volume you are using with SQL Server and delete the errorlog mentioned above.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="Docker Desktop" src="https://blog-dev.funkysi1701.com/images/2022/docker-desktop1.png" loading="lazy"
width="2945" height="1010"
/&gt;
&lt;/p&gt;
&lt;p&gt;Now if you retry SQL will start OK.&lt;/p&gt;
&lt;p&gt;Repeating the SELECT @@VERSION gives us a new CU&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-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Microsoft SQL Server 2019 (RTM-CU14) (KB5007182) - 15.0.4188.2 (X64) Nov 3 2021 19:19:51 Copyright (C) 2019 Microsoft Corporation Developer Edition (64-bit) on Linux (Ubuntu 20.04.3 LTS) &amp;lt;X64&amp;gt;
&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-txt" data-lang="txt"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Microsoft SQL Server 2019 (RTM-CU15) (KB5008996) - 15.0.4198.2 (X64) Jan 12 2022 22:30:08 Copyright (C) 2019 Microsoft Corporation Developer Edition (64-bit) on Linux (Ubuntu 20.04.3 LTS) &amp;lt;X64&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;How much easier is this than manually installing updates and rebooting or attempting to uninstall and reinstall SQL Server. As SQL Server 2022 isn&amp;rsquo;t out yet I can&amp;rsquo;t say for certain what issues I may encounter but hopefully it will be as easier as this. And I don&amp;rsquo;t need to backup or restore and databases they are all available as before!&lt;/p&gt;</description></item><item><title>dotnet is 20 years old</title><link>https://blog-dev.funkysi1701.com/posts/2022/dotnet-is-20-years-old/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 14 Feb 2022 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/dotnet-is-20-years-old/</guid><category term="DotNet">DotNet</category><media:content medium="image" type="image/jpeg" url="https://blog-dev.funkysi1701.com/images/FLjBrnPXwAQE8BN.jfif"/><description>&lt;p&gt;Today Microsoft celebrated 20 years since the first version of dotnet was released with a special live stream event.&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/67tCWKnweso" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;A lot has happened in the 20 years of dotnet (or .Net). It is my understanding that .Net was created to rival Java. When the .Net Framework was first created it was a windows only thing, but today modern .Net is a modern run anywhere platform, with .net applications running everywhere from PCs and Laptops, Raspberry Pi&amp;rsquo;s, Mobile phones and tablets (via Xamarin Forms), to Websites and Microservice APIs running on every Cloud platform out there.&lt;/p&gt;
&lt;p&gt;If you want to celebrate this achievment tweet with the hashtag &lt;a href="https://twitter.com/search?q=%23dotnetlovesme" target="_blank" rel="noopener noreferrer"&gt;#DotNetLovesMe&lt;/a&gt;
or download some of the digital swag available from &lt;a href="https://github.com/dotnet-presentations/dotNET20th/tree/main/Swag" target="_blank" rel="noopener noreferrer"&gt;github&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;On Thursday the 17th Feb the first preview of dotnet 7.0 is going to be released, with the latest version 6.0 only being released last November.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="History of DotNet" src="https://blog-dev.funkysi1701.com/images/2022/FLj8kj7XEAcW3ng.jpg" loading="lazy"
width="2916" height="1260"
/&gt;
&lt;/p&gt;
&lt;p&gt;The above graphic comes from the following tweet.&lt;/p&gt;
&lt;blockquote class="twitter-tweet"&gt;&lt;p lang="en" dir="ltr"&gt;This is 20 years of &lt;a href="https://twitter.com/hashtag/dotnet?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#dotnet&lt;/a&gt; releases. &lt;a href="https://twitter.com/hashtag/dotNETLovesMe?src=hash&amp;amp;ref_src=twsrc%5Etfw"&gt;#dotNETLovesMe&lt;/a&gt; &lt;a href="https://t.co/Zxfe1SdWTq"&gt;pic.twitter.com/Zxfe1SdWTq&lt;/a&gt;&lt;/p&gt;&amp;mdash; Khalid 🎟 (@buhakmeh) &lt;a href="https://twitter.com/buhakmeh/status/1493220984916258817?ref_src=twsrc%5Etfw"&gt;February 14, 2022&lt;/a&gt;&lt;/blockquote&gt; &lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;
&lt;p&gt;What do you like about dotnet? When did you first start using it? What are you going to build with it next?&lt;/p&gt;</description></item><item><title>Why developers need a personal site</title><link>https://blog-dev.funkysi1701.com/posts/2022/why-do-i-have-a-website/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Tue, 25 Jan 2022 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/why-do-i-have-a-website/</guid><category term="Website">Website</category><media:content medium="image" type="image/jpeg" url="https://blog-dev.funkysi1701.com/images/WHAT-IS-THE-CORPORATE-WEBSITE.jpg"/><description>&lt;p&gt;Is it to share my ideas? Is it to learn new technologies and techniques? Is it to create a following? Is it to educate others? Is it to build some kind of service? Is it some combination of all of these.&lt;/p&gt;
&lt;h2 id="history"&gt;History&lt;a class="anchor ms-1" href="#history" aria-label="Permalink: History"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Back when the web was young and I was first learning HTML. I hand crafted web pages, adding photos I had taken with captions. If I needed a new page I just added a new html page and linked to it from another page.&lt;/p&gt;
&lt;p&gt;As time went on I started to learn mysql and php and my website became a hand crafted php nightmare. I also applied what I learned to help my father run the website for his camera club.&lt;/p&gt;
&lt;p&gt;At some point I started playing with WordPress. I have had various WordPress websites or blogs over the years. WordPress is very powerful you can do so many things, install so many plugins. WordPress runs on php and mysql and as my career started to centre around the .net space, I started to want something that was similar, so I could apply things I had learnt to my own website.&lt;/p&gt;
&lt;p&gt;This has led me to the current state of my website. I have a WordPress blog, with most of my oldest content, my newer content lives on dev.to and I have a Blazor webassembly site that uses the dev.to api to run my new website.&lt;/p&gt;
&lt;p&gt;Blazor webassembly is great, however it has some limitations which I am starting to push against. To host this as cheaply as possible I am using Azure static web apps, so no .net backend all the website is front end. I have some Azure Functions that does the backend bits that I need.&lt;/p&gt;
&lt;p&gt;Google and other bots are not able to find any of my pages except index, due to the way Blazor works. I have got round this by pre rendering the content using &lt;a href="https://prerender.io/" target="_blank" rel="noopener noreferrer"&gt;https://prerender.io/&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;My next difficulty is how to generate a sitemap.xml or a rss feed for my blog. This has started to make me question my architecture decisions.&lt;/p&gt;
&lt;p&gt;I could use a hosted solution like &lt;a href="https://ghost.org/" target="_blank" rel="noopener noreferrer"&gt;ghost&lt;/a&gt;
which is popular with a some of my peers. This would solve many of the problems I am currently facing but I wouldn&amp;rsquo;t be able to play with everything as it is hosted and therefore someone else&amp;rsquo;s problem. How important that is I will look at later.&lt;/p&gt;
&lt;p&gt;Another option would be to use github pages, there are quite a few ways to publish a github page, &lt;a href="https://jekyllrb.com/" target="_blank" rel="noopener noreferrer"&gt;Jekyll&lt;/a&gt;
and &lt;a href="https://gohugo.io/" target="_blank" rel="noopener noreferrer"&gt;Hugo&lt;/a&gt;
appear to be the most popular. Both produce static content and both are a new for me to learn. Interestingly I could also publish either to Azure Static Web apps if github pages ends up not being suitable.&lt;/p&gt;
&lt;h2 id="split-in-two"&gt;Split in two&lt;a class="anchor ms-1" href="#split-in-two" aria-label="Permalink: Split in two"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I think my website needs to be split in two. I need a stable blog platform probably using Hugo and github pages. This is what I want to get indexed by the search engines and be the primary way people find out about what I am doing.&lt;/p&gt;
&lt;p&gt;I then have additional sites, that I use as my playground for learning new tech. I can easily link between them and I can tweak the style so they &amp;ldquo;fit&amp;rdquo; nicely together.&lt;/p&gt;
&lt;p&gt;I am still considering what to do with dev.to. I like that I am using it as the backend for my blog posts, and its API gives me that flexibility to display that content where I want.&lt;/p&gt;</description></item><item><title>Using GitHub Actions</title><link>https://blog-dev.funkysi1701.com/posts/2022/using-github-actions/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Mon, 10 Jan 2022 20:00:45 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/using-github-actions/</guid><category term="GitHub">GitHub</category><category term="DevOps">DevOps</category><media:content medium="image" type="image/png" url="https://blog-dev.funkysi1701.com/images/2022/using-github-actions-banner.png"/><description>&lt;p&gt;I&amp;rsquo;ve been running my website on Azure Static Web Apps for a while and it is pretty cool.&lt;/p&gt;
&lt;p&gt;When you create a Static Web App on Azure you get asked for the github repo of your source code and even the branch to use.
&lt;img class="img-fluid" alt="GitHub Repo for my Static Web App" src="https://blog-dev.funkysi1701.com/images/2022/static-web-app-github-repo.png" loading="lazy"
width="734" height="340"
/&gt;
&lt;/p&gt;
&lt;p&gt;Once you have selected this, you get asked for the type of code to deploy, mine is Blazor Web Assembly but you can use Angular, React or Vue.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="GitHub Actions workflow creation" src="https://blog-dev.funkysi1701.com/images/2022/github-actions-workflow-creation.png" loading="lazy"
width="730" height="321"
/&gt;
You now have three variables to fill in the location in your code of the Website, the location of your Azure Functions and the output location usually wwwroot. Once you have set these three you can preview the GitHub Actions file that will be created and added to your repository.&lt;/p&gt;
&lt;p&gt;I get something like this&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;name: Azure Static Web Apps CI/CD
on:
push:
branches:
- feature/tempbranch
pull_request:
types: [opened, synchronize, reopened, closed]
branches:
- feature/tempbranch
jobs:
build_and_deploy_job:
if: github.event_name == &amp;#39;push&amp;#39; || (github.event_name == &amp;#39;pull_request&amp;#39; &amp;amp;&amp;amp; github.event.action != &amp;#39;closed&amp;#39;)
runs-on: ubuntu-latest
name: Build and Deploy Job
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Build And Deploy
id: builddeploy
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_&amp;lt;GENERATED_HOSTNAME&amp;gt; }}
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
action: &amp;#34;upload&amp;#34;
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
app_location: &amp;#34;Client&amp;#34; # App source code path
api_location: &amp;#34;Api&amp;#34; # Api source code path - optional
output_location: &amp;#34;wwwroot&amp;#34; # Built app content directory - optional
###### End of Repository/Build Configurations ######
close_pull_request_job:
if: github.event_name == &amp;#39;pull_request&amp;#39; &amp;amp;&amp;amp; github.event.action == &amp;#39;closed&amp;#39;
runs-on: ubuntu-latest
name: Close Pull Request Job
steps:
- name: Close Pull Request
id: closepullrequest
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_&amp;lt;GENERATED_HOSTNAME&amp;gt; }}
action: &amp;#34;close&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This github action will run when you create a Pull Request to the branch mentioned in the file, or if you push code into the branch. This code get added into the .github/workflows/ folder and is the location that all github action workflows live.&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t done much with github actions, however I have used Azure DevOps quite a bit. Over on the Azure DevOps side I have created a pipeline that deploys to a Dev environment, then a Test environment and finally a production environment.&lt;/p&gt;
&lt;p&gt;Lets have a look at the workflow that I ended up with and with can break down how it all works. Note I am new to Github actions so if there is a better way of doing this do let me know.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;name: Azure Static Web Apps
on:
push:
branches:
- main
- develop
- feature/*
jobs:
dev:
runs-on: ubuntu-latest
environment:
name: Dev
name: Dev
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Build And Deploy
id: builddeploy
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_&amp;lt;GENERATED_HOSTNAME&amp;gt; }}
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
action: &amp;#34;upload&amp;#34;
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
app_location: &amp;#34;Blog&amp;#34; # App source code path
api_location: &amp;#34;Blog.Func&amp;#34; # Api source code path - optional
output_location: &amp;#34;wwwroot&amp;#34; # Built app content directory - optional
###### End of Repository/Build Configurations ######
test:
if: github.ref == &amp;#39;refs/heads/develop&amp;#39;
runs-on: ubuntu-latest
environment:
name: Test
name: Test
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Build And Deploy
id: builddeploy
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_&amp;lt;GENERATED_HOSTNAME&amp;gt; }}
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
action: &amp;#34;upload&amp;#34;
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
app_location: &amp;#34;Blog&amp;#34; # App source code path
api_location: &amp;#34;Blog.Func&amp;#34; # Api source code path - optional
output_location: &amp;#34;wwwroot&amp;#34; # Built app content directory - optional
###### End of Repository/Build Configurations ######
prod:
if: github.ref == &amp;#39;refs/heads/main&amp;#39;
runs-on: ubuntu-latest
environment:
name: Prod
name: Prod
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Build And Deploy
id: builddeploy
uses: Azure/static-web-apps-deploy@v1
with:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_&amp;lt;GENERATED_HOSTNAME&amp;gt; }}
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
action: &amp;#34;upload&amp;#34;
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
app_location: &amp;#34;Blog&amp;#34; # App source code path
api_location: &amp;#34;Blog.Func&amp;#34; # Api source code path - optional
output_location: &amp;#34;wwwroot&amp;#34; # Built app content directory - optional
###### End of Repository/Build Configurations ######
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first thing I did was create three Azure Static Web Apps, I am using the free tier so while this is tripling my costs it is all still free! Doing this created three github action workflow files, I deleted two and edited the third, but before I deleted them I made a note of the AZURE_STATIC_WEB_APPS_API_TOKEN. If you look in your settings -&amp;gt; secrets for your repo you will see secrets have been created, this is the secure token that github uses to update your static web app.&lt;/p&gt;
&lt;p&gt;While we are in settings we might as well look at environments. I created a Prod, Test and Dev environment that I was going to use in my github actions.&lt;/p&gt;
&lt;p&gt;Environments can have various rules setup on them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Required reviewers - this is like an approver, a user specified here must approve for the workflow to be deployed&lt;/li&gt;
&lt;li&gt;Wait time - I didn&amp;rsquo;t use this, but it looks like a certain amount of time can be set to pause the deployment. (I assume to do some kind of manual check)&lt;/li&gt;
&lt;li&gt;Deployment Branch - specify what branch are allowed to be deployed to what environments. I specified develop, main and feature branches could be deployed to the Dev environment, develop and main could go on Test and main could go on Prod&lt;/li&gt;
&lt;li&gt;Environment secrets - I didn&amp;rsquo;t use this as my secrets were already created, however it looks like your secrets can be associated with a specific environment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that we have the static web apps setup and the environments lets look at the github action file.&lt;/p&gt;
&lt;p&gt;First of all I removed the PR stuff and just concentrated on pushes. I wanted my workflow to be.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Push to feature branch&lt;/li&gt;
&lt;li&gt;Deploys to Dev env&lt;/li&gt;
&lt;li&gt;PR feature branch to develop&lt;/li&gt;
&lt;li&gt;Once merged code gets pushed into develop&lt;/li&gt;
&lt;li&gt;Deploys to Test env&lt;/li&gt;
&lt;li&gt;PR develop to main&lt;/li&gt;
&lt;li&gt;Once merged code gets pushed into main&lt;/li&gt;
&lt;li&gt;Deploys to Prod env (after approval)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The approval on deploying to production I think is probably overkill, but I still have it setup like that for now.&lt;/p&gt;
&lt;p&gt;My gh action has three jobs defined as dev: test: and prod: they are all the same except they have the azure_static_web_apps_api_token that is correct for their environment.&lt;/p&gt;
&lt;p&gt;They also each have a environment defined eg&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;environment:
name: Prod
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Lastly Test and Prod have an if test setup, if the test is false the job won&amp;rsquo;t run. Importantly it won&amp;rsquo;t fail it just won&amp;rsquo;t run.&lt;/p&gt;
&lt;p&gt;For Prod this needs to only run on main branch so we have&lt;/p&gt;
&lt;p&gt;if: github.ref == &amp;lsquo;refs/heads/main&amp;rsquo;&lt;/p&gt;
&lt;p&gt;For Test this needs to only run on develop so&lt;/p&gt;
&lt;p&gt;if: github.ref == &amp;lsquo;refs/heads/develop&amp;rsquo;&lt;/p&gt;
&lt;p&gt;I could have a test for develop to only run on feature/* but I have allowed it to run every time.&lt;/p&gt;
&lt;p&gt;There is loads more you can do with github actions, but hopefully this gives you a taste of some of the things you can do. I currently have a mix of Azure DevOps and github actions so I will be working on getting github actions to do more.&lt;/p&gt;
&lt;h2 id="github-actions-cheat-sheet"&gt;GitHub Actions Cheat Sheet&lt;a class="anchor ms-1" href="#github-actions-cheat-sheet" aria-label="Permalink: GitHub Actions Cheat Sheet"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Want a quick-reference guide you can keep beside your keyboard? I&amp;rsquo;ve put together a one-page GitHub Actions cheat sheet covering workflow structure, triggers, runners, contexts, conditions, matrix builds, caching, artifacts, OIDC permissions, and the most common actions — all on a single A4 page.&lt;/p&gt;
&lt;div class="card mb-4 border-primary"&gt;
&lt;div class="card-body"&gt;
&lt;h3 class="card-title"&gt;GitHub Actions Cheat Sheet — PDF&lt;/h3&gt;
&lt;p class="card-text text-muted"&gt;A one-page A4 quick-reference covering workflow structure, triggers, runners, contexts, conditions, matrix builds, caching, artifacts, OIDC permissions, and the most-used actions.&lt;/p&gt;
&lt;div class="d-flex justify-content-between align-items-center mt-3"&gt;
&lt;span class="fs-4 fw-bold text-success"&gt;£2.99&lt;/span&gt;
&lt;a href="https://buy.stripe.com/8x200j5Exe6UgRB5Ne0Ny00" class="btn btn-primary btn-lg" target="_blank" rel="noopener noreferrer"&gt;
Buy Now &amp;rarr;
&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item><item><title>2022 Goals</title><link>https://blog-dev.funkysi1701.com/posts/2022/2022-goals/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Sat, 01 Jan 2022 00:00:00 +0000</pubDate><guid>https://blog-dev.funkysi1701.com/posts/2022/2022-goals/</guid><category term="Goals">Goals</category><description>&lt;p&gt;Lets have a look at what my goals were for 2021. I had eight of them, lets look at them one by one.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Azure certification&lt;/strong&gt;. In May of this year I sat and passed the Azure Fundamentals exam. I am calling this goal as achieved.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mentoring&lt;/strong&gt;. I didn&amp;rsquo;t do anything about working with others or mentoring, so not sure I achieved this one. However I do now work in a development team and I have been reviewing others code and having my own reviewed. We have a junior developer and I am enjoying the opportunities I have to work with him and share my wisdom.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;F#&lt;/strong&gt;. I have done zero work with F# in 2021, so this one I didn&amp;rsquo;t achieve.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cosmos db/Mongo db&lt;/strong&gt;. I have worked with both of these technologies in 2021. I used Cosmos the most with my website, and storing data for it. I used Mongo/Atlas for auditing for a project I did for my previous job. I wouldn&amp;rsquo;t say I was expert in either of these, but I am starting to get a flavour of non SQL Server databases. I should also note that I am using mysql a lot in my latest job, so another non SQL Server technology that I get to use on a daily basis.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Give a talk&lt;/strong&gt;. I said last year that maybe I would make baby steps towards doing this, and I have. In the interview for my new job I gave a short presentation (I thought it was bad, but others didn&amp;rsquo;t!) I also gave a short introduction to Blazor talk which went down well.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mandlebrot Generator&lt;/strong&gt;. Did nothing on this one as well. I may have googled the code but that is as far as I got.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pwned Pass Mobile App&lt;/strong&gt;. I got an increase in users in 2021 and hence it it still running and I still pay for the API key. I am still considering what to do with it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time for me&lt;/strong&gt;. Achieved this one, had plenty of time for myself.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="not-a-bad-year-but-what-are-my-goals-for-2022"&gt;Not a bad year but what are my goals for 2022?&lt;a class="anchor ms-1" href="#not-a-bad-year-but-what-are-my-goals-for-2022" aria-label="Permalink: Not a bad year but what are my goals for 2022?"&gt;&lt;i class="fas fa-link" aria-hidden="true"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Video&lt;/strong&gt;. I have just purchased a green screen, so my first goal is to learn how to use OBS, how to light myself properly without getting horrible reflections. I have the content for my first talk, the talk I gave at work about Blazor.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Conference&lt;/strong&gt;. Attend an in person conference. I am booked to attend Scottish Summit, however it has been postponed due to COVID-19.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Blog More&lt;/strong&gt;. I have been neglecting writing blog posts a bit recently, so I want to do more.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Metrics&lt;/strong&gt;. I have been recording various metrics from twitter, github etc and I would like to expand this and make it a service.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Profile Pic&lt;/strong&gt;. My profile pic is getting a bit old, so it would be nice to update the images I use online and improve my personal brand.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item></channel></rss>