<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2026-01-13T14:11:53+00:00</updated><id>/feed.xml</id><title type="html">Posts</title><subtitle>Sam Ollason, personal site. My way of recording and sharing what I have learnt.</subtitle><entry><title type="html">Collecting evidence to beat imposter syndrome</title><link href="/self-development/mental/health/productivity/2025/11/20/managing-imposter-syndrome.html" rel="alternate" type="text/html" title="Collecting evidence to beat imposter syndrome" /><published>2025-11-20T07:13:41+00:00</published><updated>2025-11-20T07:13:41+00:00</updated><id>/self-development/mental/health/productivity/2025/11/20/managing-imposter-syndrome</id><content type="html" xml:base="/self-development/mental/health/productivity/2025/11/20/managing-imposter-syndrome.html"><![CDATA[<p><strong>TL;DR</strong>
One technique, which helps me manage my imposter syndrome, is writing down evidence! Find/decide what ‘good’ looks like and regularly put evidence against it. E.g. every week write bullet points against your competency/skills matrix at work and over time the black-and-white factual evidence speaks for itself. How can you argue against facts?!</p>

<hr />

<p>Like many others I speak to in tech (and other fields) I have struggled with imposter syndrome massively at different points in my career (and life in general). I think this is all too common in software because there is no checklist/certificate/exam that proves that you are, in a binary fashion, ‘good enough’, … which is at odds with other professions (you either are or aren’t a qualified Doctor, or a chartered Accountant etc).</p>

<p>At times, with other inter-related things, imposter syndrome has compounded with other challenges of life and really hampered my mental health and happiness as a human. I was in a tough spot (‘a real pickle’ as my late Nan would have said) a while ago and, alongside some other reasons, I was really struggling with my mental health and sense of worth. Desperate to find a technique to get a handle on it, I read <a href="https://www.drjessamy.com/impact" target="_blank">Dr Jessamy Hibbard’s</a> book and the main takeaway for me was all about <strong>cold, hard, evidence leads proof!</strong>.</p>

<p>For life in general, I found the exercise of ‘write down literally everything you have ever achieved in life’ to be really cathartic. This means every exam passed, saving for holidays, having the courage to try a new sport, painting a room in your house … everything! As per the suggestions, I did this over several days and weeks as different thoughts kept coming to me. That was a really useful reflective exercise.</p>

<p>For work specifically, the technique I use (which is similar to the above) is to evidence against our organisation’s competency framework. We have a skills matrix for all different levels of engineering and the behaviours expected at each level (as do most companies, … as <em>should</em> all companies, I believe). At the end of each week I spend 15 minutes writing evidence against each of the areas of the framework. Just a few bullet points each week. This is a private process and tool for me to reflect on, I don’t share it (although I wouldn’t have any problem sharing it).</p>

<p>The effect: looking back over a few months I can see looooooads of evidence of me doing different parts of the job across multiple weeks. Right in front of my eyes.</p>

<p>Surely if I am doing and achieving all of this across all areas of the ‘senior engineer’ job spec, … that means I am doing what a senior engineer would be expected to do … therefore I am a senior engineer! This helps quieten the voices in my head.</p>

<p>The other bonus of this is that it makes it easier to identify where I have ‘evidence gaps’ that I can use to tailor individual quarterly goals, and it’s also super useful for me to reflect on at the end of each quarter.</p>

<hr />

<h1 id="conclusion">Conclusion</h1>

<p>I hope you found this useful. How do you manage imposter syndrome? Feel free to message me on <a href="https://www.linkedin.com/in/samollason/" target="_blank" rel="noopener">LinkedIn</a> :)</p>]]></content><author><name></name></author><category term="self-development" /><category term="mental" /><category term="health" /><category term="productivity" /><summary type="html"><![CDATA[TL;DR One technique, which helps me manage my imposter syndrome, is writing down evidence! Find/decide what ‘good’ looks like and regularly put evidence against it. E.g. every week write bullet points against your competency/skills matrix at work and over time the black-and-white factual evidence speaks for itself. How can you argue against facts?!]]></summary></entry><entry><title type="html">Maintaining control and getting 10x from Vibe coding</title><link href="/ai/productivity/2025/11/19/stay-in-control-with-copilot.html" rel="alternate" type="text/html" title="Maintaining control and getting 10x from Vibe coding" /><published>2025-11-19T07:13:41+00:00</published><updated>2025-11-19T07:13:41+00:00</updated><id>/ai/productivity/2025/11/19/stay-in-control-with-copilot</id><content type="html" xml:base="/ai/productivity/2025/11/19/stay-in-control-with-copilot.html"><![CDATA[<p><strong>TL;DR</strong>
My top tips to stay in control, maximise learning and get the best from months of Vibe Coding (using Copilot in agent mode).</p>

<p>I’ve been using Copilot to improve my productivity a lot in 2025. I’m always exploring how it can serve me best. I’ve written about it before <a href="https://samollason.github.io/ai/2025/07/24/using-copilot-agent-and-tdd.html" target="_blank">here</a> and lead sessions sharing my learnings across Howden’s engineering function.</p>

<p>I’m convinced the best engineers are going to be those that can play the orchestrator mode (shepherding AI to do the 80%) and the heart surgeon role (locate and dive into a very specific line of code to solve a nuanced and tricky issue - the 20%).</p>

<p>Here are some of my top tips so far:</p>

<ol>
  <li>
    <p><strong>Ctrl+V</strong>: Pasting in screenshots to the chat window - ‘A picture says 1000 words’ and all that. I constantly share screenshots with Copilot to give quick context to what I am trying to do. E.g. if I want it to debug a UI feature I will screenshot the browser, the open developer tools and ask it whats wrong. Just screengrab and paste it into the command. Another use case is when I don’t understand why VS code is behaving a certain way - I just screenshot the area of the screen instead of trying to describe the issue.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Add logs so we can debug this</code>. - sometimes I have seen Copilot get stuck in loops when it’s trying to debug a particular issue. It suggests something, which doesn’t work, and then suggests something else, which doesn’t work … and then goes back to option 1 again! This is particularly acute when the bugs are due to race conditions, asynchronous behaviour and complex interactions in UIs. Copilot can rapidly add tonnes of Console.WriteLine() statements in seconds to help you spot what’s going on, quickly (or, better yet, to help it understand what’s going on! See notes on screenshots above).</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Are we using the right pattern/approach? What would be idiomatic for [languageX]</code> - Building off of 2 above, sometimes I have noticed Copilot getting confused and spinning into loops by adding more and more code that doesn’t solve the problem. As the human in control, in these scenarios I ask Copilot ‘hang on a minute, are we trying to solve this using the wrong pattern?’. I saw this most recently with an issue relating to keeping different areas of our UI in sync. After asking Copilot, it explained to me that the way we were using events wasn’t best practice and wasn’t idiomatic, and instead it would be more idiomatic in Blazor.
note: this is where humans can add value and experience of senior engineers is valuable; I was able to refer to the way that React works with params (‘props’) and understand this issue that way.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">Give it permission for all git commands - except push</code>. I’ve saved loads of time by giving Copilot the ability to run most git commands (add, merge, pull, commit etc) but I have explicitly asked it not to <code class="language-plaintext highlighter-rouge">push</code> on my behalf. This lets me review each micro change it makes to make sure I understand and agree.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">'quiz me!'</code> - you are responsible for your code, so to make sure I understand what’s being proposed I regularly ask Copilot ‘create a quiz with 3 questions about the core concepts we have covered so far’. This is particularly useful when using Copilot as a learning tool. When I am working on a side project to learn a new technology I lean on this heavily to get the best combination of ‘let’s build a real thing quickly so I can see how it works’ and ‘I want to make sure I understand the theory’. This can also be a fun way of getting started on a project to ‘warm up’ for a session of coding.</p>
  </li>
</ol>

<hr />

<h1 id="conclusion">Conclusion</h1>

<p>I hope you found this useful. How are you using Copilot? Feel free to message me on <a href="https://www.linkedin.com/in/samollason/" target="_blank" rel="noopener">LinkedIn</a> :)</p>]]></content><author><name></name></author><category term="ai" /><category term="productivity" /><summary type="html"><![CDATA[TL;DR My top tips to stay in control, maximise learning and get the best from months of Vibe Coding (using Copilot in agent mode).]]></summary></entry><entry><title type="html">‘Agentic TDD’ and other Learnings from coding with CoPilot in agent mode</title><link href="/ai/2025/07/24/using-copilot-agent-and-tdd.html" rel="alternate" type="text/html" title="‘Agentic TDD’ and other Learnings from coding with CoPilot in agent mode" /><published>2025-07-24T11:13:41+00:00</published><updated>2025-07-24T11:13:41+00:00</updated><id>/ai/2025/07/24/using-copilot-agent-and-tdd</id><content type="html" xml:base="/ai/2025/07/24/using-copilot-agent-and-tdd.html"><![CDATA[<p><strong>TL;DR</strong>
I’ve been using GitHub CoPilot for ‘Agentic TDD’ a lot recently in Visual Studio. Here is what I have been exploring and what I have learnt.</p>

<ol>
  <li>User stories + TDD + CoPilot is a huge boost to speed while maintaining accuracy and understanding</li>
  <li>Analysis of your codebase and recommendations for best practices can boost learning and generate documentation at the same time.</li>
  <li>Easily increase unit test coverage of existing code (we increased by 5% in a month while adding more code)</li>
  <li><a href="https://docs.github.com/en/copilot/how-tos/custom-instructions/adding-repository-custom-instructions-for-github-copilot" target="_blank">copilot-instructions.md</a> is a great place to evolve a useful and usable style guide that you can use to direct CoPilot.</li>
</ol>

<hr />

<h1 id="overview">Overview</h1>

<p>Agent mode in Visual Studio CoPilot came out about 6 weeks ago, and I’ve been playing around with a lot in day-to-day work to see how it can improve my workflow.</p>

<h1 id="1-agentic-tdd">1. ‘Agentic TDD’</h1>

<p>This is a skill I have been actively working on and refining recently. It’s a kind of meta-programming, in a way.</p>

<p>I’ve long been a fan of using TDD (Test Driven Development) as a development practice for many reasons. The obvious ones are that by the time you are finished, you have tests written (instead of moving onto the next feature) and self-documenting code. But another reason, with my product management hat on, is that it constantly forces you to think about the <em>problems</em> you are solving <em>while working on the solution</em> (e.g. “I want a method that formats the date of birth field on the screen … so that users don’t have to calculate this themselves”), which I think keeps re-focussing you on what you are trying to achieve.</p>

<p><strong>One of the challenges I have always found with TDD is how frustrating and long-winded it can be to set up the infrastructure and boilerplate needed for tests</strong>, especially if you are creating tests for a new class or file that doesn’t have any prior art. Anyone who has written unit tests in real production apps knows how fiddly and time-consuming it is to mock all of the dependencies needed for unit tests etc etc. We’ve all been there when you need 50+ lines of setup boilerplate … all for a method assertion that is one line of code. However, CoPilot changes that! It’s extremely good, though not perfect, at generating all of that setup and boilerplate.</p>

<p>This leans into the motto I’ve read about: <strong>“outsource your tasks, not your thinking”</strong> to CoPilot.</p>

<p>This has led me to change my workflow for most tasks to:</p>

<ol>
  <li>In the CoPilot chat window in my IDE (Visual Studio at the moment), share some context and User Story (context and Given/When/Then).</li>
  <li>Ask CoPilot to generate a failing test for the first acceptance criteria.</li>
  <li>Inspect the tests it generates and fix/tweak them. Often, I encourage CoPilot to generate extra scenarios, fix a few import errors, or subtly change what is being tested. Here is where humans, with experience and domain knowledge, can really add value. For instance, instead of just getting CoPilot to generate unit tests to calculate an insurance premium, nudge CoPilot to add realistic business scenarios based on cohorts/personas (“young drivers scenario where they will have higher premiums”), etc.</li>
  <li>Ask CoPilot to fix the tests. Sometimes I literally just say “fix this” and it does it.</li>
  <li>I have set up our CoPilot-instructions to ask CoPilot to build and run all unit tests after every change it makes. I inspect the results of the tests (usually they now pass).</li>
  <li>Inspect CoPilot’s solution: often I have to make a few tweaks, but not much; I suppose when you break down most work items into very small pieces, everything is usually a just a solved problem really, so CoPilot finds this easy.</li>
</ol>

<p><strong>Another good habit alongside TDD that this encourages is writing down a proper user story</strong>, which, again, aligns everyone in the team around what it is you are really doing, and why.</p>

<p>I’ve been surprised by good this approach above is; CoPilot has often added really neat UI layouts and implementations that I wasn’t thinking of.</p>

<p>Also, I have added instructions about using TDD and my team’s preferences into our CoPilot-instructions.md file (more on this below). I have also added some notes about style and coding preferences in here, which seem to be getting used (most of the time). More on this below.</p>

<hr />

<h2 id="2-living-style-guide">2. Living style guide</h2>

<p>Whenever CoPilot doesn’t generate code or comments in a way that suits our team’s style (or best practice), pI update our coPilot-instructions.md file (which sits in our application solution alongside other documentation) with notes about how things should be done. I have found that this is evolving into a useful and usable ‘living’ style guide for our project.</p>

<p>A few months ago I led an initiative at work to author the first draft of our engineer department cross-team C#/Blazor style guide. It lives in a shared Wiki and doesn’t really get looked at (largely because it’s separated from our workflow). The style guide section of the CoPilot-instructions file is starting to replacing this, and at a certain point I will probably break it out and share it with other teams.</p>

<p>A flavour of of our copilot-instructions (redacted and sensitive information removed):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Context

### Business context
* We work for Howden Insurance, a global insurance broking company.
* The work we do is regulated by the FCA and other UK/Global institutions.
* &lt;some notes here about how our users use our apps, how they feel when using their apps, how we want them to feel, what they are trying to achieve, what their personas are&gt;

### Code style
* Always consider accessibility.
* Use best practice and latest C#/Blazor features. Try to use the same style and patterns that exist already in the codebase, and if these two things conflict, use the best practice approach but make this clear to me in comments where you have deviated from the usual style.

### Testing
* We use BUnit and NUnit for unit tests.

### Security
* To mitigate against the risk of XSS attacks, please do not use `MarkupString` or any other method that means user input won't be properly validated and sanitized before being displayed in the UI.
* Consider OWASP top 10 security risks when adding new features
...
</code></pre></div></div>

<hr />

<h2 id="3-increasing-unit-test-coverage">3. Increasing unit test coverage</h2>

<p>Building on the above, the habit I am getting into is whenever I touch a new area of our codebase, <strong>I review the unit test coverage and if it’s lacking, then use CoPilot to generate some tests</strong> before we add more (via TDD). This increases our coverage and increases my confidence that I haven’t broken anything.</p>

<p>You are probably thinking, “you should be doing this anyway,” and, yes, I completely agree. However, the difference now is that it takes CoPilot seconds to generate dozens of test cases for existing code that I can then tweak, review, and modify, instead of me having to write them all out by hand which, being realistic, isn’t always feasible given deadlines and the need to add good quality to the new work being introduced. <strong>This has been a 10x (or more) time saving for me</strong> and has led to us increasing our unit test coverage 5% in a month (despite adding loads of new lines of code).</p>

<p>Interestingly, there are a few times where we have decided to refactor some older, existing code to make it more testable, which has resulted in better code!</p>

<hr />

<h2 id="4-analysis-of-your-codebase">4. Analysis of your codebase</h2>

<p>When I first joined the team I am in now, I hadn’t worked with Blazor, C# or .NET before. I wanted to understand the approach our app used for state management, and whether this was done consistently and followed best practices (especially compared to other projects I had worked on). It took a bit of nudging, lots of back and forth in the conversation with CoPilot (e.g. “please give some real examples”), but I got a great result. This now lives in our documentation for others to view, and it reinforces CoPilot to continue using these patterns (for consistency).</p>

<p>Similarly, I did a similar exercise for analysing our approach to security – what is our application’s approach to auth? Does it follow best practices?</p>

<p>I started by writing down a numbered list of my understanding of how authentication/authorization works with our application in terms of the user flow and what methods are called etc. I then asked CoPilot to review it, correct it, and provide me with snippets and file locations of where the configuration is. It wasn’t always right, but it got me 95% of the way.</p>

<p><strong>A massive benefit of using CoPilot to co-author these documents is speed of learning and being able to produce useful and relevant documentation to add to the solution for others as well. A double win!</strong></p>

<hr />

<h1 id="conclusion">Conclusion</h1>

<p>I hope you found this useful. How are you using CoPilot? Feel free to message me on <a href="https://www.linkedin.com/in/samollason/" target="_blank" rel="noopener">LinkedIn</a> :)</p>]]></content><author><name></name></author><category term="ai" /><summary type="html"><![CDATA[TL;DR I’ve been using GitHub CoPilot for ‘Agentic TDD’ a lot recently in Visual Studio. Here is what I have been exploring and what I have learnt.]]></summary></entry><entry><title type="html">Coding with AI - using images and Copilot agent</title><link href="/ai/2025/07/09/uploading-images-to-copilot.html" rel="alternate" type="text/html" title="Coding with AI - using images and Copilot agent" /><published>2025-07-09T11:13:41+00:00</published><updated>2025-07-09T11:13:41+00:00</updated><id>/ai/2025/07/09/uploading-images-to-copilot</id><content type="html" xml:base="/ai/2025/07/09/uploading-images-to-copilot.html"><![CDATA[<p><strong>TL;DR</strong> - uploading screenshots to Copilot in agent mode of your wireframes saves some grunt work of creating the UI markup code. Give it a go!</p>

<p>I’ve been really enjoying trying out the new Copilot AI capabilities that are have been (rapidly) made available in the past few months.</p>

<p>I’ve been using Copilot in agent mode with Visual Studio since it was made available recently. If you aren’t aware, this mode is designed to take prompts and commands from you and make real-time live code changes to your codebase in front of you, instead of just suggesting changes inside of the chat window (which is what we had with ‘chat’ mode)</p>

<p>A really neat trick I discovered last week is taking a screenshot of a wireframe (e.g. in Figma) and uploading the image as part an interaction with Copilot.</p>

<p>I had a screenshot of a wireframe of a table of information that we wanted to add to our UI. I specified that I wanted Copilot to produce the UI markup (I am using .NET’s Blazor and therefore the markup is in razor syntax) and all the relevant model bindings, and to follow examples of a few similar code files. It took some nudging, but it was pretty successful.</p>

<p>I was then really pleased when I continued to iterate on the initial static markup to enhance the table to make it dynamic; I wanted the contents of the table to appear depending on an option a user has selected elsewhere in the app (this was already built at this point).</p>

<p><img src="/_images/copilot_agent_mode_upload_screenshot.png" alt="Screenshot of how to upload an image to Copilot in Visual Studio" /></p>]]></content><author><name></name></author><category term="ai" /><summary type="html"><![CDATA[TL;DR - uploading screenshots to Copilot in agent mode of your wireframes saves some grunt work of creating the UI markup code. Give it a go!]]></summary></entry><entry><title type="html">Thoughts on .NET 10.4 preview</title><link href="/dotnet/c%23/blazor/2025/06/10/thoughts-on-dotnet-10_4-previews.html" rel="alternate" type="text/html" title="Thoughts on .NET 10.4 preview" /><published>2025-06-10T11:13:41+00:00</published><updated>2025-06-10T11:13:41+00:00</updated><id>/dotnet/c%23/blazor/2025/06/10/thoughts-on-dotnet-10_4-previews</id><content type="html" xml:base="/dotnet/c%23/blazor/2025/06/10/thoughts-on-dotnet-10_4-previews.html"><![CDATA[<p>I’ve been working with .NET at <a href="https://www.howdengroup.com/uk-en" target="_blank">Howden</a> for about 9 months now and, after getting my head around whats available ‘now’ in .NET I have been looking to the future with what will be coming up in .NET 10 later in 2025.</p>

<p>You can read about other previews <a href="https://samollason.github.io/" target="_blank">here</a>.</p>

<p><em>(All views expressed are my own).</em></p>

<h1 id="overview">Overview</h1>

<p>.NET 10 will be released in late 2025, but the previews are already being released (10.4 was released in May).</p>

<p>Below are my thoughts on what’s been announced and, in particular, what’s more relevant to those of us working with Blazor.</p>

<p>Full announcements: <a href="https://devblogs.microsoft.com/dotnet/dotnet-10-preview-4/" target="_blank">.NET 10 Preview 4 is now available! - .NET Blog</a></p>

<h1 id="a-more-meta-point">A more ‘meta’ point</h1>

<p>This is more of a comment on the .NET release notes structure, but I often find myself naturally asking ‘what does this apply to?’ and ‘what previously existed?’ when looking at new features to contextualise them. I often turn to the CoPilot app to give me some more background. It would be useful if some of this information was included in the release notes from Microsoft themselves, IMO.</p>

<p>E.g. this was particularly useful:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tell me more about integration testing with Kestrel in .NET 10.4

what types of .NET application is this relevant to?

https://github.com/dotnet/core/blob/main/release-notes/10.0/preview/preview4/aspnetcore.md#use-webapplicationfactory-with-kestrel-for-integration-testing
</code></pre></div></div>

<h1 id="blazor-webassembley-runtime-diagnostics">Blazor WebAssembley runtime diagnostics</h1>

<p>In .NET 10 Preview 4, Microsoft are introducing enhanced runtime diagnostics for Blazor WebAssembly apps, which include:</p>

<ul>
  <li>Performance traces: You can now collect detailed performance profiling data.</li>
  <li>Memory dumps: Capture memory snapshots for in-depth analysis.</li>
  <li>Runtime metrics: Monitor runtime behavior such as memory usage.</li>
</ul>

<p>These diagnostics are now built into the WebAssembly runtime, rather than relying solely on browser developer tools or external profiling setups. I haven’t yet explored these but I am keen to see what additional insights we can gain about our application to give our users a better experience.</p>

<h1 id="use-webapplicationfactory-with-kestrel-for-integration-testing">Use WebApplicationFactory with Kestrel for integration testing</h1>

<p>There is a new and improved way to create integration tests which allows for more realistic tests, which should bring more confidence.</p>

<p>This is particularly for applications have endpoints exposed from Blazor WASM hybrid apps.</p>

<p>Previously, using WebApplicationFactory to setup integration tests used an in-memory HTTP server called TestServer, but in 10.4 WebApplicationFactory can now be setup to use Kestrel which is the actual web server used in production by a .NET app.</p>

<p>Using Kestrel instead of TestServer in tests enables:</p>

<ul>
  <li>End-to-end testing of real HTTP features (e.g., HTTPS, HTTP/2, WebSockets).</li>
  <li>Middleware and pipeline validation under real server conditions.</li>
  <li>Testing of custom server configurations (e.g., ports, certificates, limits).</li>
</ul>

<p>Copied from some examples online, here is an example setup to give you a flavour of how this could work in your integration test setup:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>var factory = new WebApplicationFactory&lt;Program&gt;()
    .WithWebHostBuilder(builder =&gt;
    {
        builder.UseKestrel(); // Use real Kestrel server
        builder.ConfigureKestrel(options =&gt;
        {
            options.ListenLocalhost(5001); // Customize as needed
        });
    });


factory.CreateClient() ...
</code></pre></div></div>

<p><a href="https://github.com/dotnet/core/blob/main/release-notes/10.0/preview/preview4/aspnetcore.md#use-webapplicationfactory-with-kestrel-for-integration-testing" target="_blank">More here</a></p>]]></content><author><name></name></author><category term="dotnet" /><category term="c#" /><category term="blazor" /><summary type="html"><![CDATA[I’ve been working with .NET at Howden for about 9 months now and, after getting my head around whats available ‘now’ in .NET I have been looking to the future with what will be coming up in .NET 10 later in 2025.]]></summary></entry><entry><title type="html">Microsoft Azure Fundamentals Certification</title><link href="/microsoft/certifications/2025/05/22/microsoft-azure-fundamentals-certification.html" rel="alternate" type="text/html" title="Microsoft Azure Fundamentals Certification" /><published>2025-05-22T10:30:00+00:00</published><updated>2025-05-22T10:30:00+00:00</updated><id>/microsoft/certifications/2025/05/22/microsoft-azure-fundamentals-certification</id><content type="html" xml:base="/microsoft/certifications/2025/05/22/microsoft-azure-fundamentals-certification.html"><![CDATA[<p>I’ve been working with .NET and Azure at <a href="https://www.howdengroup.com/uk-en" target="_blank">Howden</a> for about 9 months now. I recently passed the <a href="https://learn.microsoft.com/en-us/credentials/certifications/azure-fundamentals/?practice-assessment-type=certification" target="_blank">Microsoft Azure Fundamentals</a> certification (on the 2nd attempt!) and, after talking to some colleagues about my experience, I thought it would useful with others that are considering the exam.</p>

<h2 id="why">Why?</h2>

<p>I wanted to increase my understanding of what Azure has to offer and how it works. I’ve been using Azure since joining (I’d only ever worked with AWS before) and I wanted to understand the landscape of Azure so I know where to look when I run into a problem. I was also curious to understand what I didn’t know.</p>

<p>I found the general ‘cloud concepts’ were useful (looking at availability zones, IaaS vs PaaS vs SaaS etc) and it was good to learn more about VMs at a high-level. However, I think I would have learnt more about the ‘product-specific’ things by clicking around the Azure portal and googling/asking CoPilot when I got stuck.</p>

<h2 id="thoughts-on-the-exam">Thoughts on the exam</h2>

<p>I have never taken an online exam remotely, and I was pleasantly surprised at how robust their integrity and ‘anti-cheat’ procedures were but also how frictionless and painless it was. Bearing in mind this process involved me having to take pictures of my Id, myself, my working area, a phone and video call with one of the exam invigilators to check my working area was free from notes etc. I was even reminded during the exam, via chat, not to speak out loud (I was reading questions out loud to myself, but I guess they thought I could be asking the questions out loud to someone in the next room?)</p>

<p>There is something to reflect on here about the user experience that I am working on in my team every day…</p>

<h2 id="how-i-prepared">How I prepared</h2>

<p>I prepared for it by going through the online learning path that’s offered my Microsoft. Its nice and bite-sized and had a few interactive exercises. I have also been using Azure in my daily work, but I haven’t spent much time setting up new things/debugging Azure which is really where you learn things.</p>

<p>I am fortunate that we get some ‘personal development time’ in our work calendars at Howden, which was good to get my head down and learn this stuff.</p>

<p>I spent about 2 hours following the Microsoft dedicated online course with some time googling and checking things out in the Azure portal. The exam was about 40 questions and only took 15-20 mins (with about 20 mins beforehand to login and checkin etc.)</p>

<h2 id="final-thoughts">Final thoughts</h2>

<h3 id="would-i-recommend-it">Would I recommend it?</h3>

<p>Thats the key question! I would recommend it to people that are new to Azure and working in roles, like me, as a developer, where I am working with Azure services regularly but not necessarily setting things up services/config myself from scratch (something that an enabling cloud team would usually do). Even if you don’t do the exam I’d say it’s worth reading through the online course and doing some of the mock exams (which would only take you 2-3 hours of reading time).</p>

<h3 id="signed-by-satya">Signed by Satya</h3>

<p>Finally, with my ‘product development’ hat on, I absolutely loved that my digital certificate is signed by Satya Nadella. I thought that was a really nice feature that would have cost Microsoft virtually nothing to build.</p>]]></content><author><name></name></author><category term="microsoft" /><category term="certifications" /><summary type="html"><![CDATA[I’ve been working with .NET and Azure at Howden for about 9 months now. I recently passed the Microsoft Azure Fundamentals certification (on the 2nd attempt!) and, after talking to some colleagues about my experience, I thought it would useful with others that are considering the exam.]]></summary></entry><entry><title type="html">Thoughts on .NET 10.3 preview</title><link href="/dotnet/c%23/blazor/2025/05/15/thoughts-on-dotnet-10_3-previews.html" rel="alternate" type="text/html" title="Thoughts on .NET 10.3 preview" /><published>2025-05-15T09:30:57+00:00</published><updated>2025-05-15T09:30:57+00:00</updated><id>/dotnet/c%23/blazor/2025/05/15/thoughts-on-dotnet-10_3-previews</id><content type="html" xml:base="/dotnet/c%23/blazor/2025/05/15/thoughts-on-dotnet-10_3-previews.html"><![CDATA[<p>I’ve been working with .NET at <a href="https://www.howdengroup.com/uk-en" target="_blank">Howden</a> for about 6 months now and, after getting my head around whats available ‘now’ in .NET I have been looking to the future with what will be coming up in .NET 10 later in 2025, in particular those parts that are relevant for folks working with Blazor.</p>

<p>You can read about other previews here: [2025-25-03-thoughts-on-dotnet-10_1-and_10_2-previews]</p>

<p><em>(All views expressed are my own).</em></p>

<p>If I have misunderstood something or you disagree with me I would love to chat 😃 #everydayaschoolday</p>

<p>Full announcement: <a href="https://devblogs.microsoft.com/dotnet/dotnet-10-preview-3/" target="_blank">.NET 10 Preview 3 is now available! - .NET Blog</a></p>

<h1 id="blazor-and-aspnet-core">Blazor and ASP.NET Core</h1>

<h2 id="declarative-model-for-persisting-component-state-">Declarative model for persisting component state 💪</h2>

<p><strong>Who will this benefit:</strong> This is useful for any server-rendered components (i.e. any component that isn’t Interactive WebAssembly <a href="https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-9.0" target="_blank">render mode</a>.</p>

<p><strong>What is this all about:</strong> Persisting component state means saving some data during prerendering and restoring it when the app becomes interactive (in the browser), so there is no need to refetch is and the user experience is sharper.</p>

<p><strong>What’s the current approach:</strong> Currently, there is a lot of boilerplate needed to support this and it was quite manual and involved being careful with serialisation:</p>
<ol>
  <li>Inject PersistentComponentState into your component.</li>
  <li>Register a callback to save state during prerendering.</li>
  <li>Read the state back when the component is interactive.</li>
</ol>

<p>With this new feature, you can just decorate a property with the [SupplyParameterFromPersistentComponentState] attribute.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
// On the server, Forecasts is loaded and persisted.
// On the client, Blazor restores Forecasts automatically—no extra code needed.
@code {
    [SupplyParameterFromPersistentComponentState]
    public WeatherForecast[]? Forecasts { get; set; }

    protected override async Task OnInitializedAsync()
    {
        if (Forecasts is null)
        {
            Forecasts = await WeatherService.GetForecastAsync();
        }https://learn.microsoft.com/en-us/credentials/certifications/azure-fundamentals/?practice-assessment-type=certification
    }
}
</code></pre></div></div>

<h2 id="validation-support-in-minimal-apis-️">Validation support in minimal APIs 🛡️</h2>

<p><strong>Who will this benefit:</strong> anyone that has APIs defined using minimal APIs.</p>

<p><strong>What is this all about</strong>: Minimal APIs are a way to define HTTP API endpoints with very little boilerplate. You typically write them directly in your Program.cs or a similar startup file, using methods like app.MapGet, app.MapPost, etc. They are concise and great for small services or microservices.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    app.MapGet("/hello", () =&gt; "Hello World!");
</code></pre></div></div>

<p>Controllers (classes that inherit from ControllerBase or Controller) are more traditional. They are decorated methods with attributes like [HttpGet], [HttpPost], etc. This approach is more structured and is often used for larger applications.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    [ApiController]
    [Route("[controller]")]
    public class HelloController : ControllerBase
    {
        [HttpGet]
        public string Get() =&gt; "Hello World!";
    }
</code></pre></div></div>
<p>I personally prefer minimal APIs because I find them more lightweight with less boilerplate code. Minimal APIs also feels more like just writing more C# code and feels more ‘organic’ to me. I also like them because of how similar they feel to defining endpoints in Express (popular NodeJS server) which was where I first started.</p>

<p><strong>Current approach:</strong> validation logic <em>inside</em> of the api body with business logic, not as a decorator.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>using System.ComponentModel.DataAnnotations;

public class Person
{
    [Required]
    public string Name { get; set; } = default!;
    [Range(0, 120)]
    public int Age { get; set; }
}

app.MapPost("/people", (Person person) =&gt;
{
    var validationResults = new List&lt;ValidationResult&gt;();
    var context = new ValidationContext(person);
    if (!Validator.TryValidateObject(person, context, validationResults, true))
    {
        return Results.ValidationProblem(validationResults
            .ToDictionary(
                v =&gt; v.MemberNames.FirstOrDefault() ?? "",
                v =&gt; new[] { v.ErrorMessage ?? "" }
            ));
    }

    return Results.Ok(person);
});
</code></pre></div></div>

<p>New approach:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>app.MapPost("/products",
    ([EvenNumber(ErrorMessage = "Product ID must be even")] int productId, [Required] string name)
        =&gt; TypedResults.Ok(productId))
    .DisableValidation();

</code></pre></div></div>

<p>Validation support looks useful and is something I will bear in mind when we need consider adding more endpoints. This certainly makes it more attractive to use them with our app.</p>

<p>More info:
<a href="https://github.com/dotnet/core/blob/main/release-notes/10.0/preview/preview3/aspnetcore.md#validation-support-in-minimal-apis" target="_blank">core/release-notes/10.0/preview/preview3/aspnetcore.md at main · dotnet/core · GitHub</a></p>

<h1 id="c-14-new-features-in-103">#C 14 new features in 10.3</h1>

<h2 id="null-conditional-assignment-">Null-conditional assignment 🤫</h2>

<p>This assigns a value to a property or field only if the containing instance exists. This is a neat way to reduce boilerplate and I’m already used to using nifty shortcuts for working with nullable <em>properties</em> with a more compact syntax (e.g. <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and-" target="_blank">null conditionals</a>) so making use of this syntax for nullable <em>objects</em> seems like a logical extension. <strong>I like this!</strong></p>

<p>More here: <a href="https://github.com/dotnet/core/blob/main/release-notes/10.0/preview/preview3/csharp.md#null-conditional-assignment" target="_blank">core/release-notes/10.0/preview/preview3/csharp.md at main · dotnet/core · GitHub</a></p>

<h2 id="extension-members-️">Extension members ⛓️</h2>

<p><strong>Whats this all about:</strong> extension methods are a way of extending a C# class - basically defining methods in a separate file the main class definition. This is useful for extending third-party libraries (I have never actually had to do this) and also to make unit testing functionality easier (which is a pattern I have seen a fair bit).</p>

<p><strong>What the current approach is:</strong> the end result is still the same, but the new extension blocks make code easier to read and mentally group things together:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static class Extensions
{
    extension(IEnumerable&lt;int&gt; source)  // new!
    {
        public IEnumerable&lt;int&gt; WhereGreaterThan(int threshold)
            =&gt; source.Where(x =&gt; x &gt; threshold);

        public bool IsEmpty
            =&gt; !source.Any();
    }
}

var list = new List&lt;int&gt; { 1, 2, 3, 4, 5 };
var large = list.WhereGreaterThan(3);
if (large.IsEmpty)
{
    Console.WriteLine("No large numbers");
}
else
{
    Console.WriteLine("Found large numbers");
}
</code></pre></div></div>

<p><strong>Benefits of the new approach</strong> I think this makes extension functionality eaisier to manage, <strong>but a word of caution:</strong> I can see this potentially getting a bit out of control; my instinct is that the ‘supporting’ methods in a block should be small, lean and as simple as possible to avoid the extension methods becoming bloated and larger than the class they are meant to extend. E.g. the examples online are for little helpers like <code class="language-plaintext highlighter-rouge">IsEmpty()</code> which I think is appropriate, but I would want to keen an eye on this. Perhaps one for an internal C# style guide to define when a method in an extension block becomes ‘too big’ 🤔</p>

<h1 id="conclusion">Conclusion</h1>

<p>Thanks for reading. I hope you found this interesting and/or useful! I certainly find this a useful way to learn and reflect on whats coming up, so that me and my team are prepared.</p>]]></content><author><name></name></author><category term="dotnet" /><category term="c#" /><category term="blazor" /><summary type="html"><![CDATA[I’ve been working with .NET at Howden for about 6 months now and, after getting my head around whats available ‘now’ in .NET I have been looking to the future with what will be coming up in .NET 10 later in 2025, in particular those parts that are relevant for folks working with Blazor.]]></summary></entry><entry><title type="html">Thoughts on .NET 10.1 and 10.2 previews</title><link href="/dotnet/c%23/blazor/2025/03/25/thoughts-on-dotnet-10_1-and_10_2-previews.html" rel="alternate" type="text/html" title="Thoughts on .NET 10.1 and 10.2 previews" /><published>2025-03-25T09:30:57+00:00</published><updated>2025-03-25T09:30:57+00:00</updated><id>/dotnet/c%23/blazor/2025/03/25/thoughts-on-dotnet-10_1-and_10_2-previews</id><content type="html" xml:base="/dotnet/c%23/blazor/2025/03/25/thoughts-on-dotnet-10_1-and_10_2-previews.html"><![CDATA[<p>I’ve been working with .NET at <a href="https://www.howdengroup.com/uk-en" target="_blank">Howden</a> for about 6 months now and, after getting my head around whats available ‘now’ in .NET I have been looking to the future with what will be coming up in .NET 10 later in 2025.</p>

<p>I’ve been following the preview releases (10.1 and 10.2 are here!). Below are my thoughts on what’s been announced and some of the points that are of more interest to me in my team working with Blazor hybrid WASM web apps.</p>

<p>If I have misunderstood something or you disagree with me I would love to chat 😃 #everydayaschoolday</p>

<p><em>(All views expressed are my own).</em></p>

<h2 id="overall-thoughts-on-net-10-so-far-">Overall thoughts on .NET 10 so far 🥅</h2>

<p>A lack of clarity on the direction, mission and aims.</p>

<p>I’m not completely clear on what the vision is for .NET 10 to be honest. I’m only 6 months into my journey with .NET, so perhaps my expectations are not quite right. But I was expecting a clearer indication of what this release is aiming for - in the same way that new versions of the iPhone have a clear headline message (even if people feel that hardware innovation is becoming harder…). There are some general improvements across the .NET ecosystem and there are some new AI capabilities in the work if you are building your own AI agents, but I haven’t seen a clear headline that helps me see the direction where .NET is heading.</p>

<p>Anyway, let’s look at the relevant features in .NET 10.1 and 10.2 previews and <em>my opinionated comments (in italics).</em></p>

<h2 id="c-14-">C# 14 🦭</h2>

<ol>
  <li><strong>Field backed properties</strong> - using the new <code class="language-plaintext highlighter-rouge">field</code> keyword means the compiler will automatically generate the backing field. <em>A nice bit of syntactic sugar, but it’s a minor improvement. It also means newer classes could look a bit different to older style classes and reduce readability across the codebase.</em></li>
  <li><strong>Implicit ‘Span’ conversions</strong> - Spans are wrappers around buffers. <em>Not relevant to what I the projects I am working on, as this is a bit too low level.</em></li>
  <li><strong>Unbound generic support for nameof</strong> - <code class="language-plaintext highlighter-rouge">nameof(List&lt;&gt;)</code> now evaluates to <code class="language-plaintext highlighter-rouge">List</code>, but before wouldn’t have worked. <em>Not sure of the situation where you would need this offhand, but useful to know.</em></li>
  <li><strong>Types no longer required with parameter modifiers</strong>. When using e.g. the <code class="language-plaintext highlighter-rouge">out</code> param modifier in a lambda you previously had to specify the type of variable, but not any longer.</li>
</ol>

<p>Before:
    <code class="language-plaintext highlighter-rouge">TryParse&lt;int&gt; parse1 = (text, int out result) =&gt; Int32.TryParse(text, out result);</code></p>

<p>in C# 14 you won’t need to specify that result is an int:  <code class="language-plaintext highlighter-rouge">TryParse&lt;int&gt; parse1 = (text, out result) =&gt; Int32.TryParse(text, out result);</code></p>

<p><em>I think this is useful for readability when there is a verbose type that is returned, as long as the variable is suitably named so the reader can infer that the variable is probably a number/string/date etc when scanning the lambda.</em></p>

<ol>
  <li><strong>Partial constructors</strong> - similar to how classes can already be defined over multiple files, constructors can now be as well. <em>I’m not sure of the benefit of this; if you need to split your constructor over multiple files because the constructor is too large then this is a sign your constructor is too big, perhaps? It seems like a marginal improvement and I think this could lead to more confusion. Happy to be proved wrong.</em></li>
</ol>

<h2 id="blazor">Blazor🔥</h2>

<ol>
  <li><strong>New ReconnectModal available out of the box</strong> - <em>useful for folks who are working with server-rendered Blazor projects.</em></li>
  <li><strong>NavigateTo method now doesnt scroll to top of page when same page nav</strong> - <em>again, more relevant to server-rendered Blazor projects.</em></li>
  <li><strong>QuickGrid styling improvements</strong> - I don’t touch QuickGrid much so I would have to look in more whether this is relevant to our use cases in my team.</li>
  <li><strong>NavLink.Matchall tweaks</strong> - NavLink is a Blazor components that sets the ‘active’ CSS class when a link matches the URL. In .NET 10, links will retain the <code class="language-plaintext highlighter-rouge">active</code> class if the URL <em>path</em> matches but the query string or fragment change. <em>This may not affect you, and I don’t believe it will affect us given the way we use NavLinks in our projects</em></li>
</ol>

<h2 id="conclusion">Conclusion</h2>

<p>Thanks for reading. I hope you found this interesting and/or useful! I certainly find this a useful way to learn and reflect on whats coming up, so that me and my team are prepared.</p>

<p>##Read more</p>

<ul>
  <li><a href="https://devblogs.microsoft.com/dotnet/dotnet-10-preview-1/#%F0%9F%93%A2-.net-10-discussions" target="_blank">.NET 10 Preview 1 is now available! - .NET Blog</a>
<a href="https://learn.microsoft.com/en-gb/dotnet/csharp/whats-new/csharp-14" target="_blank">What’s new in C# 14 | Microsoft Learn</a></li>
  <li>Subscribe to the .NET newsletter to get updates: <a href="https://devblogs.microsoft.com/dotnet/newsletter/" target="_blank">Newsletter - .NET Blog</a></li>
</ul>]]></content><author><name></name></author><category term="dotnet" /><category term="c#" /><category term="blazor" /><summary type="html"><![CDATA[I’ve been working with .NET at Howden for about 6 months now and, after getting my head around whats available ‘now’ in .NET I have been looking to the future with what will be coming up in .NET 10 later in 2025.]]></summary></entry><entry><title type="html">My first 3 weeks learning C# and Blazor</title><link href="/blazor/c%23/introduction/2024/08/30/learning-blazor-and-csharp.html" rel="alternate" type="text/html" title="My first 3 weeks learning C# and Blazor" /><published>2024-08-30T08:30:57+00:00</published><updated>2024-08-30T08:30:57+00:00</updated><id>/blazor/c%23/introduction/2024/08/30/learning-blazor-and-csharp</id><content type="html" xml:base="/blazor/c%23/introduction/2024/08/30/learning-blazor-and-csharp.html"><![CDATA[<p>After a few years working in product managemenent roles and more ‘generalist roles’ (founding an <a href="https://www.sync-savings.com/" target="_blank">embedded finance startup</a>), I am excited to be moving back into a full-time software engineering role at <a href="https://www.howdeninsurance.co.uk/?bridging=off&amp;int=2123&amp;keyword=howden%20insurance&amp;gclid=Cj0KCQjw28W2BhC7ARIsAPerrcITIywhGDjjxvcSGicSRtryxuikt4B_o7A3Ymztfsm3566uwokdpM4aAnmOEALw_wcB" target="_blank">Howden</a>. I’m looking forward to using the skills I have gained from these roles that are ‘adjacent’ to software engineering (perhaps another blog post on this sometime…) in my new role.</p>

<p>While I have remained close to the code and written <em>some</em> code in the past few years (mainly building prototypes etc.), I haven’t been coding full time for a while. Plus, I haven’t worked with C# or <a href="https://learn.microsoft.com/en-us/aspnet/core/blazor/?view=aspnetcore-8.0" target="_blank">Blazor</a> before, so I was going to have to sharpen up my programming skills <em>and</em> learn a new language/framework at the same time.</p>

<p>So, here are my first thoughts on C# and Blazor from an intensive 3 weeks of learning before starting my new role, and how these technologies compare to others I have worked with, in my opinion.</p>

<p>Please feel free to message me on <a href="https://www.linkedin.com/in/sam-ollason-1b404593/" target="_blank">LinkedIn</a> with your thoughts, if I have misunderstood something, or if you have a different point of view 😀.</p>

<p><em>(All views expressed are my own).</em></p>

<h1 id="my-background">My background</h1>

<p>To set the scene: I’ve been in full-time software dev roles for over 6 years, starting in front-end web development roles (React, <a href="https://angularjs.org/" target="_blank">AngularJS</a> and also on the backend with JavaScript/TypeScript). I have also worked with C++.</p>

<p>So I have experience learning new front-end frameworks and working with statically typed languages.</p>

<h1 id="how-i-approached-learning">How I approached learning</h1>

<p>In the last few weeks I went through <a href="https://www.udemy.com/course/blazor-deep-dive-from-beginner-to-advanced/learn/lecture/42460350#overview" target="_blank">this Blazor course on Udemy</a> and this <a href="https://academy.zerotomastery.io/courses/enrolled/2025735" target="_blank">C# course on ZTM</a>. I’ve taken notes using Notion and used <a href="https://zorbi.com/" target="_blank">Zorbi</a> to automatically generate revision flashcard from Notion that I run through each morning. I have also been doing lots of the simpler katas on <a href="https://www.codewars.com/dashboard" target="_blank">Codewars</a> each morning to get my muscle memory used to the syntax and foundations of C# (where brackets need to go, filtering arrays, splitting strings etc.).</p>

<p>There is probably another blog post I could write reflecting on the difference between making time to learn <em>new material</em> and <em>reinforcing existing knowledge</em> in such a fast-moving industry like software engineering.</p>

<h1 id="structure">Structure</h1>

<p>What immediately struck me was how structured C# is as a language, and .NET is as a framework/toolkit. This felt quite different to working with JavaScript which has some strange quirks and edges. For instance, JavaScript’s equality operators have lots of gotchas, working with null always feels weird and I’ve never quite found a library I’m happy with to work with dates.</p>

<p>The best analogy of how they <em>feel</em> to me is that JavaScript is a lifeform that has evolved in a petri dish thats been left out (like <a href="https://www.acs.org/education/whatischemistry/landmarks/flemingpenicillin.html#:~:text=In%201928%2C%20at%20St.%20Mary's,number%20of%20deaths%20from%20infection." target="_blank">penicillin</a>), whereas C# is a robot built in a factory in a systemtic and structured way. Neither is better or worse - just different. And I think it makes sense given JavaScript was famously initially created in 10 days to add interactivity to web pages and then grew into what is is today.</p>

<p>Also, I really like C#’s <a href="https://learn.microsoft.com/en-us/dotnet/csharp/linq/" target="_blank">Linq</a> as a centralised and consistent way of working with enumerable data structures and I have found that when doing my daily Codewars practices that I reach for these as my first port of call for filtering, appending etc.</p>

<h1 id="bouncing-up-against-the-walls">Bouncing up against the walls</h1>

<p>I always find it interesting to find the limitations of a front-end framework and how this is handled. I remember working with AngularJS as it was evolving in 2015/16 and components struggled to contain reusable logic gracefully, and so ‘<a href="https://dev.to/omnoms/angularjs-component-directives-306" target="_blank">component directives</a>’ were introduced …but still had lots of workarounds (and I seem to remember what felt like hacks). React has Refs and introduced ‘Context’ to avoid props drilling and, of course, React introduced <a href="https://react.dev/reference/react/hooks" target="_blank">Hooks</a> to overcome the challenges of sharing stateful logic between components.</p>

<p>With C#, so far, the main thing I have found is hooking into JavaScript to run alerts/confirmation pop-ups. I understand why this is necessary, but it does feel a bit ‘unclean’ having to rely on JavaScript to overcoming (what feels like) a C# shortcoming. The purist in me would want to only work in C# if possible. I haven’t yet made up my mind whether this feels like a code smell or not.</p>

<h1 id="scaffolding">Scaffolding</h1>

<p>I was pleasantly suprised by how easy it is to configure and manage Blazor apps. I remember the days of having to manually configure Webpack for front-end projects which was a complete nightmare. I know things like Vite and NextJS have moved things forwards but working with these JavaScript bundlers always feel a bit like hardwork. Perhaps it’s partly that C# and Blazor is all Microsoft instead of a created by the community/third parties. I think I prefer a clearer and more idiomatic way of doing things instead of a huge array of choice, at least at the moment.</p>

<h1 id="what-i-am-excited-to-explore-next">What I am excited to explore next</h1>

<p>I’ve enjoyed the journey so far - I quite like the humbling experience of feeling like a novice, despite feeling uncomfortable a lot of the time in doing so.</p>

<ul>
  <li>I am looking forward to getting more into <a href="https://bunit.dev/" target="_blank">bUnit</a> for testing Blazor UIs</li>
  <li>I’ve gotten really interested in <a href="https://craftbettersoftware.com/p/how-i-write-1000s-tests-with-little" target="_blank">property testing</a> as a way of improving unit test coverage and want to play around with <a href="https://www.production-ready.de/2023/06/10/property-based-testing-in-csharp-en.html" target="_blank">FsCheck</a> a bit more</li>
  <li>I’m keen to start looking more into <a href="https://docs.reqnroll.net/latest/quickstart/index.html" target="_blank">Reqnroll</a> as a way of generating ‘<a href="https://www.youtube.com/watch?v=knB4jBafR_M" target="_blank">executable specifications</a>’ for Blazor apps</li>
</ul>]]></content><author><name></name></author><category term="blazor" /><category term="c#" /><category term="introduction" /><summary type="html"><![CDATA[After a few years working in product managemenent roles and more ‘generalist roles’ (founding an embedded finance startup), I am excited to be moving back into a full-time software engineering role at Howden. I’m looking forward to using the skills I have gained from these roles that are ‘adjacent’ to software engineering (perhaps another blog post on this sometime…) in my new role.]]></summary></entry><entry><title type="html">Symbols in JavaScript</title><link href="/2020/12/18/symbols-in-javascript.html" rel="alternate" type="text/html" title="Symbols in JavaScript" /><published>2020-12-18T13:00:57+00:00</published><updated>2020-12-18T13:00:57+00:00</updated><id>/2020/12/18/symbols-in-javascript</id><content type="html" xml:base="/2020/12/18/symbols-in-javascript.html"><![CDATA[<p>Recently I was upgrading a library and found that it broke some of our unit tests. The reason it was failing was 
because the test infrastructure was looking for keys in the mocked request that weren’t being found anymore. 
It turns out that the new keys were in fact <strong>symbolic keys</strong>.
That investigation lead to me learning more about JavaScript symbols. These were the
notes I wish I had last week! Hopefully they help you too.</p>

<h2 id="what-are-they">What are they</h2>
<p>JavaScript has two categories of types: primitives and objects. 
Technically, <code class="language-plaintext highlighter-rouge">null</code> is both a primitive and an object, 
so the more accurate definition is of a primitive is: <em>If it isn’t an object and has 
no methods then it’s a primitive</em> (see <a href="https://developer.mozilla.org/en-US/docs/Glossary/Primitive" target="_blank">here</a>).</p>

<p>A few years ago the Symbol primitive was added to the language. I read about it at the time and remember getting the impression that 
it’s a bit of a niche corner of the language that most people won’t
need to bother with most of the time.
I think that’s still correct, but I happened to run into a situation recently where
I needed to know what they were and how they worked in more detail.</p>

<h1 id="why-use-them">Why use them?</h1>
<p>They provide a way of generating unique identifiers.</p>

<h1 id="example-of-why-they-are-useful">Example of why they are useful</h1>

<p>They seem to be used mainly for ‘hidden’ fields on objects. 
Although it is still possible to access them, the point is that their implementation
makes it difficult to access. They aren’t found using <code class="language-plaintext highlighter-rouge">for...in</code> loops or
by accessing <code class="language-plaintext highlighter-rouge">Object.keys()</code>.</p>

<p>This is useful if you want to set flags that you don’t want developers to accidentally set. 
The example that comes up a lot online is to indicate whether a list is sorted or not. 
This is useful metadata that you don’t want someone to accidentally overrite.</p>

<p>Read down below to lern about how to access symbolic keys.</p>

<h2 id="how-to-use-them">How to use them</h2>

<h1 id="what-they-feel-like">What they feel like</h1>
<p>As mentioned above, they are a primitive in the JavaScript language, but the way they are written
and used makes them feel kind of like an object, but with some noticeable differences.</p>

<h1 id="creating-new-ones">Creating new ones</h1>
<p>For instance, you can’t need to use the <code class="language-plaintext highlighter-rouge">new</code> operator.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let sym1 = Symbol() // correct
let sym1 = new Symbol()  // TypeError
</code></pre></div></div>

<p>You can wrap them up in an object if you really want to, but it’s not straightforward:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>let sym = Symbol('foo')
typeof sym      // "symbol"
let symObj = Object(sym)
typeof symObj   // "object
</code></pre></div></div>

<p>And I’m not sure yet why you would want to do this.</p>

<h1 id="uniqueness">Uniqueness</h1>
<p>Something else that is interesting that’s worth mentioning here is that each ‘symbol’ is unique:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// each of these is a different symbol
let sym1 = Symbol()
let sym2 = Symbol('foo')
let sym3 = Symbol('foo')

Symbol('foo') === Symbol('foo')  // false

</code></pre></div></div>

<h1 id="global-keys">Global keys</h1>
<p>You can create symbols in such a way that they are globally available throughout your code base using <code class="language-plaintext highlighter-rouge">Symbol.for()</code>,
which could be used really well or abused really well!</p>

<h1 id="accessing-symbolic-keys---indexing">Accessing symbolic keys - indexing</h1>

<p>This was where my original problem was. I was trying to access the value of the nested ‘path’ field
in this object:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Request {
    size: 0,
    timeout: 0,
    follow: 20,
    compress: true,
    counter: 0,
    agent: undefined,
    [Symbol(Body internals)]: { body: null, disturbed: false, error: null },
    [Symbol(Request internals)]: {
        method: 'GET',
        redirect: 'follow',
        path: 'mypath'
        ...
    }
}
</code></pre></div></div>

<p>It turns out that doing <code class="language-plaintext highlighter-rouge">request['Symbol(Request internals)']</code> doesn’t work.</p>

<p>I mentioned above that when symbols are used as keys in objects they can’t be accessed through
‘the standard’ methods.</p>

<p>To access them I had to use <code class="language-plaintext highlighter-rouge">Object.getOwnPropertySymbols(request)</code> which returns an array of symbols. To find
the particular symbol I had to use a little helper which searches through the array and finds a particular element.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const sym = Object.getOwnPropertySymbols(data).find(s =&gt; String(s) === 'Symbol(Request internals)')
const path = request[sym].path

</code></pre></div></div>

<p>However, that approach <a href="https://stackoverflow.com/questions/59118271/using-symbol-as-object-key-type-in-typescript" target="_blank">doesn’t agree with TypeScript just quite yet</a>
(as at December 2020), so you will have to add <code class="language-plaintext highlighter-rouge">@ts-ignore</code> above where <code class="language-plaintext highlighter-rouge">sym</code> is used!</p>

<h1 id="accessing-symbolic-keys---methods">Accessing symbolic keys - methods</h1>
<p>Sometimes you will get lucky and the object you are working with has some methods to access symbolic keys
easily. I also had to access the ‘headers’ field in a request as part of this test and fortunately there
is a method that just takes care of this nicely in this object. You can see more <a href="https://stackoverflow.com/questions/50060008/nodejs-parse-fetch-response-containing-object-symbolmap" target="_blank">here</a>.</p>

<h2 id="more-reading">More reading</h2>
<ul>
  <li><a href="https://stackoverflow.com/questions/50060008/nodejs-parse-fetch-response-containing-object-symbolmap/50856907" target="_blank">https://stackoverflow.com/questions/50060008/nodejs-parse-fetch-response-containing-object-symbolmap/50856907</a></li>
  <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol" target="_blank">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol</a></li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[Recently I was upgrading a library and found that it broke some of our unit tests. The reason it was failing was because the test infrastructure was looking for keys in the mocked request that weren’t being found anymore. It turns out that the new keys were in fact symbolic keys. That investigation lead to me learning more about JavaScript symbols. These were the notes I wish I had last week! Hopefully they help you too.]]></summary></entry></feed>