<![CDATA[Daniel Little Dev]]>https://daniellittle.devGatsbyJSSat, 20 Feb 2021 02:20:54 GMT<![CDATA[Don't Ignore Your Functions]]>https://daniellittle.dev/dont-ignore-your-functionshttps://daniellittle.dev/dont-ignore-your-functionsMon, 05 Oct 2020 20:00:00 GMT<p>Ignoring return values can often be dangerous in subtle ways but you may be so used to doing it that you don't even notice anymore. It's likely that at some point you have run into an issue caused by forgetting to use the return value of a function. It's even more likely you throw away the return values of functions without thinking too much about it. Most of the time there's no real impact of doing so, and if there is it's certainly not immediate. But if you find yourself doing this often it is important to ask why. Presumably, the function is returning this value for a reason? Is there something wrong with the design of the API, or are you missing something important?</p> <h2>Adding to a date doesn't change it</h2> <p>Have you ever seen code like this?</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DateTime</span><span class="token punctuation">(</span><span class="token number">2000</span><span class="token punctuation">,</span> <span class="token number">01</span><span class="token punctuation">,</span> <span class="token number">01</span><span class="token punctuation">)</span><span class="token punctuation">;</span> date<span class="token punctuation">.</span><span class="token function">AddYears</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>$<span class="token string">"{date.ToShortDateString()}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>It looks pretty straightforward, but there's a bug in this code. If you're familiar with the dotnet <code class="language-text">DateTime</code> API it might be an obvious one but it can be subtle and confusing if you've never used it before.</p> <p>The issue is that when you call <code class="language-text">AddYears</code> it doesn't modify the date, instead it returns a brand new date. Therefore when <code class="language-text">WriteLine</code> is called the value will still say <code class="language-text">2000/01/01</code> instead of <code class="language-text">2001/01/01</code> like you may have expected.</p> <p>To get this to work correctly you'd have to capture the new date by assigning the new value to the date variable, like so.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DateTime</span><span class="token punctuation">(</span><span class="token number">2000</span><span class="token punctuation">,</span> <span class="token number">01</span><span class="token punctuation">,</span> <span class="token number">01</span><span class="token punctuation">)</span><span class="token punctuation">;</span> date <span class="token operator">=</span> date<span class="token punctuation">.</span><span class="token function">AddYears</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>$<span class="token string">"{date.ToShortDateString()}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>So why does <code class="language-text">AddYears</code> return a new date object instead of adding a year to the existing date? It does this because date is an immutable type. This means that once you create a date you can never modify or change it, in any way. If you need a different date you'll always need to create a new one.</p> <p>Immutability itself is a very useful technique because it can help manage complexity due to limiting the possibilities you have to consider; there is only one way to change the date, replace it. However, issues like the example above can be hard to find if you're not looking for them. Wouldn't it be great if the C# compiler could detect issues like this and prevent you from making the mistake in the first place!</p> <h2>Async and you forgot to await</h2> <p>Let's look at a different problem for a moment. Say you had an async function which calls out to two async functions but you forget to await one of them.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">async</span> Task<span class="token operator">&lt;</span>ActionResult<span class="token operator">&lt;</span>Resource<span class="token operator">>></span> <span class="token function">GetResource</span><span class="token punctuation">(</span><span class="token keyword">string</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">AuditRequestAsync</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Forgot to await this, oops</span> <span class="token keyword">return</span> <span class="token keyword">await</span> <span class="token function">LoadResourceAsync</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>In this case, you'll get a warning from the C# compiler telling you that there might be a missing await. This is fantastic because the majority of the time this is almost certainly a bug. However, depending on how closely you monitor your warning, it's still possible to compile the app with the default compiler options. But what happens if we have the same function but without the async keyword, like so.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp">Task<span class="token operator">&lt;</span>ActionResult<span class="token operator">&lt;</span>Resource<span class="token operator">>></span> <span class="token function">GetResource</span><span class="token punctuation">(</span><span class="token keyword">string</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">AuditRequestAsync</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token function">LoadResourceAsync</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Semantically this function is exactly the same, it also suffers from the same bug but this time there's not even a warning. I've found this kind of issue to more common than it appears because a function can start off by only returning a task without needing the async keyword. In the example above if the <code class="language-text">AuditRequestAsync</code> function was added later on, or by a different author, they could forget to add the async keyword and the program will still happily compile.</p> <p>To make matters worst, the function might work in some cases, but fail in others. The <code class="language-text">AuditRequestAsync</code> function will still run, but without <code class="language-text">await</code> there is no guarantee the caller will still be around when it finishes. In some cases you might get an error regarding <code class="language-text">multiple active result sets</code> if they both make database calls. In others, you might not notice anything is wrong at all. Issues like these can often lie dormant until other changes trigger them, or result in indeterministic (or at the very least non obvious) behaviour making them extremely hard to track down and fix.</p> <h2>Implicitly ignoring functions is dangerous</h2> <p>What these examples have in common is that the value returned by a function (<code class="language-text">AddYears</code> and <code class="language-text">AuditResourceRequestAsync</code>) was implicitly ignored, resulting in a bug. If the compiler had issued a warning or an error indicating that the value was unused or implicitly ignored these issues could have been caught earlier or prevented entirely.</p> <p>There are also many more scenarios that suffer from this problem. For example using APIs like LINQ, Reactive Extensions, using Structs, and all immutable types, are cases where forgetting to use the value is almost certainly a bug. Even regular functions, particularly those that return values without side effects would benefit from making it obvious that a return value was ignored or forgotten.</p> <h2>Explicitly ignoring functions is safer</h2> <p>Instead of implicitly throwing away unused values, if we don't want to use a value we should explicitly discard it.</p> <p>To help catch unused values you could use a custom analyzer to create a warning for all unused values, not just a missing await inside an async function. There are no analyzers that do this yet, however, there are a few similar existing analyzers for some of these cases, such as <a href="https://docs.particular.net/nservicebus/operations/nservicebus-analyzer">async await</a>.</p> <p>Once there are warnings for unused return values it becomes clearer that an unused value is either a bug or something that can be explicitly discarded.</p> <p>A task, for example, would result in a warning about a possible missing await. If you do want to ignore the task then you can use a <code class="language-text">standalone discard</code> to let others know you don't care about it.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp">_ <span class="token operator">=</span> Task<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// Explicitly discard the result</span></code></pre></div> <p>This makes it clear that you made a conscious decision not to use the value. It shows other developers that a decision was made not to use the value as opposed to forgetting to use it.</p> <p>When someone else reads that code it is the difference between:</p> <ul> <li><em>Did they</em> <em>forget to use the return value? I'll need to investigate, versus...</em></li> <li><em>They've chosen to ignore the</em> <em>return value</em>. <em>I can move on.</em></li> </ul> <p>Making things more explicit will prevent bugs and save you and others a lot of time.</p> <h2>Would this really work</h2> <p>There's a lot of code out there today which was written without explicit discards in mind. And I don't expect the world of C# to change drastically overnight. Nevertheless, the aim of this article is to get more you interested in an analyzer that warns developers about unused return values in the same way your editor warns you about an unused variable today.</p> <p>You may still be wondering if so much C# code was written without explicit ignores in mind, would this be even practical to do in C#? Recently I've been doing a lot of dotnet development using F# which does emit compiler warning if a function return value is not used. So I can say that even with the dotnet as it exists today, I have been pleasantly surprised. I didn't need to discard half as many values as I thought I would.</p> <p>The large majority of code didn't need a single discard. There were only a few cases where I needed to use a discard, for example discarding the value at the end of a mutable fluent API.</p> <p>In that case, I would use an extension method to explicitly "cap off" the expression.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp">builder <span class="token punctuation">.</span><span class="token generic-method"><span class="token function">RegisterType</span><span class="token punctuation">&lt;</span><span class="token class-name">HttpClient</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AsSelf</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">InstancePerLifetimeScope</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">Ignore</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// &lt;- Takes a type &lt;T> and returns a void</span></code></pre></div> <p>I did however still run into at least one bug where I explicitly discarded a value that I shouldn't have. In the end, I found that even explicitly discarding values was something that should be done sparingly. Whenever I discarded a return value I found myself rethinking the code instead.</p> <p>I was more likely to use or log a status code or return code.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> response <span class="token operator">=</span> <span class="token keyword">await</span> httpClient<span class="token punctuation">.</span><span class="token function">PostAsync</span><span class="token punctuation">(</span>url<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> log<span class="token punctuation">.</span><span class="token function">Information</span><span class="token punctuation">(</span><span class="token string">"Responded with {StatusCode}"</span><span class="token punctuation">,</span> response<span class="token punctuation">.</span>StatusCode<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>If I wanted to run a task in the background I kept the task in a Task service and it simplified error handling for all background tasks.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp">BackgroundService<span class="token punctuation">.</span><span class="token function">Register</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// Instead of</span> _ <span class="token operator">=</span> Task<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// Hope you handled the exceptions in here</span></code></pre></div> <p>If I used the builder pattern or a fluent API I considered using an immutable API and returning the value instead of a using a mutable one. For example using LINQ vs using the List API.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">public</span> IEnumerable<span class="token operator">&lt;</span>Out<span class="token operator">></span> <span class="token function">GetResults</span><span class="token punctuation">(</span>IEnumerable<span class="token operator">&lt;</span>In<span class="token operator">></span> items<span class="token punctuation">)</span> <span class="token operator">=></span> items <span class="token punctuation">.</span><span class="token function">Where</span><span class="token punctuation">(</span>x <span class="token operator">=></span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> <span class="token operator">*</span><span class="token operator">*</span><span class="token punctuation">.</span><span class="token function">Select</span><span class="token punctuation">(</span>x <span class="token operator">=></span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">OrderBy</span><span class="token punctuation">(</span>x <span class="token operator">=></span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span></code></pre></div> <p>I'm also cautious of functions that don't return values but that's another story.</p> <h2>I'm interested but maybe not convinced</h2> <p>Whenever I first stumble across a new concept or technique I find that I need to play with it for a while to start to get a good feel for how it works. Have a go at building an analyzer and see where the warnings are. Try writing a program from scratch with the warnings on. Turn on warnings as errors so you aren't tempted to take shortcuts and follow where the analyzer takes you.</p> <p>But most importantly, if you find yourself discarding values without using them, ask yourself why.</p><![CDATA[Type-Safe Hypermedia Controls]]>https://daniellittle.dev/type-safe-hypermedia-controlshttps://daniellittle.dev/type-safe-hypermedia-controlsSun, 12 Jul 2020 08:00:00 GMT<p>Hypermedia Controls in REST provide links and actions with each response pointing to related resources. This concept is a powerful tool that enables the server to remain in control of links and access. If you're not sure what I mean by this, take a moment to read my previous article on my approach regarding <a href="/practical-hypermedia-controls">Practical Hypermedia Controls</a>.</p> <p>Enter Typescript. Adding types to JavaScript allows us to write safer code, so naturally I wanted to figure out how to make a Hypermedia Controls type-safe. Typically when writing a type-safe API you might start out with something like this.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">const</span> <span class="token function-variable function">api</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">fetch<span class="token punctuation">:</span> Fetch</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> getAccount<span class="token punctuation">:</span> <span class="token keyword">async</span> <span class="token punctuation">(</span>id<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token parameter">AccountResource</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/account/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>id<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> jsonGetOptions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> AccountResource<span class="token punctuation">;</span> <span class="token punctuation">}</span> updateAccount<span class="token punctuation">:</span> <span class="token keyword">async</span> <span class="token punctuation">(</span>account<span class="token punctuation">:</span> AccountResource<span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token parameter">AccountResource</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/account/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>account<span class="token punctuation">.</span>id<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token function">jsonPutOptionsWith</span><span class="token punctuation">(</span>account<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> AccountResource<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre></div> <p>In this example, the <code class="language-text">Request</code> and <code class="language-text">Response</code> types are strongly typed but the URL is hardcoded and you can't tell when you'd have access or who has access to this endpoint. Using Hypermedia Controls can provide that missing context. Links and actions are related to a resource, and the server can dictate if or when the various links and actions are available.</p> <p>In order to see how to combine these two concepts, let's look at what the usage of type-safe Hypermedia controls would look like.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token comment">// Fetch a root resource</span> <span class="token keyword">const</span> account <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetchAccount</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span> <span class="token keyword">const</span> accountHypermedia <span class="token operator">=</span> <span class="token function">accountHypermedia</span><span class="token punctuation">(</span>account<span class="token punctuation">)</span> <span class="token keyword">const</span> accountUpdate <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token operator">...</span>account<span class="token punctuation">,</span> email<span class="token punctuation">:</span> <span class="token string">"daniellittle@elsewhere"</span> <span class="token punctuation">}</span> <span class="token comment">// Invoke the Update action</span> <span class="token keyword">const</span> updatedAccount <span class="token operator">=</span> <span class="token keyword">await</span> accountHypermedia<span class="token punctuation">.</span>actions<span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>updatedAccount<span class="token punctuation">)</span> <span class="token comment">// &lt;- Typechecked!</span></code></pre></div> <p>In this example the account email address is being updated and then the Hypermedia Controls are used to update the resource. Fetching the account resource contains the raw Hypermedia Controls but passing the resource into the <code class="language-text">accountHypermedia</code> function transforms the hypermedia into a type safe API style object. There are a few interesting things happening here, so let's peel back the covers.</p> <h2>Types for Links and Actions</h2> <p>First, Let's take a look at what the <code class="language-text">AccountResource</code> type looks like.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">export</span> <span class="token keyword">type</span> AccountResource <span class="token operator">=</span> <span class="token punctuation">{</span> id<span class="token punctuation">:</span> Identifier username<span class="token punctuation">:</span> <span class="token builtin">string</span> name<span class="token punctuation">:</span> <span class="token builtin">string</span> email<span class="token punctuation">:</span> <span class="token builtin">string</span> _links<span class="token punctuation">:</span> <span class="token punctuation">{</span> self<span class="token punctuation">:</span> Relationship <span class="token punctuation">}</span> _actions<span class="token punctuation">:</span> <span class="token punctuation">{</span> activate<span class="token operator">?</span><span class="token punctuation">:</span> Relationship deactivate<span class="token operator">?</span><span class="token punctuation">:</span> Relationship update<span class="token punctuation">:</span> Relationship <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>The Hypermedia Controls are statically defined inside of the <code class="language-text">_links</code> and <code class="language-text">_actions</code> properties which contain all the well known relationships. Looking at these relationships we can see the resource always contains a <code class="language-text">self</code> link and an <code class="language-text">update</code> action but optionally contains <code class="language-text">activate</code> and <code class="language-text">deactivate</code>. It's important to note that the types are only coupled to the names of the relationships (rels) and their optionality. The server still controls the URLs and the presence of optional relationships.</p> <p>Be cautious of making the types for the Hypermedia Controls too dynamic. On my first attempt at adding types for hypermedia, I used a more general dictionary type for links and actions. My thinking was that this would more accurately model the changing and dynamic hypermedia relationships a resource would have.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">type</span> Relationships <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span>rel<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">]</span><span class="token punctuation">:</span> Relationship <span class="token operator">|</span> <span class="token builtin">unknown</span> <span class="token punctuation">}</span></code></pre></div> <p>This assumption quickly turned out to be false and worked against the goal and benefits of strong typing. The relationships were not as dynamic as I had originally assumed. Links and actions don't change frequently, so you can safely define them as part of the type. Another downside was that you can't easily see what relationships are contextual and which ones are always present.</p> <p>Hypermedia is often taken a bit too far and is often associated with machine-readable metadata or form builders. My advice here is to avoid designing your types for general hypermedia clients. Instead, think of these types as representing a well defined and static contract between the client and the server.</p> <p>All links and actions use the <code class="language-text">Relationship</code> type which represents the relationship and its location. A relationship can be either a simple URL or a contain extra info such as the <code class="language-text">Method</code> or <code class="language-text">Title</code>.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">export</span> <span class="token keyword">type</span> Href <span class="token operator">=</span> <span class="token builtin">string</span> <span class="token keyword">export</span> <span class="token keyword">type</span> DetailedRelationship <span class="token operator">=</span> <span class="token punctuation">{</span> href<span class="token punctuation">:</span> Href method<span class="token operator">?</span><span class="token punctuation">:</span> Method title<span class="token operator">?</span><span class="token punctuation">:</span> <span class="token builtin">string</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">type</span> Relationship <span class="token operator">=</span> <span class="token operator">|</span> Href <span class="token operator">|</span> DetailedRelationship</code></pre></div> <p>I usually use the <code class="language-text">DetailedRelationship</code> type but sometimes it's conventient to only provide the URL for links, which typically use the <code class="language-text">GET</code> verb.</p> <h2>Contextual Relationships</h2> <p>In the <code class="language-text">AccountResource</code> above you can see there are three potential actions. The <code class="language-text">update</code> action is always available but <code class="language-text">activate</code> and <code class="language-text">deactivate</code> are optional so the client only has to check for the presence of the optional relationships. The server can then decide when these optional actions are available, enabling the actions for the client based on the state of the resource.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">const</span> account <span class="token operator">=</span> <span class="token function">fetchAccount</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span> <span class="token keyword">const</span> accountHypermedia <span class="token operator">=</span> <span class="token function">accountHypermedia</span><span class="token punctuation">(</span>account<span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>accountHypermedia<span class="token punctuation">.</span>deactivate<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// The account can be deactivated!</span> <span class="token keyword">await</span> accountHypermedia<span class="token punctuation">.</span><span class="token function">deactivate</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// &lt;- Also Typechecked, no request payload is needed!</span> <span class="token punctuation">}</span></code></pre></div> <p>In this sample, <code class="language-text">deactivate</code> has to be null checked before it can be used. The <code class="language-text">call</code> function also knows that <code class="language-text">deactivate</code> takes no payload and what the return type is.</p> <h2>Creating a Hypermedia Model</h2> <p>Next, let's look into the <code class="language-text">accountHypermedia</code> function, which does the heavy lifting of transforming the resource with hypermedia into a typed hypermedia model containing all the links and actions. To make the conversion easier I've also written a function <code class="language-text">createHypermediaModel</code> which helps to create the API for a resource.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">type</span> none <span class="token operator">=</span> <span class="token keyword">void</span> <span class="token comment">// Used when a Request requires no payload (function &lt;T>(arg: T) would need no arguments)</span> <span class="token keyword">const</span> accountHypermedia <span class="token operator">=</span> <span class="token function">createHypermediaModel</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resource<span class="token punctuation">:</span> AccountResource<span class="token punctuation">,</span> resolve</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> links<span class="token punctuation">:</span> <span class="token punctuation">{</span> self<span class="token punctuation">:</span> resolve<span class="token operator">&lt;</span>none<span class="token punctuation">,</span> AccountResource<span class="token operator">></span><span class="token punctuation">(</span>resource<span class="token punctuation">.</span>_links<span class="token punctuation">.</span>self<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> actions<span class="token punctuation">:</span> <span class="token punctuation">{</span> deactivate<span class="token punctuation">:</span> resolve<span class="token operator">&lt;</span>none<span class="token punctuation">,</span> AccountResource<span class="token operator">></span><span class="token punctuation">(</span>resource<span class="token punctuation">.</span>_actions<span class="token punctuation">.</span>deactivate<span class="token punctuation">)</span><span class="token punctuation">,</span> update<span class="token punctuation">:</span> resolve<span class="token operator">&lt;</span>none<span class="token punctuation">,</span> AccountResource<span class="token operator">></span><span class="token punctuation">(</span>resource<span class="token punctuation">.</span>_actions<span class="token punctuation">.</span>update<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span></code></pre></div> <p>You can view this code as a mapping from the resource to a set of, ready to use, functions. The resolve function takes the relationship and returns an object containing a strongly typed <code class="language-text">call</code> function as well as the <code class="language-text">href</code> and <code class="language-text">title</code> if one was provided.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">resolve&lt;none, AccountResource&gt;(resource._links.self)</code></pre></div> <p><em>Note: In Typescript, you are able to pass through a generic function as a parameter. The <code class="language-text">resolve</code> parameter makes use of this to compose (an instance of) fetch and the request/response types.</em></p> <p>The <code class="language-text">ResolvedRelationship</code> makes it convenient to access the <code class="language-text">href</code> and other metadata if you only have access to the hypermedia model.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">export</span> <span class="token keyword">type</span> ResolvedRelationship<span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function-variable function">call</span><span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token parameter">request<span class="token punctuation">:</span> Request</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token builtin">Promise</span><span class="token operator">&lt;</span>Response<span class="token operator">></span> href<span class="token punctuation">:</span> <span class="token builtin">string</span> title<span class="token punctuation">:</span> <span class="token builtin">string</span> <span class="token operator">|</span> undefined <span class="token punctuation">}</span></code></pre></div> <p>I use <code class="language-text">href</code> from the <code class="language-text">ResolvedRelationship</code> to follow links to different pages by changing the URL. This means exposing the <code class="language-text">Method</code> isn't nessesary as they are always <code class="language-text">GET</code> requests.</p> <h2>Multiple Resources</h2> <p>The <code class="language-text">createHypermediaModel</code> function focuses on creating a hypermedia model for a single resource. In order to create a model for an entire API you can use a <code class="language-text">createApi</code> function to create a single object composing the sub-APIs for each individual resource.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">createApi</span><span class="token punctuation">(</span><span class="token parameter">fetch<span class="token punctuation">:</span> Fetch</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> resolve <span class="token operator">=</span> <span class="token function">createResolver</span><span class="token punctuation">(</span>fetch<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token function-variable function">getAccount</span><span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token parameter">url<span class="token punctuation">:</span> <span class="token builtin">string</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> resolve<span class="token operator">&lt;</span>none<span class="token punctuation">,</span> AccountResource<span class="token operator">></span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> accounts<span class="token punctuation">:</span> <span class="token function">accountHypermedia</span><span class="token punctuation">(</span>resolve<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// More models go here!</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>That covers all the main pieces of using <code class="language-text">createHypermediaModel</code> to build a type-safe hypermedia API. Please let me know if you liked this approach as I'm considering wrapping this up into an npm package. However, I've glossed over the detail of how <code class="language-text">createHypermediaModel</code> works. It's mostly the glue and pluming but there are a few interesting parts. Feel free to read the apendix below if you'd like to dig deeper under the covers.</p> <p>That's all I have for now and as always thanks for reading!</p> <h2>Apendix: Deeper into the Code</h2> <p> Here is the bulk of the code, feel free to skim over it and jump to the alaysis at the bottom.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">export</span> <span class="token keyword">type</span> JsonFetch <span class="token operator">=</span> <span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span><span class="token punctuation">(</span><span class="token parameter">method<span class="token punctuation">:</span> Method<span class="token punctuation">,</span> url<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">,</span> data<span class="token operator">?</span><span class="token punctuation">:</span> Request</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token builtin">Promise</span><span class="token operator">&lt;</span>Response<span class="token operator">></span> <span class="token keyword">export</span> <span class="token keyword">type</span> Resolver <span class="token operator">=</span> <span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span><span class="token punctuation">(</span><span class="token parameter">relationship<span class="token punctuation">:</span> Relationship</span><span class="token punctuation">)</span> <span class="token operator">=></span> ResolvedRelationship<span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span> <span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getHref</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">rel<span class="token punctuation">:</span> Relationship</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> rel <span class="token operator">===</span> <span class="token string">"string"</span> <span class="token operator">?</span> rel <span class="token punctuation">:</span> rel<span class="token punctuation">.</span>href<span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getTitle</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">rel<span class="token punctuation">:</span> Relationship</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> rel <span class="token operator">===</span> <span class="token string">"string"</span> <span class="token operator">?</span> undefined <span class="token punctuation">:</span> rel<span class="token punctuation">.</span>title<span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">createResolver</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">fetch<span class="token punctuation">:</span> JsonFetch</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span><span class="token punctuation">(</span> relationship<span class="token punctuation">:</span> Relationship <span class="token punctuation">)</span><span class="token punctuation">:</span> ResolvedRelationship<span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token function-variable function">apiCall</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter">request<span class="token punctuation">:</span> Request</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> rel<span class="token punctuation">:</span> <span class="token punctuation">{</span> href<span class="token punctuation">:</span> Href<span class="token punctuation">;</span> method<span class="token punctuation">:</span> Method<span class="token punctuation">;</span> name<span class="token operator">?</span><span class="token punctuation">:</span> <span class="token builtin">string</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">typeof</span> relationship <span class="token operator">===</span> <span class="token string">"string"</span> <span class="token operator">?</span> <span class="token punctuation">{</span> href<span class="token punctuation">:</span> relationship<span class="token punctuation">,</span> method<span class="token punctuation">:</span> <span class="token string">"get"</span> <span class="token punctuation">}</span> <span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token operator">...</span>relationship<span class="token punctuation">,</span> method<span class="token punctuation">:</span> relationship<span class="token punctuation">.</span>method <span class="token operator">||</span> <span class="token string">"get"</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> response <span class="token operator">=</span> <span class="token keyword">await</span> fetch<span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span><span class="token punctuation">(</span>rel<span class="token punctuation">.</span>method<span class="token punctuation">,</span> rel<span class="token punctuation">.</span>href<span class="token punctuation">,</span> request<span class="token punctuation">)</span> <span class="token keyword">return</span> response <span class="token keyword">as</span> Response <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> call<span class="token punctuation">:</span> apiCall<span class="token punctuation">,</span> href<span class="token punctuation">:</span> <span class="token function">getHref</span><span class="token punctuation">(</span>relationship<span class="token punctuation">)</span><span class="token punctuation">,</span> title<span class="token punctuation">:</span> <span class="token function">getTitle</span><span class="token punctuation">(</span>relationship<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">const</span> createHypermediaModel <span class="token operator">=</span> <span class="token operator">&lt;</span>Resource<span class="token punctuation">,</span> <span class="token constant">T</span><span class="token operator">></span><span class="token punctuation">(</span> <span class="token function-variable function">builder</span><span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token parameter">resource<span class="token punctuation">:</span> Resource<span class="token punctuation">,</span> resolver<span class="token punctuation">:</span> Resolver</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token constant">T</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token parameter">resolver<span class="token punctuation">:</span> Resolver</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token parameter">resource<span class="token punctuation">:</span> Resource</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">builder</span><span class="token punctuation">(</span>resource<span class="token punctuation">,</span> resolver<span class="token punctuation">)</span></code></pre></div> <p>The code is written in a functional programming style and functions declared before they are used. Therefore it is usually easier to look at functions starting from the bottom and going up.</p> <p>The first function is, therefore, <code class="language-text">ceateHypermediaModel</code>, which uses a bit of currying so the resolver and resource can be provided at different times. Dependencies such as Fetch and the Resolver are threaded through the call stack so no global references are needed.</p> <p>The other main function is <code class="language-text">createResolver</code> which constructs the <code class="language-text">ResolvedRelationship</code>. Its main job is to wrap up the call to fetch using the given relationship and the request/response types.</p><![CDATA[Practical Hypermedia Controls]]>https://daniellittle.dev/practical-hypermedia-controlshttps://daniellittle.dev/practical-hypermedia-controlsTue, 07 Jul 2020 08:00:00 GMT<p>A lot has been written about REST but less so when it comes to Hypermedia Controls. I haven't seen too many Hypermedia based APIs out in the wild. I theorize that there are two main reasons for this. First, it is something many people haven't been exposed to, and second, it requires a little more up-front effort in order to get the ball rolling. However, I believe it's an incredibly useful pattern and it's easier to get started than you might think. This post aims to help out with that first problem, exposure. We'll take a look at what Hypermedia Controls are and why they're useful.</p> <p>Whatever the reason for the rarity of Hypermedia Controls, what you might commonly see in a REST API instead, is something like this.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token punctuation">{</span> <span class="token property">"id"</span><span class="token operator">:</span> <span class="token string">"0001"</span> <span class="token property">"username"</span><span class="token operator">:</span> <span class="token string">"daniellittledev"</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Daniel Little"</span> <span class="token property">"email"</span><span class="token operator">:</span> <span class="token string">"daniellittle@somewhere"</span> <span class="token property">"canUpdate"</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token property">"canDeactivate"</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span></code></pre></div> <p>This JSON object represents a user account. In this system, there are a few simple rules. Only the owner of the resource can update it and only admins can deactivate or activate accounts. This resource uses boolean flags to inform the client what state the object is in and what actions it can perform.</p> <p>However, there are some problems with this model.</p> <ul> <li>We can't tell if the current user should be able to activate or deactivate the account.</li> <li>We can't tell if the account can be activated, we have to assume it can be because we can't deactivate it.</li> <li>We don't know how to update or deactivate an account, we'd need more external information like the URL.</li> </ul> <p>Wouldn't it be nice if all these things were a bit easier to figure out? I think so too!</p> <h2>Enter Hypermedia Controls</h2> <p>Hypermedia Controls in REST APIs are all about adding links and actions to a resource instead of needing to interoperate what links and actions are available based on state. Examples of state are boolean flags like above or a status value like <code class="language-text">ready</code> or <code class="language-text">pending</code>. Here's what the same resource would look like if we added Hypermedia Controls instead.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token punctuation">{</span> <span class="token property">"id"</span><span class="token operator">:</span> <span class="token string">"0001"</span><span class="token punctuation">,</span> <span class="token property">"username"</span><span class="token operator">:</span> <span class="token string">"daniellittledev"</span><span class="token punctuation">,</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Daniel Little"</span><span class="token punctuation">,</span> <span class="token property">"email"</span><span class="token operator">:</span> <span class="token string">"daniellittle@somewhere"</span><span class="token punctuation">,</span> <span class="token property">"links"</span><span class="token operator">:</span> <span class="token punctuation">{</span> ... <span class="token punctuation">}</span> <span class="token property">"actions"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"update"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"href"</span><span class="token operator">:</span> <span class="token string">"/account/0001"</span><span class="token punctuation">,</span> <span class="token property">"method"</span><span class="token operator">:</span> <span class="token string">"put"</span><span class="token punctuation">}</span> <span class="token property">"activate"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"href"</span><span class="token operator">:</span> <span class="token string">"/account/0001/activate"</span><span class="token punctuation">,</span> <span class="token property">"method"</span><span class="token operator">:</span> <span class="token string">"post"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Now we can clearly see which actions are available. There are two available actions, update and activate, along with the URL and verb needed to make the calls. Instead of the client needing to infer this from the data, the server directly dictates what actions are available. We don't need to assume the client can activate the account if <code class="language-text">canDeactivate</code> is <code class="language-text">false</code>. There's also no danger of adding conflicting flags. The client can directly show or enable buttons or links directly based on what Hypermedia Controls are present.</p> <p>Let's look at our previous problems again, now that we're using Hypermedia.</p> <ul> <li>There is no action for deactivating the account; so the user can't see or perform that action.</li> <li>There is an action to activate the account; so the user should see and perform that action.</li> <li>We know the URL and method, so the client doesn't need hardcode or build-up any URLs.</li> </ul> <p>Much better! This also helps out immensely when debugging or looking at the REST API directly. There's no need for all that extra context to be extracted from the client because it's all there in the resource.</p> <p>Also, note that to perform an update you would simply modify the resource as desired and send it right back. You can optionally remove the links and actions, but otherwise, they're typically ignored.</p> <p>All this makes the API much easier to reason about and use. But the key benefit is the client no longer needs to interpret any state to figure out what is going on. We're able to keep the knowledge, of who can do what and when, on the server without having to duplicate any logic into the client. And while this example is a fairly trivial one, a few more flags like the ones above or worse, enum states where the client has to decide what buttons are available based on states like <code class="language-text">Pending</code>, <code class="language-text">InProgress</code> or <code class="language-text">Completed</code>, can easily increase complexity and the burden of keeping everything in sync.</p> <h2>More Control</h2> <p>We can also do more than just make links and actions available or unavailable. We could also show that an action exists but isn't available. On the UI this could manifest as a visible but disabled button.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token property">"actions"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"update"</span><span class="token operator">:</span> <span class="token null keyword">null</span> <span class="token comment">// or { disabled: true }</span> <span class="token punctuation">}</span></code></pre></div> <p>If you'd like things to be a bit more dynamic or server controlled you can also include a title for an action which could be used as the label for a link or button.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token property">"actions"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"update"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"href"</span><span class="token operator">:</span> <span class="token string">"/account/0001"</span><span class="token punctuation">,</span> <span class="token property">"method"</span><span class="token operator">:</span> <span class="token string">"put"</span><span class="token punctuation">,</span> <span class="token property">"title"</span><span class="token operator">:</span> <span class="token string">"Update Account"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>It's really up to you to choose how much information is provided to the client. However, I'd be cautious of adding too much. You might be tempted to include other metadata like field types or validation rules. But the main goal here is to keep duplicate logic out of the client and keep the server in control of application state. Decoupling too much tends to lead to the <a href="https://en.wikipedia.org/wiki/Inner-platform_effect">Inner Platform Effect</a>.</p> <h2>Client-Side Routing</h2> <p>There's one unexpected question I came across while implementing a Hypermedia based API. Which is how they affect client-side routing. I've found keeping API URLs in sync with the browser URLs to be a good approach. Or to be more accurate, I believe they should be the same URL. If you're coming from a non-hypermedia based API your URLs will most likely have diverged so I'll demonstrate what this looks like in practice.</p> <p>The root hypermedia resource is the starting point for the API, it provides all the top level links you'd need to get started.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token comment">// Request:</span> GET <span class="token string">"/"</span> <span class="token comment">// Response:</span> <span class="token punctuation">{</span> <span class="token property">"links"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"my-account"</span><span class="token operator">:</span> <span class="token string">"/account/0001"</span><span class="token punctuation">,</span> <span class="token property">"accounts"</span><span class="token operator">:</span> <span class="token string">"/account"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Following a link such as <code class="language-text">my-account</code> (which the client knows by name) would update the browsers route to match, eg. <code class="language-text">/account/0001</code>. The client-side routing rules mirror the server-side rules to render the relevant components but simply forward the URL directly to the API to fetch a resource. Note that the value here is that the client doesn't have to hardcode, reconstruct or build any URLs.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token comment">// Request:</span> GET <span class="token string">"/account/0001"</span> <span class="token comment">// Response:</span> <span class="token punctuation">{</span> <span class="token property">"links"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"self"</span><span class="token operator">:</span> <span class="token string">"/account/0001"</span><span class="token punctuation">,</span> <span class="token property">"home"</span><span class="token operator">:</span> <span class="token string">"/"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Actions are a little different and don't usually represent a route change. I recommend using a get-post-redirect style pattern so that a link (self) or a redirect is used to determine the next URL for the client.</p> <h2>Try it out</h2> <p>Next time you're building a form with a few actions especially if those actions change under different conditions or states consider using Hypermedia Controls. I hope you enjoyed this article, and if so make sure to keep an eye out for my next post on <a href="/type-safe-hypermedia-controls">Type Safe Hypermedia with Typescript</a>.</p><![CDATA[Power Query - The M Language]]>https://daniellittle.dev/power-query-the-m-languagehttps://daniellittle.dev/power-query-the-m-languageMon, 22 Jun 2020 10:40:00 GMT<p>Recently I had the opportunity to write a Custom Connector for Power BI and come across something I didn't expect. To build a Connector you use Power Query also known as the M formula language. Power Query was designed to build data transformation pipelines, focusing on repeatable importing and manipulations of tables.</p> <blockquote> <p>A core capability of Power Query is to filter and combine, that is, to mash-up data from one or more of a rich collection of supported data sources.</p> </blockquote> <p>But what I didn't expect is that Power Query is a lazy functional programming language. The documentation describes it as "a functional, case sensitive language similar to F#". So not only does Power BI include a programming language it's also a functional programming language! Although if I had to describe it, I'd say it's more of a simplified cross between JavaScript and Haskell. Curious? Well then, let's take a quick look at what Power Query looks like, and some of its features.</p> <p>The first thing you might notice about Power Query is that it's almost entirely expression-based. Every function is comprised of a single expression. </p> <div class="gatsby-highlight" data-language="fsharp"><pre class="language-fsharp"><code class="language-fsharp">Function <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"Hello"</span> <span class="token function">Function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// returns "Hello"</span></code></pre></div> <p>Here we have a global variable called <code class="language-text">Function</code> which contains a function which returns "hello". All functions are lambdas.</p> <p>One of the most common building blocks is the <code class="language-text">let</code> expression, which lets you build up more complex functions using variables.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token keyword">let</span> <span class="token hvariable">hello</span> <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token hvariable">world</span> <span class="token operator">=</span> <span class="token string">"World"</span> <span class="token keyword">in</span> <span class="token hvariable">hello</span> <span class="token operator">&amp;</span> <span class="token string">" "</span> <span class="token operator">&amp;</span> <span class="token hvariable">world</span> <span class="token operator">&amp;</span> <span class="token string">"!"</span></code></pre></div> <p>If you're not familiar with the <code class="language-text">let</code> syntax it's quite common in expression-based functional languages. A <code class="language-text">let</code> expression allows you to define and bind other expressions for use in the <code class="language-text">in</code> clause. You can read it like, let these "names" be bound to these "values" in this "expression".</p> <p>Let's look at a more complex function. The function below makes a web request to a given URL and returns the result as JSON.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token constant">Fetch</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token hvariable">url</span> <span class="token hvariable">as</span> <span class="token hvariable">text</span><span class="token punctuation">)</span> <span class="token hvariable">as</span> <span class="token hvariable">record</span> <span class="token operator">=></span> <span class="token keyword">let</span> <span class="token hvariable">accessToken</span> <span class="token operator">=</span> <span class="token constant">Extension.CurrentCredential</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token hvariable">access_token</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token hvariable">authHeader</span> <span class="token operator">=</span> <span class="token string">"Bearer "</span> <span class="token operator">&amp;</span> <span class="token hvariable">accessToken</span><span class="token punctuation">,</span> <span class="token hvariable">response</span> <span class="token operator">=</span> <span class="token constant">Web.Contents</span><span class="token punctuation">(</span><span class="token hvariable">url</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token constant">ManualCredentials</span> <span class="token operator">=</span> <span class="token hvariable">true</span><span class="token punctuation">,</span> <span class="token constant">Headers</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token constant">Authorization</span> <span class="token operator">=</span> <span class="token hvariable">authHeader</span><span class="token punctuation">]</span> <span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">in</span> <span class="token constant">Json.Document</span><span class="token punctuation">(</span><span class="token hvariable">response</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>There are a few things going on in this function but one of the interesting things to point out are the two main types you see in Power Query, apart from tables of course. These are lists and records, and the interesting bit is that the symbols are opposite to what you might expect if coming from most other languages. </p> <p>Lists are defined using braces <code class="language-text">{}</code> and records are defined using square brackets <code class="language-text">[]</code>, the exact opposite of JavaScript or FSharp.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token hvariable">list</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span> <span class="token hvariable">record</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token constant">Property</span> <span class="token operator">=</span> <span class="token hvariable">true</span><span class="token punctuation">,</span> <span class="token constant">AnotherProperty</span> <span class="token operator">=</span> <span class="token string">"Hello"</span> <span class="token punctuation">]</span></code></pre></div> <p>Accessing a property is also a little different and also uses <code class="language-text">[]</code>.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token hvariable">value</span> <span class="token operator">=</span> <span class="token hvariable">record</span><span class="token punctuation">[</span><span class="token constant">Property</span><span class="token punctuation">]</span></code></pre></div> <p>In the Fetch function above you can see the <code class="language-text">access_token</code> property being used via the credentials record.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token constant">Extension.CurrentCredential</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token hvariable">access_token</span><span class="token punctuation">]</span></code></pre></div> <p>Briefly, on types, the language is dynamic with optional types and can also be extended with custom metadata. Below the function starts without any types and you can see how the code changes as I add more type information.</p> <div class="gatsby-highlight" data-language="fsharp"><pre class="language-fsharp"><code class="language-fsharp"><span class="token punctuation">(</span>url<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token operator">..</span><span class="token punctuation">.</span>expression <span class="token punctuation">(</span>url <span class="token keyword">as</span> text<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token operator">..</span><span class="token punctuation">.</span>expression <span class="token punctuation">(</span>url <span class="token keyword">as</span> text<span class="token punctuation">)</span> <span class="token keyword">as</span> record <span class="token operator">=</span><span class="token operator">></span> <span class="token operator">..</span><span class="token punctuation">.</span>expression <span class="token punctuation">(</span>url <span class="token keyword">as</span> text<span class="token punctuation">)</span> <span class="token keyword">as</span> record meta <span class="token punctuation">[</span> Documentation<span class="token punctuation">.</span>Name <span class="token operator">=</span> <span class="token string">"My Record Type"</span> <span class="token punctuation">]</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token operator">..</span><span class="token punctuation">.</span>expression</code></pre></div> <p>Now, I've saved the best until last. One of the most powerful features of Power Query is that it's lazy. Take for example the following code.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token keyword">let</span> <span class="token hvariable">pets</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token constant">Fetch</span><span class="token punctuation">(</span><span class="token string">"https://api.service.com/dogs"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token constant">Fetch</span><span class="token punctuation">(</span><span class="token string">"https://api.service.com/cats"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">in</span> <span class="token hvariable">pets</span><span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">}</span></code></pre></div> <p>In this expression, we have a list of pets which contains the result of some API calls to a web service. However, only the first element of the array is ever accessed and because Power Query is lazy the second fetch will never actually be evaluated. In a custom connector, this could be used to access a paged rest API in order to import a table. And because evaluation is lazy using the standard <code class="language-text">take</code> function will only fetch the pages that are needed are fetched.</p> <p>It's exciting to see functional programming, especially a language as interesting as Power Query, popping up in the mainstream. I had a blast learning about Power Query and I learnt so much along the way. If you're interested in trying out a functional first language, whatever it may be, I encourage you, now is the time to check one out!</p><![CDATA[Environment Settings for Build Once Packages in React]]>https://daniellittle.dev/environment-settings-for-build-once-packages-in-reacthttps://daniellittle.dev/environment-settings-for-build-once-packages-in-reactTue, 14 Jan 2020 17:00:00 GMT<p>Let's look at some questions:</p> <ol> <li>How do you specify which API to use for an environment?</li> <li>How do you configure the environment settings of frontend apps for each environment?</li> <li>How to you achieve: build once, deploy everywhere packages for a frontend app?</li> </ol> <p>Most frontend applications currently take the approach of <a href="https://twitter.com/housecor/status/973881714710908928">building a package for each environment</a>. This approach is reasonably well supported by Webpack and it is a common approach. There's also a lot of workarounds such as sniffing the URL, injecting extra scripts or using a find and replace script on the bundle. These approaches can provide a single package but are often custom solutions for individual applications.</p> <p>I think there are two main reasons for this, the first, is that when you <code class="language-text">create-react-app</code> out of the box there is no built-in support for build once, deploy everywhere. You have to fend for yourself. But second, and possibly, more importantly, it is more difficult to set up runtime style environment settings needed for build once, deploy everywhere packages.</p> <h2>Build Once, Deploy Everywhere</h2> <p>As this approach is less common, let's look at what exactly this is, why it's important and some of the benefits of this approach. The build once, deploy everywhere pattern refers to the building a single deployment artefact which can be deployed to one or many different environments.</p> <h3>Shorter build times</h3> <p>Building packages is expensive, building a package once saves quite a bit of time and compute. If your build takes 40 seconds, and you have two environments, the total build time is effectively doubled to over a minute. Fast builds and deployment times are also important for low deployment lead times and short development cycles. Today it's also common to have you build/ci agent in the cloud where we'll typically pay per minute or per agent for parallel builds. Here short build times have an even greater impact on development and costs.</p> <h3>Exact same code</h3> <p>By building the package once and using that same package in every environment, you can guarantee they'll all be running the exact same code. There are multiple reasons why you might end up with slight unexpected variations such as non-deterministic compilers, resulting in different optimisations. Dependencies could change, for example, if the build step runs an auto package restore or the build script relies on an external service. There may also be bugs in the tooling which can be unforeseen. By building the package once, there are fewer opportunities for things to go wrong, which means less risk.</p> <h3>Simplified deployment pipeline</h3> <p>Modern deployment pipelines such as those in products such as Octopus Deploy or Azure DevOps support environment based deployments, deployment promotion and variable substitution. These tools assume a single artifact or package which can then be deployed to an environment. Variable substitution is applied at deployment time after the package has been created, typically as a final configuration step during deployment. Taking advantage of these features results in a simplified deployment pipeline. The tooling can often assist with promoting to the next environment or marking the package as containing defects, managing the lifecycle of the package for us.</p> <h2>Loading Environment Settings in React</h2> <p>In order to load the settings, I've gone with the approach of using a single file to keep loading times as low as possible.</p> <p>There is a single <code class="language-text">settings.json</code> file which contains the environment you want to load settings for, as well as blocks containing the default and environment settings. In the example below the environment is <code class="language-text">development</code> which is what I'd also check into version control.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token comment">// settings.json</span> <span class="token punctuation">{</span> <span class="token property">"environment"</span><span class="token operator">:</span> <span class="token string">"development"</span><span class="token punctuation">,</span> <span class="token property">"default"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"api"</span><span class="token operator">:</span> <span class="token string">"defaultapi.com"</span><span class="token punctuation">,</span> <span class="token property">"siteName"</span><span class="token operator">:</span> <span class="token string">"Example Site"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token property">"development"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"api"</span><span class="token operator">:</span> <span class="token string">"developmentapi.com"</span><span class="token punctuation">,</span> <span class="token property">"banner"</span><span class="token operator">:</span> <span class="token string">"You are in the Development Environment"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>On deployment, environment property is replaced with the appropriate environment name. Settings can also be added or modified. Then, when the application is run the application, I'll get the combination of (using spread internally) the default and matching environment blocks.</p> <p>To tie it all together, I'm using a component called <code class="language-text">AppSettingsLoader</code> which loads the settings given the URL of a settings file. It also takes three other props to determine what to show while the settings are being loaded or unavailable, what to render once the settings are available, and optionally an error prop.</p> <div class="gatsby-highlight" data-language="tsx"><pre class="language-tsx"><code class="language-tsx"><span class="token keyword">import</span> AppSettingsLoader <span class="token keyword">from</span> <span class="token string">"react-environment-settings"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> settingsAssetUrl <span class="token keyword">from</span> <span class="token string">"./settings.json.txt"</span><span class="token punctuation">;</span> <span class="token keyword">interface</span> <span class="token class-name">Settings</span> <span class="token punctuation">{</span> api<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> banner<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">&lt;</span>AppSettingsLoader<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Settings</span></span><span class="token punctuation">></span></span><span class="token plain-text"> settingsUrl=</span><span class="token punctuation">{</span>settingsAssetUrl<span class="token punctuation">}</span><span class="token plain-text"> loading=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Loading settings...</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">}</span><span class="token plain-text"> ready=</span><span class="token punctuation">{</span><span class="token parameter">s</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>pre</span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>s<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>pre</span><span class="token punctuation">></span></span><span class="token punctuation">}</span><span class="token plain-text"> /></span></code></pre></div> <p>The AppSettingsLoader is also a generic component; in this example, you can also see the <code class="language-text">Settings</code> interface used to specify the type of the combined settings. Therefore, the final product of the Settings for all environments need to match a common interface.</p> <div class="gatsby-highlight" data-language="tsx"><pre class="language-tsx"><code class="language-tsx"><span class="token operator">&lt;</span>AppSettingsLoader<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Settings</span></span><span class="token punctuation">></span></span><span class="token plain-text"> ... /></span></code></pre></div> <p>In order to load the settings themselves, there were a number of issues I had to work through. I wanted to keep the settings file separate to the application bundle, but <code class="language-text">json</code> files are bundled if you import them. I also wanted to avoid caching issues so I couldn't just move the file into the public folder and fetch it from there.</p> <p>In order to load the settings file with Typescript and Webpack I was able to use the <a href="https://webpack.js.org/guides/typescript/#importing-other-assets">Importing Other Assets</a> functionality which lets you import a file, in this case, a <code class="language-text">txt</code> file. Importing the file will cause it to be processed giving it a unique filename, but unlike a <code class="language-text">json</code> import the file contents are unmodified and the file is stored in the <code class="language-text">media</code> folder.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&gt; build &gt; static &gt; css &gt; js &gt; media &gt; settings.json.4355cbd.txt</code></pre></div> <p>Above is an example of where you can locate the file after a build. As you can see the settings file is easy to locate, having a similar but also cache busting filename. This means it's easy to locate the settings file and perform environment name and variable substitution.</p> <p>Importing the file in Typescript also requires a module declaration.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token comment">// global.d.ts</span> <span class="token keyword">declare</span> <span class="token keyword">module</span> <span class="token string">'*.txt'</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> content<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> content<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>And when the file is imported, you'd receive the path to the file which can be passed to the <code class="language-text">AppSettingsLoader</code> and loaded via a fetch.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">import</span> settingsAssetUrl <span class="token keyword">from</span> <span class="token string">"./settings.json.txt"</span><span class="token punctuation">;</span></code></pre></div> <p>You could also provide a Url from another source if needed.</p> <p>Finally, by using <code class="language-text">AppSettingsLoader</code> at the root of an application, you're then able to breifly delay running the application until the settings have been loaded and are available.</p> <div class="gatsby-highlight" data-language="tsx"><pre class="language-tsx"><code class="language-tsx"><span class="token operator">&lt;</span>AppSettingsLoader<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Settings</span></span><span class="token punctuation">></span></span><span class="token plain-text"> settingsUrl=</span><span class="token punctuation">{</span>settingsAssetUrl<span class="token punctuation">}</span><span class="token plain-text"> loading=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Loading...</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">}</span><span class="token plain-text"> ready=</span><span class="token punctuation">{</span><span class="token parameter">s</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">App</span></span> <span class="token attr-name">appSettings</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>s<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">}</span><span class="token plain-text"> /></span></code></pre></div> <h2>Installation and Code</h2> <p>If you'd like to try it out, you can install this package.</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> i react-environment-settings</code></pre></div> <p>I won't go into all the code, but you can find the full project on GitHub <a href="https://github.com/daniellittledev/react-environment-settings">daniellittledev/react-environment-settings</a>. Originally I was only planning on sharing my approach with a blog post, but it just wouldn't be complete without a package on npm.</p> <p>I've tried to keep the code relatively simple, so I'll just share a few key parts.</p> <p>The bulk of the logic is inside two main files, <code class="language-text">loadSettings.ts</code> which loads the merges the settings, and <code class="language-text">index.ts</code> which contains the component itself.</p> <p>Below is the main load settings function. Here I'd like to highlight in terms of error handling, fetch and loading issues are both caught at the top level of this function.</p> <div class="gatsby-highlight" data-language="tsx"><pre class="language-tsx"><code class="language-tsx"><span class="token keyword">export</span> <span class="token keyword">async</span> <span class="token keyword">function</span> loadSettings<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">T</span></span><span class="token punctuation">></span></span><span class="token plain-text">( settingsUrl: string ) </span><span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> settings <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getSettings</span><span class="token punctuation">(</span>settingsUrl<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> allSettings <span class="token operator">=</span> <span class="token function">getSelectedSettings</span><span class="token punctuation">(</span>settings<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> mergedSettings <span class="token operator">=</span> <span class="token function">mergeSettings</span><span class="token punctuation">(</span>allSettings<span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token builtin">unknown</span><span class="token punctuation">;</span> <span class="token keyword">return</span> success<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">T</span></span><span class="token punctuation">></span></span><span class="token plain-text">(mergedSettings as T); } catch (ex) </span><span class="token punctuation">{</span> <span class="token keyword">return</span> error<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">T</span></span><span class="token punctuation">></span></span><span class="token plain-text">(ex); } };</span></code></pre></div> <p>This error is then directly accessible using the <code class="language-text">error</code> prop on the <code class="language-text">AppSettingsLoader</code> component.</p> <div class="gatsby-highlight" data-language="tsx"><pre class="language-tsx"><code class="language-tsx"><span class="token keyword">switch</span> <span class="token punctuation">(</span>settings<span class="token punctuation">.</span><span class="token keyword">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token keyword">case</span> <span class="token string">"Error"</span><span class="token punctuation">:</span> <span class="token keyword">return</span> props<span class="token punctuation">.</span>error <span class="token operator">?</span> <span class="token punctuation">(</span> props<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span>settings<span class="token punctuation">.</span>error<span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Error loading settings</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>So you have full control if something goes wrong.</p> <h2>Wrapping up</h2> <p>Good luck out there with your settings loading journey. If you're trying to get a new project up and running or updating an existing project, I hope this post has helped you.</p><![CDATA[Practising Continuous Deployment]]>https://daniellittle.dev/practising-continuous-deploymenthttps://daniellittle.dev/practising-continuous-deploymentMon, 21 Oct 2019 17:00:00 GMT<p>I've long been an advocate of Continuous Deployment, but it's always felt somewhat out of reach. I've come close with projects that have had decent test coverage and automated deployments, but there was always something missing. There was always still a button you needed to click to promote from test into production. Often unreleased code could build-up, resulting in a bigger riskier release or more manual testing.</p> <p>Continuous Deployment can be difficult to adopt <em>because</em> you need to build reliability and confidence into your build and deployment pipelines. But more difficult is the culture shift, it's a different way of working and you can't just slap some tests on it and declare Continuous Deployment. Buy-in is important and so is process, because while Continuous Deployment is positively self-reinforcing, not practising it is negatively reinforcing. You need critical mass, and you need to jump the gap quickly. So while I've come close, it remained difficult to bridge the gap into the magical world of Continuous Deployment.</p> <p>However, during my time with the wonderful folks at Stacktrace, we practised Continuous Delivery amongst a team of eight developers. To date, it's that only team I've joined that was already practising Continuous Delivery. It was everything I hoped it would be. And since then I've brought a lot of what I learnt with me, continuing to put Continuous Delivery into practice.</p> <p>So I'd like to tell you about the strategies we used.</p> <h3>Shared code ownership</h3> <p>Everyone was equally across most areas of the codebase, and everyone felt comfortable working on any feature or change. We all paid attention to quality and avoided cutting corners. This made everything easier; you can take for granted cohesion, consistency and tests to cover your back. We also made sure to keep it that way.</p> <h3>Always production-ready</h3> <p>All commits are production-ready, you know that each push could potentially make it to production. If code isn't ready to go live, then it's either not wired up to the UI, silently running beside an existing version or behind a feature toggle. This ensures each release is small and all code is continuously integrated, so everyone sees the latest code even if it's not finished.</p> <p>Features also need to be backwards compatibility typically through parallel implementations or on-the-fly database migrations.</p> <h3>Short-lived branches</h3> <p>Branches are kept small and short-lived typically only lasting for 1-2 days. They're also only used for Pull Requests and usually don't represent a full or complete feature. As long as they're production-ready they're good to go.</p> <h3>Rebasing onto master</h3> <p>Master is always moving forward and in order to get value out of continuous integration, you need the latest code on your machine. We frequently rebased development branches onto master. To make this even easier, I'll use a function like fmar, which stands for fetch master and rebase.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">function fmar { git fetch git rebase origin/master }</code></pre></div> <h3>Quick Code Reviews</h3> <p>All code is merged into master from a PR, and each PR must be reviewed by someone else. Sometimes we'd pick someone familiar with the change and sometimes we'd pick someone different to share things around.</p> <p>We also treated code reviews as a priority. Initially it's the responsibility of the author to find someone to review the PR. Once you agreed to review a PR, it was then up to you to review it promptly or hand the PR back if something unexpected came up.</p> <p>We also tried to as much as possible give feedback as advice. PRs were almost always approved, instead of blocked, but most feedback was actioned regardless. Sometimes in a follow-up PR instead of delaying an existing PR.</p> <h3>Clean history</h3> <p>The key to quick PRs is code and commits that are easy to read and easy to follow. We would regularly rebase the commits in a PR so commits would tell a story or make a change easier to follow. And because branches were short-lived force pushing isn't a problem. We'd also use git pushfl or git push --force-with-lease for added safety, which aborts if anyone else has pushed to that branch.</p> <h3>Automated Code Formatters</h3> <p>Another tool we used to keep PRs quick was automated code formatting. This ensures that all code is consistent and that no one needs to waste time on style discussions in a PR.</p> <h3>Robust Test Suite</h3> <p>A good test suite is invaluable for continuous integration and deployment. Many changes can be verified via the tests without needing to run the application and perform lots of slower manual testing. Every change is backed by tests, and the tests are first-class code which is also actively maintained and improved.</p> <h3>Fully Automated deployments</h3> <p>Setting up fully Automated deployments is a key aspect because it reinforces many of the concepts above. Completing a PR doesn't just sit in test until it's ready. Keeping commits production-ready is more than just an ideal. The PR will go all the way to production, and it needs to be production-ready.</p> <p>This is also where a robust test suite really becomes indispensable. Automated builds always run before PRs can be integrated, and deployments are exercised by deploying to a test environment before they're deployed to production.</p> <h3>Testing in Prod</h3> <p>The last point I want to mention is testing in production. Having a test tenancy in the production environment allows for the testing and review of new functionality and changes that have not yet been enabled for all users. This was invaluable to exercise the system from end to end with real data and with all the real dependencies.</p> <h2>A Reflection</h2> <p>I found it an incredibly valuable experience to practice continuous deployment, but even more importantly, the practises that support it, make it possible and sustain it. </p> <p>Joining a team and learning through immersing myself in a culture that was already practising helped to bring these strategies into focus for me. </p> <p>I find that sometimes, it is hard to do things one step at a time because they can all seem to depend on each other. In the case of Continuous Deployment I still think that's true to some extent. There is a gap you have to jump to truly adopt Continuous Deployment. But I feel I have a much better idea of what makes Continuous Deployment successful.</p> <p>I'd also love to hear about what makes Continuous Deployment work for you. If you think I've missed something or one thing really stands out for you tag me on twitter <a href="https://twitter.com/daniellittledev">@daniellittledev</a>.</p><![CDATA[How to run Expecto with dotnet test]]>https://daniellittle.dev/how-to-run-expecto-with-dotnet-testhttps://daniellittle.dev/how-to-run-expecto-with-dotnet-testMon, 07 Oct 2019 19:00:00 GMT<p>Expecto is a fantastic test framework and test runner for FSharp. But contrary to the name, the thing I like most about Expecto is that it contains so little magic. Your test project is a simple Console applications and to run you tests you just run the app. No Visual Studio plugins required.</p> <div class="gatsby-highlight" data-language="powershell"><pre class="language-powershell"><code class="language-powershell">dotnet run</code></pre></div> <p>However, recently I wanted to also run my tests using <code class="language-text">dotnet test</code> to fit into a existing test suit and build script. By default Expecto tests won't be discovered by <code class="language-text">dotnet test</code> but the good news is it's only two packages and an attribute away from working with both <code class="language-text">run</code> and <code class="language-text">test</code>.</p> <p>I started with an application that used no auto test discovery opting for explicit test registration like the following. </p> <div class="gatsby-highlight" data-language="f#"><pre class="language-f#"><code class="language-f#">let allTests = testList &quot;all-tests&quot; [ BuilderTests.tests Convention.test Domain.tests ] [&lt;EntryPoint&gt;] let main argv = printfn &quot;Running tests!&quot; runTestsWithArgs config argv allTests</code></pre></div> <p>We'll come back to this later, first we need to install some packages.</p> <p>In order to set up tests with dotnet core we need to add the <code class="language-text">Test SDK</code> to the project file.</p> <div class="gatsby-highlight" data-language="xml"><pre class="language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>PackageReference</span> <span class="token attr-name">Include</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Microsoft.NET.Test.Sdk<span class="token punctuation">"</span></span> <span class="token attr-name">Version</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>16.3.0<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <p>However this will generate an entry point for your application and because we already have one we'll need to disable that by setting <code class="language-text">GenerateProgramFile</code> to <code class="language-text">false</code> in the project file.</p> <div class="gatsby-highlight" data-language="xml"><pre class="language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>PropertyGroup</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>GenerateProgramFile</span><span class="token punctuation">></span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>GenerateProgramFile</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>PropertyGroup</span><span class="token punctuation">></span></span></code></pre></div> <p>After that we'll need to add the package <code class="language-text">YoloDev.Expecto.TestSdk</code> in order <code class="language-text">dotnet test</code> to discover Expecto tests.</p> <div class="gatsby-highlight" data-language="xml"><pre class="language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>PackageReference</span> <span class="token attr-name">Include</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>YoloDev.Expecto.TestSdk<span class="token punctuation">"</span></span> <span class="token attr-name">Version</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0.8.0<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <p>This package exposes Expecto Test Attributes for discovery via the Microsoft Test SDK.</p> <p>Finally, we need to make one change to the <code class="language-text">Program.fs</code> file, adding the <code class="language-text">Tests</code> attribute to the tests so they can be discovered.</p> <div class="gatsby-highlight" data-language="f#"><pre class="language-f#"><code class="language-f#">[&lt;Tests&gt;] let allTests = testList &quot;all-tests&quot; [ BuilderTests.tests Convention.test Domain.tests ] [&lt;EntryPoint&gt;] let main argv = printfn &quot;Running tests!&quot; runTestsWithArgs config argv allTests</code></pre></div> <p>Now when we run <code class="language-text">dotnet test</code> we see the following:</p> <div class="gatsby-highlight" data-language="powershell"><pre class="language-powershell"><code class="language-powershell">> dotnet test Test run <span class="token keyword">for</span> App<span class="token punctuation">.</span>Tests<span class="token punctuation">.</span>dll<span class="token punctuation">(</span><span class="token punctuation">.</span>NETCoreApp<span class="token punctuation">,</span>Version=v2<span class="token punctuation">.</span>2<span class="token punctuation">)</span> Microsoft <span class="token punctuation">(</span>R<span class="token punctuation">)</span> Test Execution Command Line Tool Version 16<span class="token punctuation">.</span>3<span class="token punctuation">.</span>0 Copyright <span class="token punctuation">(</span>c<span class="token punctuation">)</span> Microsoft Corporation<span class="token punctuation">.</span> All rights reserved<span class="token punctuation">.</span> Starting test execution<span class="token punctuation">,</span> please wait<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> A total of 1 test files matched the specified pattern<span class="token punctuation">.</span> Test Run Successful<span class="token punctuation">.</span> Total tests: 31 Passed: 31 Total time: 1<span class="token punctuation">.</span>3619 Seconds</code></pre></div> <p>Success!</p><![CDATA[Reliable Messaging over a Service Bus]]>https://daniellittle.dev/reliable-messaging-over-service-bushttps://daniellittle.dev/reliable-messaging-over-service-busThu, 16 May 2019 18:00:00 GMT<p>When working with a traditional database inside of a monolith application, we don't usually need to think too much about how transactions work. We can rely on a transaction to either roll back all the changes or commit them. Either way, our model is always consistent.</p> <p>More recently, many applications have become distributed in one way or another. Many use a Service Bus or a REST API to communicate with other external systems. Communication between these systems is not transactional, so they won't be able to share a transaction and rollback if there are failures. So we'll need a method of reliably sending messages from one system to another. In this post, we'll be looking at how to implement reliable messaging between two applications using a Service Bus.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/2e091859671a8874dbfdbf7eeb89f2b7/9435c/services-communicating-over-service-bus.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.61855670103093%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAo0lEQVQY012Q2QoCMQxF+/+/4pP/Ifqo+DQOiAvFKczSznS53pQWqoHThiS9Sar0suA8DFi9hycppR94wIWQQROPJfecJlyNQWBeUBeK7boO47ZBrCYyMSKyyVFrHIgI1LiXBuTE+L7vYVknpsQRMW0tPs5lAd+Iiv/gFrdxxMq6SLGai0TeT+Q1z/lWvihL4E1Q1mlXzhOR/++o4mJ3rm440BczOzhKFmMUIAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Services communicating over a Service Bus" title="Services communicating over a Service Bus" src="/static/2e091859671a8874dbfdbf7eeb89f2b7/fea0e/services-communicating-over-service-bus.png" srcset="/static/2e091859671a8874dbfdbf7eeb89f2b7/064a4/services-communicating-over-service-bus.png 225w, /static/2e091859671a8874dbfdbf7eeb89f2b7/44727/services-communicating-over-service-bus.png 450w, /static/2e091859671a8874dbfdbf7eeb89f2b7/fea0e/services-communicating-over-service-bus.png 900w, /static/2e091859671a8874dbfdbf7eeb89f2b7/9435c/services-communicating-over-service-bus.png 970w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <h2>What's the problem?</h2> <p>When sending messages over a Service Bus there are a number of failure points to consider. If there is a failure at any of these points then information could be lost, state could be corrupted or the process may stall.</p> <blockquote> <p>We need to do three things when processing a message</p> <ol> <li>Execute domain logic</li> <li>Send new messages</li> <li>Save updates to the database</li> </ol> </blockquote> <p>The core of the problem lies with the fact that there are two data-stores, the primary database and a (durable) queue or topic. However, it's only possible to write to one or the other first.</p> <h3>Send then Save</h3> <p>Let's look at what happens when we send messages first, then save to the database.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 478px;" > <a class="gatsby-resp-image-link" href="/static/19ea4df6bd8aa4109b9a107960494007/16786/send-first-with-failure-to-save.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 87.23849372384937%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB0klEQVQ4y6VU20oDMRDt/3+Fr76oT6IgguCLCiqoVWll7WVba+/tXpvdHc9JkxK3a0UcOCSZ2TlzyWRrYRSJZJmESSKr1UoKpSTFyj1X2jrzuVx/fEicppIZuwJ49mYzeZtOJYA/dTXJc/GCQA5bLTnudmVGEkgha5nCad/zZK/ZlMvBQOvyYm29GY3kvN/X+gsEpNRSOBy123I/Hsup78vVcKgNGQJRemEoj8hgEMdyCwJl9JRXZBejggwBXrCnrcbSzno9OUF2B8iSBk1osvBBSFJKHbaVQ/iMc2rOdQTVhDl6EgJ3yJDKwhDZNUDAh8lEnmBroJduyb7Jnn7ecmlKNj1zpUxKcTNzbSRXzve6ZO2ALBVgDRa6fPYJKEo2nvOSbUOoHMKyqF+CubYNoc0iwTwt0I8lEGCcNCH0uSm53A7q6bdFGGMsPtHkLm7Ow+gQ7xiTIQI00PQIaxWhTaSSMKm4IObFi4sdwqr+bhEu8ASHAOcqQk8sOLghhl+Vgtn7/5GQvYuwT9jHEkgYMkvsIwLfFtDtJIxQ8hgZTvDhBA4WfMvMfARMeYZzFy8r73R2E+o/jTFsNzJf4y8l2+uvGl5VMdhSMTb66VnCbyT/wBd2TDIPzoq5pQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="After sending message there is a failure to save" title="After sending message there is a failure to save" src="/static/19ea4df6bd8aa4109b9a107960494007/16786/send-first-with-failure-to-save.png" srcset="/static/19ea4df6bd8aa4109b9a107960494007/064a4/send-first-with-failure-to-save.png 225w, /static/19ea4df6bd8aa4109b9a107960494007/44727/send-first-with-failure-to-save.png 450w, /static/19ea4df6bd8aa4109b9a107960494007/16786/send-first-with-failure-to-save.png 478w" sizes="(max-width: 478px) 100vw, 478px" loading="lazy" /> </a> </span></p> <p>In this situation, we've sent out messages, but there was an error while writing the updated application state to the database. In this case, no updates are made to the database so as far as our application is concerned nothing happened, but we ended up leaking messages.</p> <p>Now downstream systems may be working with inconsistent messages. The Service Bus may also redeliver the message, so the application can retry, but if the message is retried a different result might be reached because state and time will continue to change between attempts.</p> <h3>Save then Send</h3> <p>So sending messages first isn't too good, what if we save first instead? Then we wouldn't process invalid messages, and we'll avoid putting bad state into the database. Let's see what that looks like.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 478px;" > <a class="gatsby-resp-image-link" href="/static/0fc82c63fe5c176d740233df6edd8d89/16786/save-first-with-failure-to-send.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 87.23849372384937%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB5ElEQVQ4y62USU/jQBCF8/9/BVcuM5wQSKORkLgAEiDNDIsIMknINlkhXmO3i6+attVyDOJASaVenuv1q+pqd6I4FikKidJUttutlHkuGaPOdVRs8PIi55OJJFkmhcNzXNfBei2Pq5WExOteR4yRIAzlZ68nh8/PslYSrJR3WxG0HwSy1+3K6XRq90z5jl7M5/J7PLb7Jxyo1skIOOj35XqxkOPhUM5mMwsUHKQ2iiL5i4JpksglBLnbV7tHXUIGBQfcMVeso6n9Go3kCHU/UKmAJXQqhhAqqdoN2NYjvGWdufUNh1pCQ00i/AqFulk6omoMOfDPcin/wB6opZ/y0KnXuGCzcSm7mvnWJFXzlfmYkufe9zZlG4DKHK+A2jV9rRNetmCmgdWEuUfYNIsR1KZeyXwhNaEFXJDuhdRnQzsZUq0UfqZ+hzChMf9DMmMcU+AnLimgTaY0/oT9icNmtE/trLtciDb4LiEfpMy1yMa7DFPVFxUVVjtYClnWRviKkjme6jOEQMeEMWbU1glde+k8rub4xj3ZHcIUIGauRJbMjSk1DDmoBG+z0tV4hzAm5QWBS+QvCa58wce9wUAM3mwb+exS7J/GAa0qXGN/mbBqj/KD1jCNl1JfmpeyfXp+Qb/D3wAOvjGhC8Bw2AAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="After saving state there is a failure to send" title="After saving state there is a failure to send" src="/static/0fc82c63fe5c176d740233df6edd8d89/16786/save-first-with-failure-to-send.png" srcset="/static/0fc82c63fe5c176d740233df6edd8d89/064a4/save-first-with-failure-to-send.png 225w, /static/0fc82c63fe5c176d740233df6edd8d89/44727/save-first-with-failure-to-send.png 450w, /static/0fc82c63fe5c176d740233df6edd8d89/16786/save-first-with-failure-to-send.png 478w" sizes="(max-width: 478px) 100vw, 478px" loading="lazy" /> </a> </span></p> <p>However, now we've got a new problem. We successfully save the state but if we failed to send the messages. If we retry now, we'd risk doing the work again, creating duplicates or sending different (invalid) messages. This is a risk because the database could again be in a different state to the first attempt. In fact, the database will always be in a different state because we just wrote to it!</p> <p>We could also check to make sure we haven't already handled this message and abort processing, but then no messages would be sent at all. The process would stall, and data would fail to propagate.</p> <h3>Sending and Saving Atomically</h3> <p>What we really need is a way to do both at once. We need to store the updated state and any messages we intend to send inside a single transaction. We need this step to be atomic. If we look towards the database, we can achieve this by writing those messages to the database along with the state. In doing so, we won't leak messages before we save, and we won't lose them after either.</p> <h2>Using an Outbox</h2> <p>Saving our state and messages inside the same transaction is the core principle of the Outbox pattern. However, there's a bit more to do before we're finished. We still need to send the messages via the Outbox.</p> <p>Once the state and the messages have been persisted the next step is to <em>attempt</em> to send the messages in the Outbox. After the messages have been sent to the Service Bus we need to make a second update to the database, marking the messages as sent (dispatched).</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 478px;" > <a class="gatsby-resp-image-link" href="/static/83b69f9837a64e7b51c975153e54d998/16786/outbox-with-mark-as-sent.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 112.55230125523012%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAXCAYAAAALHW+jAAAACXBIWXMAAAsTAAALEwEAmpwYAAACiElEQVQ4y6WVy3ITMRBF/f+fwQdQQLECdiygiueSVDJx7BA/MrbL9ryf4lxFMnI8wwZVqVqalm53X11pJlmeG9O2Ji9LU9e16RlXWI1l+6Yx2ywzn5ZLa0N/Q18libna7cwGX8Paiek6M2fyaj43b+/vzQZgtd48tabvzcvZzLyIIrsm9C1I5g17fmy35jW+PQEmiqTJt83GfFgszMfVyi7u+qdth6oyX+LYPBaFtXvmvs3T1CxIRu2OTFcEsIDvAHr/8GCBvxMtBBTAzfFoxxF2FwDOAFQgD24BO+o+Avr58dF8JcsaCmxZDrCCs58EudrvrfV+mz37VK4CylewdiKCnzcP5q1axuLQ732qJCMp32zJlnw+Nmzqgw2+d2TVOcAwyMmvfW58BlgPZOuz8JWcBZOPYCW8+kAnQDl6ZSJgFjSua1xCfBuUdRHQZXgGqCgxErgTyUjnmh5xUNcI+hcK+H04WI3qVGO67Jb5lAOJkYzP/i8gzpKxzrBz4vXn2apkMpRtqMJ3zQu+p7ptbs8JMCHimgwLFuaUUGIlg5QNCdknBNRJJ6zP+aYuX6q5AB2nFxkW2ASRpoDrnutAWoAax+GFApQ1vksOAdoAMOOii7tovbZWvEXwt3dXLJSNn48Cjolc/KUBYCjsUUBxuKRUcSiuzro4c3d2qORadAxlKD21zEtKrwCQlRYLvYPBHX7e2iEdVgBuAZjzCEx5JKY8VTfwOEOXt4xXZB8P6PD2XzrMySbUoe/SmxQwpEO9RoM6lFwWRJK+MtelMWntSKCjAupX4X2uZ9Kh5/cMkI/1yAMgjkR8P3Yo+vf418YL1j5RI8T7J2z0cQh8k4wTtH84vSzO/k//A8EnBRqnpw1sAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Outbox sending messages then marking them as sent" title="Outbox sending messages then marking them as sent" src="/static/83b69f9837a64e7b51c975153e54d998/16786/outbox-with-mark-as-sent.png" srcset="/static/83b69f9837a64e7b51c975153e54d998/064a4/outbox-with-mark-as-sent.png 225w, /static/83b69f9837a64e7b51c975153e54d998/44727/outbox-with-mark-as-sent.png 450w, /static/83b69f9837a64e7b51c975153e54d998/16786/outbox-with-mark-as-sent.png 478w" sizes="(max-width: 478px) 100vw, 478px" loading="lazy" /> </a> </span></p> <p>However, there are still three separate actions being performed here, and any one of them may fail. We're safe if the first step fails because our system will still be in a consistent state. No messages are lost or leaked. However, if the second step fails, we'll still need to send those messages.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 478px;" > <a class="gatsby-resp-image-link" href="/static/200a47de33dbb09ae377ed06f306a274/16786/save-state-and-messages-with-failure-to-send.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 87.23849372384937%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB8klEQVQ4y62UW08bMRCF8/9/RV/7An2qqISQKvWFIkGlFlpE0DYJuSy5Z+/X6TeON3KWBfWBkUb2+njOjMfH24viWKQsJUpTyfNc6qKQjFHnOio22m7l+2wmSZZJafEC129vs5HH9VpC4nWtJ1UlXhjK6WAgn5+eZKMkWC17WxP00fPkQ78v33zfrFX1Hr1aLORiOjXrX0mo1ssI+DQcyo/lUr6Mx3I5nxugJJHaJIrkFxX4SSLXEBR2Xe2e6hJOUJLgD3PFenq088lEzqjuhCoVMIS2ijGESqp2B5Y7hL/5zuz3HUkNYUVPIvyGCnWxtkTNGJLw52olt2AP9NI98thWr3FeENgj25651iZVcytzMSUvnP3myCaAKgu8AVwvtE943caUsIUdCAuHsG0V1WmQzXZUoa67hRwIS5sp5jYDZBRaD+jNlt41hO0Km7gXhAlEzzR5SIP/Ig/jXJSHjB7R2QzyOeKds+/gfPfZrwLvJExbom5MNal91As4crAUsqyLcMcTXOAZiwkEOWPKGNOfkACVj8pLx9hKLcQD+2RfEKYAMfMl/fI5qrrOUzaFJKrBu6x2LuyIUC9jSaBPr6a7nUx4BTMIV2wejEZS4W3ZyFuXYv40jTS6qrDC/m/CRmv1K9KoWi+lU6P69NyGvof/A9m9L/6ur6HtAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Save messages and state to database then fail to send" title="Save messages and state to database then fail to send" src="/static/200a47de33dbb09ae377ed06f306a274/16786/save-state-and-messages-with-failure-to-send.png" srcset="/static/200a47de33dbb09ae377ed06f306a274/064a4/save-state-and-messages-with-failure-to-send.png 225w, /static/200a47de33dbb09ae377ed06f306a274/44727/save-state-and-messages-with-failure-to-send.png 450w, /static/200a47de33dbb09ae377ed06f306a274/16786/save-state-and-messages-with-failure-to-send.png 478w" sizes="(max-width: 478px) 100vw, 478px" loading="lazy" /> </a> </span></p> <h3>Retry based dispatch</h3> <p>Unlike our earlier attempt of saving first then sending to the service bus, this time we can take advantage of our new Outbox! Now if we encounter an error, we can retry processing the message except we'll only want to send the messages we already have.</p> <h3>Asynchronous dispatch</h3> <p>Messages that aren't redelivered after a failure, require us to also use some method of asynchronous dispatch. Either because the maximum number of tried was reached or because the message isn't configured to retry at all. Asynchronous dispatch allows us to check for unsent messages that fall through the cracks.</p> <h3>At least once delivery</h3> <p>After all that, we should now be in a position where a message will always be delivered to the Service Bus, <em>at least once</em>. At least once delivery is an unavoidable property of distributed messaging. Furthermore, we've been relying on it a bit already. When messages aren't successfully processed, aka there's a failure before the message is acknowledged, we depend on the message being redelivered so we can retry.</p> <p>So, on the delivery side, there could be a failure to deliver a message:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/85311166dcb1f8e13789de45c31d89e3/9435c/app-delivery-failure.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.61855670103093%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAArklEQVQY012Q3Q7CIAyFef9X8cr3MHqp8WouMf6EuMVtsFngeFpnoiP5oPTn0OJ8CNg3DSYRCCml/MENY0oGZl/OGblku1/7Hse2RWJccQeKraoK3esFXd+AoYV8ZOs9NkQFsiTEZ4MwBSZn7Ohf1zUi83Q5NVTMx4jHOJqA/IiqfeEUp67DxDztLiWxmNpa35PbMNjpZFZWx51YF4uRtVMhy+/4iCerP3P0lg29AQ/fOBxJmC0kAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Application failure and redelivery" title="Application failure and redelivery" src="/static/85311166dcb1f8e13789de45c31d89e3/fea0e/app-delivery-failure.png" srcset="/static/85311166dcb1f8e13789de45c31d89e3/064a4/app-delivery-failure.png 225w, /static/85311166dcb1f8e13789de45c31d89e3/44727/app-delivery-failure.png 450w, /static/85311166dcb1f8e13789de45c31d89e3/fea0e/app-delivery-failure.png 900w, /static/85311166dcb1f8e13789de45c31d89e3/9435c/app-delivery-failure.png 970w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>A failure while processing a message:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/92af90ab64b5f27b2d89ad8445cfc278/9435c/app-processing-failure.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.61855670103093%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAq0lEQVQY011Qyw7CIBDk/3/Fm9/ReNV4qlpjNMQ2FgrlNe6QNqluMrDsDMMuSk8Tjn2POUZEQSnlB7LAp1SBTT1XDnhai/MwIAlPqJOY7doWYwhgrERFzsjyyEFrNAIarlwkN1k03RX7WwcnOoZiQjPtHN7eV4O4MWX+kCku44hZdFmMWOcegsfHGVg5s1Mjd1VcnFl4CbCMsx2ZnbKj/++gLqdcNXdjMEhDXxnWOB3peRadAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Application failure and redelivery" title="Application failure and redelivery" src="/static/92af90ab64b5f27b2d89ad8445cfc278/fea0e/app-processing-failure.png" srcset="/static/92af90ab64b5f27b2d89ad8445cfc278/064a4/app-processing-failure.png 225w, /static/92af90ab64b5f27b2d89ad8445cfc278/44727/app-processing-failure.png 450w, /static/92af90ab64b5f27b2d89ad8445cfc278/fea0e/app-processing-failure.png 900w, /static/92af90ab64b5f27b2d89ad8445cfc278/9435c/app-processing-failure.png 970w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>Or a failure when sending messages a message acknowledgment, which may be lost even though the message was processed.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/7859d585c167b5eaffd63a3fa8792d83/9435c/app-ack-failure.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.61855670103093%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAqklEQVQY01WPzQ6CMBCE+/6v4sn3MHrUeEIS408aaaRQoC3jTAMJbvLRzU6Z7Rjb9zg3DcYYEck8z3/wgyGlAjbzvGhP73F1Dom6MBea7aoK7TRBtQqFnJG55GgtDkQGqxa1IEWcON/XNQLvqYwamdkQ8BmGYhA3puofTHFr25IiBI/x65C1jJr+9+TVdeU0cXHW4E2wxNlG1ksjKVF10mjttVR1Z3THB/0AHrY4F/ycApoAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Application failure and redelivery" title="Application failure and redelivery" src="/static/7859d585c167b5eaffd63a3fa8792d83/fea0e/app-ack-failure.png" srcset="/static/7859d585c167b5eaffd63a3fa8792d83/064a4/app-ack-failure.png 225w, /static/7859d585c167b5eaffd63a3fa8792d83/44727/app-ack-failure.png 450w, /static/7859d585c167b5eaffd63a3fa8792d83/fea0e/app-ack-failure.png 900w, /static/7859d585c167b5eaffd63a3fa8792d83/9435c/app-ack-failure.png 970w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>This means downstream services may receive messages more than once.</p> <p>Next up, On the dispatch side, if multiple messages are sent, some may get through, but a failure can make it impossible to know which messages are successfully delivered. Even if the messages are dispatched one at a time, messages may still be sent multiple times due to failures.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/9b0a0738f2f72825917f05d2afae9001/9435c/app-dispatch-failure.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.61855670103093%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAq0lEQVQY012P2wrCMBBE8/+/4pP/Ifqo+FQLopVgS9N7LuNMbEFcOCS7m8zOGjsMONc1Zu/hSUrpS4yIhAmmEDLYeiQS5c+uw7VpENgX5kKxXVHALQsUKuqxdy36oUVifrQWByKB/JGDvAaQE+v7ssRIMwqji8TsOOI9TYhyuk4Tuj+4xc05zHwn11svEv3vSNX3+TR+VVbhRbCuk37Ijkj6q2/iijtXb2joAw5VOB/7iCNXAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Dispatch failure and redelivery" title="Dispatch failure and redelivery" src="/static/9b0a0738f2f72825917f05d2afae9001/fea0e/app-dispatch-failure.png" srcset="/static/9b0a0738f2f72825917f05d2afae9001/064a4/app-dispatch-failure.png 225w, /static/9b0a0738f2f72825917f05d2afae9001/44727/app-dispatch-failure.png 450w, /static/9b0a0738f2f72825917f05d2afae9001/fea0e/app-dispatch-failure.png 900w, /static/9b0a0738f2f72825917f05d2afae9001/9435c/app-dispatch-failure.png 970w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>For these reasons (and few more I don't have time for right now) it's a good idea to make message processing idempotent. Or in other words, making them safe to process multiple times. As an added optimisation, we can also store the Id's of the messages we have successfully processed and use them to drop any duplicate messages. This can help us to avoid further unnecessary processing. Then we can jump straight to sending any unsent messages.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 299px;" > <a class="gatsby-resp-image-link" href="/static/6c10e78f3bc3fab8a03c66da4ddb6b01/b9a2f/transaction-inbox-outbox.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 41.47157190635451%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB6ElEQVQoz52SX0hTYRjGDxoEUhFWBBVElDd1EWiBhlAQBRLUdXcRBEGBRSO1lSaFShHdBLLE7Wxzfy4as2QgGuSSUdBFF+XsYnNnW3gmO3PbOfuXkL8+T2MXXfbBj+d7H14eeHlfqVAoYJRK6IaBvqWCgq6TF36+WGxosVhgq9dE/E3fJG9S1EVvPo9UrlQw1tcp53KUNM2EjQ3+5+mGjlQtl/mcTuNbWsJfJxiPM5NMMqMoBBMJPq6qpFIKyz+iRKPfSaQTRJQvhGOf+BCLEFp+z9f0NyqlMtJmtcqtSIS26WkOBwI0uVw0C5qcTrYJpMlJOkMhvG4HT8eGGX5sxeazccF5lTPjlzn1qoeWoWPcDPTBr99IiMDr4TCSLNPq9bLL42mwW9TNIvT83BwueQJL/x0eWu8jB2RO2y5xaLSDthfd7B85Se/bR2zW6oHXFhaQ7HZ2ipCWqakGOwSS7ODs7CxOx2vu9fXyYMCC/Y2djvEeDoy0c/R5F3uenOB20FoPrNW4sbhojrrP76fV52uwV9Tb3W4uzs/jcdvpt1oYHBzAFXTRNXGFI886Of7yHAfH2rn7buhvYEmcyapYdyybZUVs+F/iwk+LK9C0LKqqksmoaDmNVPYnibUkylqKFaFqLoOhG/wBInz2KWfArqoAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Transaction containing state, inbox and outbox" title="Transaction containing state, inbox and outbox" src="/static/6c10e78f3bc3fab8a03c66da4ddb6b01/b9a2f/transaction-inbox-outbox.png" srcset="/static/6c10e78f3bc3fab8a03c66da4ddb6b01/064a4/transaction-inbox-outbox.png 225w, /static/6c10e78f3bc3fab8a03c66da4ddb6b01/b9a2f/transaction-inbox-outbox.png 299w" sizes="(max-width: 299px) 100vw, 299px" loading="lazy" /> </a> </span></p> <p>We can refer to this as the Inbox. We also don't need to keep things in the Inbox forever. I usually opt to keep a certain window, such as Id's no longer than 30 minutes old, or the first few thousand.</p> <h3>Using a relational database</h3> <p>We've talked a lot about a database but not what kind of database because all that matters is that the Inbox, State and the Outbox are all inside the same transaction. In a relational database, I'll usually use a separate table for the Inbox and Outbox. The Outbox will usually have the following columns:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">- SequenceNo (Clustered Primary Key) - MessageId - AddedAt - Metadata (json) - MessageType - Payload (json) - Dispatched (bool) - DeliveredAt (datetime)</code></pre></div> <p>You can also remove messages from the Outbox after they're delivered and processed if they're of no further use.</p> <h3>Using a document database</h3> <p>You can also use the Outbox pattern with a Document database. However, it's typical for document databases not to have cross-document transactions. In this case, we can still achieve our requirement of keeping the Inbox and Outbox inside the transaction by storing them inside each document instead.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">{ id: &quot;product-1&quot;, name: &quot;phone (model x)&quot;, stockLevel: 9, backorderAvalible: false, inbox: [ &quot;m-1&quot;, &quot;m-2&quot;, &quot;m4&quot; ], outbox: [ { id: &quot;m-5&quot;, type: &quot;QuantityReserved&quot; ... } ] }</code></pre></div> <p>Many Document Databases will let you run queries so you can find unsent messages. If you're using Azure CosmosDB the change feed is a fantastic method of subscribing to changes through the database.</p> <h2>Final Notes</h2> <p>The real world often forces us to think about all the ways our software can fail. The Outbox presents a robust method of reliable message delivery in the face of failure. It's incredibly important to build this reliability into our systems. Otherwise, when things inevitably fail, data inconsistency and data loss will happen.</p> <p>As an industry, I worry that it's all too common to see companies delay or avoid implementing reliable messaging. Instead, hoping that these failures won't happen (yet). And while some of these failures can be rare, the alternative is often much worse. When message silently go missing or messages are leaked it can quickly become a big issue. One that's often difficult to resolve.</p> <p>Finally, I'd like to point out this certainly isn't the only way to tackle the problem of reliable messaging. But when it comes to messaging and a ServiceBus it's certainly an invaluable tool to have at your disposal.</p> <p>Happy Outboxing.</p><![CDATA[Why you need Reliable Messaging]]>https://daniellittle.dev/why-you-need-reliable-messaginghttps://daniellittle.dev/why-you-need-reliable-messagingWed, 16 Jan 2019 00:00:00 GMT<p>You might have heard the phrase "there's no such thing as reliable messaging". It's an interesting statement, but aside from being completely untrue, the statement is also entirely unhelpful. What you can't have is "completely reliable messaging", but the real question is how close can you get? How close do you need to get?</p> <p>The concept of Reliable Messaging is broad and can be somewhat complex at times. I won't get into all the details just yet. Instead, in this post, I'm going to establish what exactly Reliable Messaging is and why it's so important.</p> <h2>What is Reliable Messaging</h2> <p>Reliable messaging is the concept of commutating with certain guarantees about the successful transmission of messages. For example, if the message is delivered, that it is delivered at least once. In contrast, this can be compared best-effort delivery, where there is no guarantee that messages will be delivered at all. I'm going to focus on message delivery and reliability, but reliable messaging may also refer to message ordering. </p> <p>These guarantees don't need to be baked into the protocol or framework you're using either. An interesting property of reliable messaging is that you can add more reliability at higher levels. You can build reliable protocols on top of unreliable protocols. The best example of this is TCP which is built on top of the IP protocol.</p> <p>The most important aspect of Reliable Messaging is, at the end of the day, the only way to know if something is done is by receiving a message saying it was done. But before I explore exactly why Reliable Messaging is so important, I'll go on a brief tangent to have a look at why you can't have Completely Reliable Messaging.</p> <h2>Why you can't have Completely Reliable Messaging</h2> <p>Reliable Messaging can't provide complete reliability for a number of reasons, but you only need one negative example to disprove something is not absolute. In a distributed system the receiver could be faulty, offline, or explosively dismantled and spread around all corners of the globe. Even if the receiver works perfectly, the communication medium may be unreliable in many different ways. The sender may also be unreliable, it may crash, or simply contain a bug or other logic error. You can't guarantee anything in a world where anything can fail, but you can plan for failures.</p> <h2>What makes Reliable Messaging important?</h2> <blockquote> <p>It is necessary to understand how a system can fail and how to deal with failures when they inevitability occur. </p> </blockquote> <p>When building any kind of distributed system it is important to know what guarantees are needed. Otherwise, the default is always best-effort delivery. Which means the system will loose data, without anyone knowing when, why or how. Even if there are no errors, exceptions or obvious signs. If messages fail to be propagated you might not realise anything went wrong for days, or months, or at all. </p> <p>Issues like this also tend to be expensive to track down and fix. Because they're found so late they may also end up being impossible to track down and fix. The core problem is, it is necessary to understand how a system can fail and how to deal with failures when they inevitability occur. In this sense, Reliable Messaging is a means to an end. </p> <p>Given that the core problem is dealing with failures, there are situations where you just don't need reliable messaging. In some systems manual monitoring and alerts could be enough; however, this is usually more indirect and coarse. Some actions may not be important at all, in which case best effort would suffice. If an action is user-driven then the user could manually retry instead. Otherwise, if you don't want to be manually adding reliability, because that get's expensive really quickly, then having a good strategy for Reliable Messaging is very important.</p><![CDATA[Automatic ModelState Validation for ASP.NET Core]]>https://daniellittle.dev/automatic-modelstate-validationhttps://daniellittle.dev/automatic-modelstate-validationMon, 02 Jul 2018 10:35:58 GMT<p>Model State Validation for a JSON API isn't too hard because you only need to send back validation errors, especially with the <code class="language-text">ApiController</code> attribute. However, for all those that are still using server-side rendering and Razor, it's still a bit challenging.</p> <p>It's challenging because you need to return the correct <code class="language-text">View</code> after posting a form. And the easiest method of getting the job done is writing this type of code in each <code class="language-text">Action</code>.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">if</span> <span class="token punctuation">(</span>ModelState<span class="token punctuation">.</span>IsValid<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">RenderTheGetForm</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>It does the job, but it's usually a lot of extra, tedious, code.</p> <p>Instead we can keep the <code class="language-text">Controller</code>s lean by shifting this code into an <code class="language-text">Action Filter</code> attribute which can be used similarly to the <code class="language-text">ApiController</code> attribute. So I decided to write one and publish it.</p> <p>Here's how it works. You install the <code class="language-text">AutomaticModelStateValidation</code> package and drop the <code class="language-text">AutoValidateModel</code> attribute on the <code class="language-text">action</code> that uses a View Model and validation.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token punctuation">[</span><span class="token class-name">Route</span><span class="token punctuation">(</span><span class="token string">"/[controller]"</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SubmissionController</span> <span class="token punctuation">:</span> <span class="token class-name">Controller</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token class-name">HttpGet</span><span class="token punctuation">]</span> <span class="token keyword">public</span> <span class="token class-name">ActionResult</span> <span class="token function">NewSubmission</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Load data for the blank form</span> <span class="token keyword">return</span> <span class="token function">View</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">NewSubmissionViewModel</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">[</span><span class="token class-name">HttpPost</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token punctuation">[</span><span class="token class-name">AutoValidateModel</span><span class="token punctuation">(</span><span class="token function">nameof</span><span class="token punctuation">(</span>NewSubmission<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token keyword">public</span> <span class="token class-name">RedirectToActionResult</span> <span class="token function">SaveSubmission</span><span class="token punctuation">(</span><span class="token class-name">SaveSubmissionViewModel</span> model<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Save submission to database</span> <span class="token keyword">return</span> <span class="token function">RedirectToAction</span><span class="token punctuation">(</span><span class="token function">nameof</span><span class="token punctuation">(</span>ViewSubmission<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token punctuation">{</span> Id <span class="token operator">=</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">[</span><span class="token class-name">HttpGet</span><span class="token punctuation">]</span> <span class="token keyword">public</span> <span class="token class-name">ActionResult</span> <span class="token function">ViewSubmission</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Load submission from database</span> <span class="token keyword">return</span> <span class="token function">View</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">ViewSubmissionViewModel</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>The <code class="language-text">AutoValidateModel</code> attribute on the <code class="language-text">SaveSubmission</code> <code class="language-text">Action</code> performs the <code class="language-text">ModelState.IsValid</code> check. If the model is valid everything continues as normal, however, if the model is invalid then the specified fallback <code class="language-text">Action</code> in is invoked and the <code class="language-text">ModelState</code> from the previous <code class="language-text">Action</code> is merged in.</p> <p>This means you're able to render the invalid <code class="language-text">Form</code> with validation messages and the appropriate HTTP status code with a single line of code!</p> <p>If you want to get started, grab the <a href="https://www.nuget.org/packages/AutomaticModelStateValidation/">Automatic ModelState Validation</a> NuGet package. And keep reading if you're interested in some more of the details.</p> <h2>The deep dive</h2> <p>One of the highlights of this attribute is to invoke the fallback action programmatically without another round trip to the client. In the past, I've achieved similar functionality by temporarily storing the ModelState and redirecting to the previous action. However, this time around I have made use of the advancements in <code class="language-text">AspNetCore</code> to bypass that step entirely.</p> <p>The bulk of the code resides in the <code class="language-text">AutoValidateModelAttribute</code> which implements the <code class="language-text">ActionFilterAttribute</code> class. After first checking that the <code class="language-text">ModelState</code> is invalid the next step is to determine check controller action to invoke.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> controllerName <span class="token operator">=</span> <span class="token function">SansController</span><span class="token punctuation">(</span>controller <span class="token operator">??</span> context<span class="token punctuation">.</span>Controller<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>If the controller isn't explicitly specified then the fallback is the <code class="language-text">Type</code> name of the controller. Here I also remove the <code class="language-text">Controller</code> suffix.</p> <p>Next, I have to locate the relevant <code class="language-text">ActionDescriptor</code> by getting the <code class="language-text">IActionDescriptorCollectionProvider</code> and finding the matching descriptor.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> controllerActionDescriptor <span class="token operator">=</span> actionDescriptorCollectionProvider <span class="token punctuation">.</span>ActionDescriptors<span class="token punctuation">.</span>Items <span class="token punctuation">.</span><span class="token generic-method"><span class="token function">OfType</span><span class="token punctuation">&lt;</span><span class="token class-name">ControllerActionDescriptor</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">FirstOrDefault</span><span class="token punctuation">(</span>x <span class="token operator">=></span> x<span class="token punctuation">.</span>ControllerName <span class="token operator">==</span> controllerName <span class="token operator">&amp;&amp;</span> x<span class="token punctuation">.</span>ActionName <span class="token operator">==</span> action<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>To invoke the <code class="language-text">ActionDescriptor</code> the next thing I'll need is an <code class="language-text">ActionContext</code>. Here is also where I pass along the previous <code class="language-text">ModelState</code> so the validation errors are carried through to the new <code class="language-text">Action</code>.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> actionContext <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ActionContext</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span>HttpContext<span class="token punctuation">,</span> context<span class="token punctuation">.</span>RouteData<span class="token punctuation">,</span> controllerActionDescriptor<span class="token punctuation">,</span> context<span class="token punctuation">.</span>ModelState<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>The last major piece is getting an <code class="language-text">IActionInvokerFactory</code> to create a <code class="language-text">ControllerActionInvoker</code> and then invoking it.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> actionInvokerFactory <span class="token operator">=</span> <span class="token generic-method"><span class="token function">GetService</span><span class="token punctuation">&lt;</span><span class="token class-name">IActionInvokerFactory</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> invoker <span class="token operator">=</span> actionInvokerFactory<span class="token punctuation">.</span><span class="token function">CreateInvoker</span><span class="token punctuation">(</span>actionContext<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">await</span> invoker<span class="token punctuation">.</span><span class="token function">InvokeAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>After that, there was just one more problem to fix. When no <code class="language-text">View</code> is explicitly specified when returning a ViewResult, AspNet Mvc will fall back to using the action name from <code class="language-text">RouteData</code>. Because I'm invoking a second Action inside a single Request the wrong view will be used unless I update the <code class="language-text">RouteData</code> to match. So, I also set the action name to the name of the fallback action before calling the <code class="language-text">ControllerActionInvoker</code>.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">if</span> <span class="token punctuation">(</span>context<span class="token punctuation">.</span>RouteData<span class="token punctuation">.</span>Values<span class="token punctuation">.</span><span class="token function">ContainsKey</span><span class="token punctuation">(</span>ActionNameKey<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> context<span class="token punctuation">.</span>RouteData<span class="token punctuation">.</span>Values<span class="token punctuation">[</span><span class="token class-name">ActionNameKey</span><span class="token punctuation">]</span> <span class="token operator">=</span> controllerActionDescriptor<span class="token punctuation">.</span>ActionName<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>If you're interested in the full source code you can check it on <a href="https://github.com/Lavinski/AutomaticModelStateValidation">GitHub under Automatic ModelState Validation</a>.</p><![CDATA[Running .NET on the Raspberry Pi]]>https://daniellittle.dev/running-mono-on-the-raspberry-pihttps://daniellittle.dev/running-mono-on-the-raspberry-piMon, 27 Nov 2017 04:59:57 GMT<p>I recently got my hands on an older <a href="https://www.raspberrypi.org">Raspberry Pi</a>, which was a great excuse to see if I could get .NET running on it! If you're interested in playing around with a Pi or just want to see what it's like to get one running, then you're in the right place. I'll take you through setting it up, installing some programs and compiling some C# on the device with a few failures along the way.</p> <p>I knew this Raspberry Pi was an older model, but I wasn't entirely sure what model it was. Figuring that out seemed like a good first step because that might impact what OS I can run. Plus I wanted to make sure the model I had was able to run <code class="language-text">.NET</code>. So my first challenge was to figure out what model I had.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 737px;" > <a class="gatsby-resp-image-link" href="/static/040c9c3b9e8c28d20dfa158974f24f2a/7dae4/PiModelB1Cleaned-1.jpg" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 68.24966078697422%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAEDAgX/xAAVAQEBAAAAAAAAAAAAAAAAAAACAf/aAAwDAQACEAMQAAABpqDJ64yr/8QAGhABAQACAwAAAAAAAAAAAAAAAQMCEQAEFP/aAAgBAQABBQJ7FB9TvCo4s1SPJY6n/8QAFREBAQAAAAAAAAAAAAAAAAAAECH/2gAIAQMBAT8Bp//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABsQAAIBBQAAAAAAAAAAAAAAAAABIRAyQWGR/9oACAEBAAY/ArlyikwaFCP/xAAbEAACAwADAAAAAAAAAAAAAAAAAREhQTFhcf/aAAgBAQABPyGGdgfGpDOdtofs+jJxyFoOg//aAAwDAQACAAMAAAAQCx//xAAXEQEAAwAAAAAAAAAAAAAAAAAAAREh/9oACAEDAQE/EIsx/8QAFhEBAQEAAAAAAAAAAAAAAAAAEQAB/9oACAECAQE/EE1sS//EABwQAQACAwEBAQAAAAAAAAAAAAEAESExQVFhcf/aAAgBAQABPxByqDx1dT3gUNCX1+kKG106iWU0ysZxyNJfIVHT8/ImwisF45P/2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="A Raspberry Pi, Model B, Gen 1" title="A Raspberry Pi, Model B, Gen 1" src="/static/040c9c3b9e8c28d20dfa158974f24f2a/7dae4/PiModelB1Cleaned-1.jpg" srcset="/static/040c9c3b9e8c28d20dfa158974f24f2a/40f63/PiModelB1Cleaned-1.jpg 225w, /static/040c9c3b9e8c28d20dfa158974f24f2a/df2c7/PiModelB1Cleaned-1.jpg 450w, /static/040c9c3b9e8c28d20dfa158974f24f2a/7dae4/PiModelB1Cleaned-1.jpg 737w" sizes="(max-width: 737px) 100vw, 737px" loading="lazy" /> </a> </span></p> <p>At first glance, it looked like it would be a bit more difficult than I was expecting because there's no clear version number printed on the board and quite a few variations which are very similar. I found <a href="https://en.wikipedia.org/wiki/Raspberry_Pi">Wikipedia</a> to be the best way to identify a Raspberry Pi. It lays out each model nicely and shows the mounting holes, components, ports and logo which you can use to determine your exact model.</p> <p>From there I was able to determine that the model I had was the Model B (Gen 1). Now that I knew what I was dealing with, it was time to see if I could get it to boot. For that, I needed an <a href="https://elinux.org/RPi_SD_cards">SD card that would work</a>, a USB Micro cable and a <a href="https://www.raspberrypi.org/blog/power-supply-confirmed-as-5v-micro-usb/">USB adapter</a>. Luckily, I had more than enough phone chargers and a few old SD cards lying around.</p> <p>My first few attempts at getting the Pi to boot were completely unsuccessful. To this day I don't know if it was because of the SD cards I tried or the <a href="https://developer.ubuntu.com/core/get-started/raspberry-pi-2-3">Raspberry Ubuntu image</a> I tried. But I may have run into almost every issue you can have (probably not, but it sure felt like it) and the quite extensive <a href="https://www.raspberrypi.org/forums/viewtopic.php?t=58151">guide to troubleshooting boot issues</a> didn't help either. However, somewhere along the way, I got my first image on screen!</p> <p><img src="/../../images/running-mono-on-the-raspberry-pi/IMG_20170820_135411.jpg" alt="Rainbow Square on Monitor"></p> <p>Is that the Raspberry Pi rendering a nice rainbow square on screen? No, it's actually just rendering four pixels that have been scaled up to fit the screen. This happens when the <a href="https://raspberrypi.stackexchange.com/questions/19354/raspberry-pi-with-boots-up-with-rainbow-screen">GPU firmware successfully loads</a> but then something later in the boot process goes wrong, such as an invalid image on the SD card. Although you'd be forgiven for mistaking it with the <a href="https://www.raspberrypi.org/forums/viewtopic.php?f=91&#x26;t=95430">small rainbow square</a> in the top right that indicates a low voltage from the power supply.</p> <p>After trying a few different SD cards, I decided to ditch Ubuntu and try one of the <a href="https://www.raspberrypi.org/downloads/">officially supported images</a>. I decided to try NOOBS first, which is an operating system installer that lets you pick from a few different operating systems including Raspbian (the official Raspberry Pi OS). This time I had a bit more luck, not much more, but more nonetheless. The Pi successfully booted! I pick Raspbian and wait for it to install.</p> <p><img src="/../../images/running-mono-on-the-raspberry-pi/IMG_20170820_143942.jpg" alt="NOOBS installing Raspbian"></p> <p>And wait. And wait. I think it got to about 20% before refusing to progress any further. It may have just been really really slow, but I was starting to consider that maybe there's something wrong with the device. At this point, I'd been at it for a while, so I decided to leave it for another weekend.</p> <p><em>One Month Later</em></p> <p>I find myself looking at a <a href="https://raspberry.piaustralia.com.au/">Raspberry Pi Zero W</a>, they're cheap and relatively easy to get. But not "already on my desk waiting for me" cheap. It's time to give this thing one last shot.</p> <p>This time it's straight to Raspbian, in particular, Raspbian Lite (which doesn't contain a GUI). I skipped over the process of getting the OS onto the SD card earlier, but I wanted to point out how nice it is. Once you've <a href="https://www.raspberrypi.org/downloads/raspbian/">downloaded the image file</a>, which is just a zip, in this case, you use <a href="https://etcher.io/">Etcher</a> to write the image to the card. It's a three-step process of selecting the image, choosing the drive and clicking start, it's fast and flawless. I plug in the mouse, keyboard and monitor, insert the SD card, and plug in the power. And it Boots!</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/c513adc162c672efaf35c051205da375/53a76/PiBootSequence.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 76.90742624618515%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAA7DAAAOwwHHb6hkAAADM0lEQVQozxXRV2/iCBQFYL+uAjHNxhXcsDEdTE0IA4GYHno1ppgaSCBVq1VmVpmMNKv51+tIR/ft07lXF4BBIymQ1IVQlhvFSvNGrtdv+0W5kc2VKrVuPJHmXW6bxQoajCaD4dxwBp6dWQxntnOj3QwCdhBESQR1k7Vqt9+fD8faYLzs9ubV20FvuLxtja7zlatMAUUw0AiaQNB0fm4FQchswmxWADGZERxBXY5CvtpqK52Omr9plKr9Sn1Yb07kSk+KpgOBBAITVrPNZrXqW0BWyG6DCBgGELPN4eXYq2A+WyvVerUvo1QbSrmutPpava3GErloPIOhtB3CYQizw4geFEFxFAXsFsjp513ZSLc1741W6uJ+qOwGyt1Q3c/Xz+P5QywlO2gvijEQTKCIE0McGErgKE7iBGC3wlRQZHNSqzEbTQ+94Wak7merl+nqefvwrmgnRXvsjnepTDkc/4biHE4wOM44cMZJ0ABiQ6igj87F5Jt+q78u1ia3HW24OBUbark1C8TzfiknBq5w0kOQHgTjUIzVPYZRDoLVMUq63VRS6nTX7eFuoJ7602NHPZTac2/0GmVCBBdx8pJLTPJi0u1J8G5JECV/MMFxXgC2oTCs/4rVa5f79+nqb+3uXbv/sTp97B5/lttapaNVuloy1wgni1JCjiVlKZ67SJfcHgmAIAyyOzFMaPa3i7vvivY22/wzWrx8qyiXcv9KHiSyzdBFOZQqSqlSIJJjuDDNBijG52S8OsbtTpdDDDc6u8HstTt5Wuz/VZZvo8VbZ/rUVo+N0T6ebQaScjRdCcUKrBB1CRFOCDGcT8ckLviYeGoweZ7vfiwPH9rhQ5+b48f64Wd7csrX1FimcVnoilKOdEUYd5zhwxwfolk/YLEgCCU4fdHh9PXu6ff+8b/t8fP+9c/29Gtz+kxet72xvC9W0MOHMrSYoIUoJYRpl44DgMUIO8JBvpgbjF8nm/f1w+f9y5/l4VPdfv+6QjkW6irnS1FfRnLyYQcXJDm/g/URrAcw/GWyIgRCcTQbYVxx3nfJ+9O8Ly0EM3wwHYzlOU+MdkdYUaL4kM5I1kPQIkEJhNP1Py/CzqlD3Qr7AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Pi Boot Sequence" title="Pi Boot Sequence" src="/static/c513adc162c672efaf35c051205da375/fea0e/PiBootSequence.png" srcset="/static/c513adc162c672efaf35c051205da375/064a4/PiBootSequence.png 225w, /static/c513adc162c672efaf35c051205da375/44727/PiBootSequence.png 450w, /static/c513adc162c672efaf35c051205da375/fea0e/PiBootSequence.png 900w, /static/c513adc162c672efaf35c051205da375/53a76/PiBootSequence.png 983w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>If you're wondering why that picture is so much clearer than the others, it's because I've switched from using a TV to a computer monitor. I didn't time how long it took, but I'd take a guess the Pi took around a minute or so to boot. After which I was prompted to log in.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Raspbian GNU/Linux 9 raspberrypi tty1 raspberrypi login:</code></pre></div> <p>There's already a default user. A quick search for the <a href="https://www.raspberrypi.org/documentation/linux/usage/users.md">default credentials</a> reveals Pi's secrets (u: <code class="language-text">pi</code> p: <code class="language-text">raspberry</code>). And I'm in!</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 719px;" > <a class="gatsby-resp-image-link" href="/static/fc6dd56a35f6799d43addfe78c160d75/04c1a/PiFirstBoot--2-.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 31.710709318497916%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsSAAALEgHS3X78AAABU0lEQVQY0w3C606CUAAAYJ5BWTXn3LwDogKpiOA5eIDDDoJ4yfsdKxVctFm/6uHr20dJ5fTMw54FfWL2MdLVNlAUBIAqtxuSVMjn6UTikaafksknOvE//ZDMpmixlAFCnpIr2Z97/B3ffGIRy1DlpsBXKwwrClKpxDAMly+UWJbnuArP86Ig1rmKLIl8LtWpZimJzQwwHNjIJzZGCGia3GqrKoS6qQGjh4jS0RtNVdfNHjKh3sOm5WDbhhruNqhmtXh7D+5xHBwOl/M1DD82u9Mlitfb0z64Hl6j+9fvbLkfvSzWm+N0vnLdwXQ08R3HQRpVY3Jjtz/yXK/vEuLCnmWRgeNPZ6vjZL4bztbL7Wmzf1O6SHhuKSoAEHbaClvINWtlqs4Vw/ByjcJLFO2D8+n8OV8H3nhhO0NMfIgI0HHfHRvYbSldCA3DsDStW+N5War+AUOUXZMzeiltAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Loging into the Pi" title="Loging into the Pi" src="/static/fc6dd56a35f6799d43addfe78c160d75/04c1a/PiFirstBoot--2-.png" srcset="/static/fc6dd56a35f6799d43addfe78c160d75/064a4/PiFirstBoot--2-.png 225w, /static/fc6dd56a35f6799d43addfe78c160d75/44727/PiFirstBoot--2-.png 450w, /static/fc6dd56a35f6799d43addfe78c160d75/04c1a/PiFirstBoot--2-.png 719w" sizes="(max-width: 719px) 100vw, 719px" loading="lazy" /> </a> </span></p> <p>The first thing I noticed was that the keyboard layout was different. Typing the pipe symbol <code class="language-text">|</code> instead inserted a hash <code class="language-text">#</code> which indicated a <code class="language-text">UK</code> keyboard layout. Most settings for the Raspberry Pi can be updated by entering the command <code class="language-text">sudo raspi-config</code>. You can also change your password and <a href="https://www.raspberrypi.org/documentation/remote-access/ssh/">enable SSH</a> from there.</p> <p>The steps to change the keyboard layout are fairly straightforward. Well, except for selecting a non-UK keyboard because those are all grouped under <code class="language-text">Other</code>. Here's the complete set of steps in case you were wondering.</p> <ol> <li>Select Internationalization menu</li> <li>Select keyboard setup menu.</li> <li>Select your keyboard (or pick one of the generic models)</li> <li>Select [Other]</li> <li>Select [English (US)]</li> </ol> <p>Now I had a fully functioning Pi. So it was time to see if I could install some variant of .NET on it, either <code class="language-text">.NET Core</code> or <code class="language-text">mono</code>. What you can run depends on the CPU of the Pi you have. But there are two main versions, <code class="language-text">arm v6</code> and <code class="language-text">arm v7</code>. All the specifications are on the same <a href="https://en.wikipedia.org/wiki/Raspberry_Pi">Wikipedia page</a> I mentioned earlier but if your Pi is running you can also use the following command.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&gt; uname -m armv61</code></pre></div> <p>You might have noticed that the same moniker is printed in the welcome message after you log in. The Raspberry Pi I have contains an <code class="language-text">armv61</code> chip the same as the Pi Zero. This is a different model from the new chip in the Raspberry Pi 3 which contains an <code class="language-text">arm v7</code> chip. Unfortunately .NET Core (and a few other languages such as node) currently only support the newer <code class="language-text">arm v7</code> architecture. This limited my options a bit, but, it turns out that Mono does support <code class="language-text">arm v6</code>. At this point, I can see the light at the end of the tunnel. I now have a method for running .NET on the Raspberry Pi.</p> <p>I still wasn't sure if I'd be able to compile .NET on the device or just run applications, so it was time to get empirical. There are two Mono packages you can install via <code class="language-text">apt-get</code>. The runtime <code class="language-text">mono-runtime</code> and everything, <code class="language-text">mono-complete</code>, which includes the compiler. I thought I'd take a stab at installing <code class="language-text">mono-complete</code>.</p> <p>The <code class="language-text">apt-get update</code> command is for updating the local package cache, so I'll get the latest version of the Mono package.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">sudo apt-get update sudo apt-get install mono-complete</code></pre></div> <p>My luck's really coming about now. Mono installs successfully, first time!</p> <p>Time to compile some code. I already had some C# I wanted to try out on the device, and I need my monitor back to get it. So it was time to switch to <code class="language-text">ssh</code> so I can access the Pi remotely. I used chocolatey to install openssh.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">choco install openssh</code></pre></div> <p>Plugged the Pi into the network, and realised I had no idea what the IP address was. A friend of mine had pointed me towards <code class="language-text">arp</code> earlier that day. A great little tool that lists all the IP addresses of devices on your local network. And while I quickly realised it is much nicer on unix-like systems, because it displays hostnames whereas I had to revert to manually looking them up (via <code class="language-text">nslookup</code>), it was still very useful.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&gt; arp -a Interface: 10.1.1.227 --- 0x13 Internet Address Physical Address Type 10.1.1.1 aa-bb-cc-dd-ee-1f dynamic 10.1.1.29 aa-bb-cc-dd-ee-2f dynamic</code></pre></div> <p>There weren't too many devices on my local network. I even chanced upon the correct Pi address on my first try.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&gt; nslookup 10.1.1.29 Name: raspberrypi.lan Address: 10.1.1.29</code></pre></div> <p>Now that I knew the IP address, I could ssh into the Pi and do the rest remotely.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">ssh [email protected]</code></pre></div> <p>The file I had to copy was fairly small, and I could have copied the file over with <code class="language-text">scp</code> but echoing out the contents into a file worked for me. Here's how to write hello world to a file.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">echo &#39;using System; namespace RaspberryPi { public class Program { public static void Main(string[] args) { Console.WriteLine(&quot;Hello World&quot;); } } }&#39; &gt; app.cs</code></pre></div> <p>Then it was just a case of compiling the program and running it.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&gt; mcs app.cs &gt; mono app.exe Hello World</code></pre></div> <p>So there we have it! Starting with an unidentified Raspberry Pi, some old SD cards and a phone charger. I managed to (eventually) successfully compile and run a .NET application.</p><![CDATA[cURL to Postman]]>https://daniellittle.dev/curl-to-postmanhttps://daniellittle.dev/curl-to-postmanTue, 14 Nov 2017 00:18:32 GMT<p>Postman is a fantastic tool for testing any HTTP endpoint. But if you're using your browser to look around and you find something of interest it can be a pain to recreate the request in Postman and copy across all the headers. There must be a better way!</p> <p>Turns out there is! Chrome and Postman both have support for cURL which makes it easy to copy any request from Chromes dev tools and into Postman. You can also export any Postman request as a cURL command which makes sharing much easier as well.</p> <p>In the Chrome Network tab, you can copy a request via a selection of formats. <span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 649px;" > <a class="gatsby-resp-image-link" href="/static/38474732d8a48ecdc75febc3b781c3fe/9a22e/Curl.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 45.76271186440678%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABM0lEQVQoz22QWVLDMBBEff97cQb4gRRJiG1to32zZNFOfkKRLpWW1rzRaKaVSxdzyrXUVmonbRUZbZwPkQuVy2Z9wNDWczKXhYWQe+s+FjJ+ui7i87zcFn75mbkkAFwQE8qFJMhgKLKlbtcbe7/OlLYPld7WkMpOrk5KScbWkrM1kHbOGk0ppa0WKSUXLMY4xmCMkZSjNe7jxYYd1ylNvffWGibApEkphei+70h6gr5O3+czTK11qRV+72Ps0Ohbm8Z9jxTOOXO8br33MEspHGJ8WdZ417Zt8AEjxUG1BzxQTlNSCinYynLOMGutQgjQcLQxz/D+DI87jMIUkRAqhgDHWbfMy22e5fGRYK19DT/KjgExwTtU7RCH5WjGXTg+WvP6ZVyjK3T0S2GPD6Ph46/+w7+ApQX2lKcCIAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Chrome Copy as cURL" title="Chrome Copy as cURL" src="/static/38474732d8a48ecdc75febc3b781c3fe/9a22e/Curl.png" srcset="/static/38474732d8a48ecdc75febc3b781c3fe/064a4/Curl.png 225w, /static/38474732d8a48ecdc75febc3b781c3fe/44727/Curl.png 450w, /static/38474732d8a48ecdc75febc3b781c3fe/9a22e/Curl.png 649w" sizes="(max-width: 649px) 100vw, 649px" loading="lazy" /> </a> </span></p> <p>Once you have your cURL request you can then use the import command and paste in the cURL command. <span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/91d9ae8a226bcf932ddc277160b65b39/3d4e0/PostmanFromCurl.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 68.39126919967664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAB6klEQVQoz4WRy4+aUBTG+Rd9dGIVpm3S2U+btE0qicoFLsg0XfjcK7rvvovu+hhHoVE7ca2C4aG2gIOgPTi1nVoz/fJBDveeH+fjQnz88L7z5dPnyw74qqdEVpSuqu78dV/srCg9Jdq9UtROr3fZ7RLPzzLnj04yZCSKItMP0w+SyXgslkwkUifJRDwOBsXicSqdfkKSqVTqMZU5JTPUKUUglmMREgWMhUgcFz3mcrlsNkvT2d+iaZrjeIz5AmKfvuCe0VFNRAzm4dqxAlPIq6rquq5l24vFwnEcqF3Pu/H9RqNRyOcRj89e4vPXLOYQwQuisJcoiiyTv77+tt1ufd8PgiAMw00Yrt1luHLa7TaEupCKby/ENxL0ioRQlIp3BNH6/T4MtG17Pp/DcCgs0/Acp9VqsYiRRJiGgYTmf2COg9iWZWmaNplMZrOZpulgeJ0sywyDABL2YQ9hWILJpmmOx2PgAdZ1HYYDHMVmWUn6038EHgwGEBjI6XRqGAbU9vK75weyDLHRfTDGeDQawYH9Oq3NJgzWwVxfL4xGs/WfyQAPh0OAV6vVDXgdeKa2lF/9eCc1m010/2Q4xlKpVK/Xa7VatVqtVCrlchluUMEuz/N3mw/h28/Gx3T7e/6CeeHIqnRMBwFBPwFBSBM+HLysugAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Postman From Curl" title="Postman From Curl" src="/static/91d9ae8a226bcf932ddc277160b65b39/fea0e/PostmanFromCurl.png" srcset="/static/91d9ae8a226bcf932ddc277160b65b39/064a4/PostmanFromCurl.png 225w, /static/91d9ae8a226bcf932ddc277160b65b39/44727/PostmanFromCurl.png 450w, /static/91d9ae8a226bcf932ddc277160b65b39/fea0e/PostmanFromCurl.png 900w, /static/91d9ae8a226bcf932ddc277160b65b39/3d4e0/PostmanFromCurl.png 1237w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>It took me a while to find out how to export the request, it's hidden under the <code class="language-text">code</code> link. <span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/9e66e97eee027dccf3293f5bb332e76a/3d4e0/PostmanMain.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 68.39126919967664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7CAAAOwgEVKEqAAAAB3UlEQVQ4y31TTY/TMBDNb+YOWqltui0tEtJy48B/4ILECe2BTdOyEj+AA4hGSmk+2sR2EjtvZ5y4hBKI9DSeeTPPM+PWe/z0AV+De3wOAsIG4e4Lgu0WQdiDzhuOOT8M8UDYbnd47HPDnt/Q2bt/O8XHu+dYvFxhvVphRZhNp5hOJhbLWx93r5aY+z7mcx/+bIYJ8a+XS7xZLPDi5ga3zBHW6zW8JMuRZylMXaGqazRNg7IUOJ9OUKLE/76acqWUkFWNWinU4gxPUlElCihFBAUVIU0SJEmKwzHBr+MRSZoiz/MrnFCec/w8nPDs/RnvHjKI9ACvlKRMnVUVo7IdFkUBWRYoKEGQVRQv2aou18JOUqKgaeKcmkhzqOgHvMa0f4xhjEEcx1A0SqsboO14vogFmWe0FO+s4SoL9knQ2IK2L9RaY7/fI8syux/T89yVEMKKMvgCrrHC1nYa/xTkcQydh4K8Co47uE4vwmMdcjCKItvNMM77ZUHdX3It5nL/EmTLhSzAxTwaW/cYzncx9ocYFXRiQ7iueA3NFTfEqKA7D7/fe2Kuw0gaCfbBdlBoRi7hF+e91vQH2H2X+BbzjvXldS+CSpZ2hOvXGvoMN1JrNKJcIxO6++0NeN7hE0niJVtAAIMaAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Postman Main" title="Postman Main" src="/static/9e66e97eee027dccf3293f5bb332e76a/fea0e/PostmanMain.png" srcset="/static/9e66e97eee027dccf3293f5bb332e76a/064a4/PostmanMain.png 225w, /static/9e66e97eee027dccf3293f5bb332e76a/44727/PostmanMain.png 450w, /static/9e66e97eee027dccf3293f5bb332e76a/fea0e/PostmanMain.png 900w, /static/9e66e97eee027dccf3293f5bb332e76a/3d4e0/PostmanMain.png 1237w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>From there you can export the request into a wide variety of formats. <span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/9fe97ebc489345c509cff81eb866ad4d/3d4e0/PostmanExport.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 68.39126919967664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAB7ElEQVQoz4WS72vTQBjH8wf6xjSkk8b6ar4W0RdrM6fN5Wf9C8QKpv03FIW+cNqatWuhUGm7DmGwTdauSe6SS87nkgXZrPjhy8PdcV++zx2P8OXzh/63w6+9/mGv7w2G3nB4U7mOiwXXYHgM+j4YwIX+0VHP84Snu5Unj+SKojxUlJ1yWRTFksiRSqUdWSoV2/uiWJakB5Iky7JSqYCq1aqgIR1pmm2ZQKPR0DP291+odVWtA2qher22V6vtaRoyTbhtmDoSTMuyTAOKYRie512v1xGH0CRKkpiLRpSx6OwH/viWjD+9eefee/xy9zmYNcGwbMu2LcuGwNFohDEmBG+usb9JcMBwyAhmEWHEj8nVhobBe9dVDzSEdAvMltN0MiB8PB6HIQ5C/+qSnp2yzSrl/oClScoykiRpt9uGrr/mJvuuOYpijIOL8+jnkl2cp78u2XrN/CD1AxaEDBNuhh6bTe66Zc7b9n0f44gmLI4ZVC6aCU7ov82QDM7VakVpzLaRt/2fZPjudBuUUtd1EUL8xfbtN08mkziOCSGQsDUZ/J1OZ7u52+3OZrPpdDqfz5cZJwWnyxPYLRaLVqsFE3G37dwPc5bXHJSh6+iZimoHCMbJdv4AE2ZCA85fNDNu1o7zynB00ykOeM/Ab9uYTGjE7wRyAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Postman Export" title="Postman Export" src="/static/9fe97ebc489345c509cff81eb866ad4d/fea0e/PostmanExport.png" srcset="/static/9fe97ebc489345c509cff81eb866ad4d/064a4/PostmanExport.png 225w, /static/9fe97ebc489345c509cff81eb866ad4d/44727/PostmanExport.png 450w, /static/9fe97ebc489345c509cff81eb866ad4d/fea0e/PostmanExport.png 900w, /static/9fe97ebc489345c509cff81eb866ad4d/3d4e0/PostmanExport.png 1237w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>And there we have it, Chrome to cURL to Postman and back again.</p><![CDATA[Dynamically calling a Function in FSharp]]>https://daniellittle.dev/dynamically-calling-a-function-in-fsharphttps://daniellittle.dev/dynamically-calling-a-function-in-fsharpSat, 11 Feb 2017 06:16:03 GMT<p>Sometimes you just want to make a dynamic call.</p> <p>There is no equivalent for <code class="language-text">Func&lt;&gt;.DynamicInvoke</code> in <code class="language-text">FSharpFunc</code> so I guess we'll have to roll our own. </p> <p>In this post I'll go though how to build a function called <code class="language-text">dynamicInvoke</code> which you use like this:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let sayHello name = printfn &quot;Hello %s!&quot; name let objectResult = dynamicInvoke sayHello [&quot;Daniel&quot;] let typedResult = objectResult :&gt; string // typedResult = &quot;Hello Daniel!&quot;</code></pre></div> <p>The example above starts off with a normal FSharp function that takes a typed argument, in this case, a <code class="language-text">string</code> and returns a <code class="language-text">string</code>. Then <code class="language-text">dynamicInvoke</code> is used to call the function with a list of arguments which returns the result as an object.</p> <p>You could also use <code class="language-text">dynamicInvoke</code> on its own to build a function with the signature <code class="language-text">obj seq -&gt; obj</code>. Which I'd say is the functional equivalent of <code class="language-text">DynamicInvoke</code>, just what we're looking for!</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let dynamicFunction = dynamicInvoke sayHello</code></pre></div> <p>The actual signature of <code class="language-text">dynamicInvoke</code> therefore is as follows <code class="language-text">obj -&gt; obj seq -&gt; obj</code>. In other words, it takes the original function (as an object), an <code class="language-text">obj seq</code> for the arguments and returns an object, which is the result of the original function.</p> <h2>How it works</h2> <p>At its core, the solution is to use standard .NET reflection to dynamically invoke <a href="https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/core.fsharpfunc%5B%27t,%27u%5D-class-%5Bfsharp%5D?f=255&#x26;MSPPError=-2147217396"><code class="language-text">FSharpFunc&lt;&#39;T,&#39;U&gt;.Invoke : &#39;T -&gt; &#39;U</code></a>. The other tricky bit involves how functions work in FSharp.</p> <p>In FSharp, functions that take multiple parameters return a function that takes the rest of the parameters. Which itself is a function that takes a single parameter and does the same. All of these functions take a single parameter. So we could also say, there is no such thing as a function that takes multiple parameters! </p> <p>Let's have a look at a function with multiple parameters:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let sayHello name age = printfn &quot;Hello %s, you are %i years old!&quot; name</code></pre></div> <p>The type hierarchy of this <code class="language-text">sayHello</code> function will contain the following type:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">FSharpFunc&lt;string, FSharpFunc&lt;int, string&gt;&gt;</code></pre></div> <p>In order to dynamically invoke the function, each <code class="language-text">FSharpFunc</code> that makes up the function can be invoked recursively until a result is reached. And because <code class="language-text">FSharpFunc</code> is a standard .NET type we can get the <code class="language-text">MethodInfo</code> for <code class="language-text">Invoke</code> and dynamically invoke it!</p> <p>For each argument, the function is partially applied. The code below does exactly this, using reflection to get the <code class="language-text">MethodInfo</code> for the <code class="language-text">Invoke</code> method and calling <code class="language-text">Invoke</code> on it. Such invoke.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let partiallyApply anyFSharpFunc argument let funcType = anyFSharpFunc.GetType() // Guard: FSharpType.IsFunction funcType let invokeMethodInfo = funcType.GetMethods() |&gt; Seq.filter (fun x -&gt; x.Name = &quot;Invoke&quot;) |&gt; Seq.head methodInfo.Invoke(anyFSharpFunc, [| argument |])</code></pre></div> <p>Now, all it takes to call a function is to recursively partially apply it until we run out of arguments to apply. Add some error handling and we're done! The complete code is below and I'll also publish a NuGet package shortly.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">open System open FSharp.Reflection type InvokeResult = | Success of obj | ObjectWasNotAFunction of Type let dynamicFunction (fn:obj) (args:obj seq) = let rec dynamicFunctionInternal (next:obj) (args:obj list) : InvokeResult = match args.IsEmpty with | false -&gt; let fType = next.GetType() if FSharpType.IsFunction fType then let (head, tail) = (args.Head, args.Tail) let methodInfo = fType.GetMethods() |&gt; Seq.filter (fun x -&gt; x.Name = &quot;Invoke&quot; &amp;&amp; x.GetParameters().Length = 1) |&gt; Seq.head let partalResult = methodInfo.Invoke(next, [| head |]) dynamicFunctionInternal partalResult tail else ObjectWasNotAFunction fType | true -&gt; Success(next) dynamicFunctionInternal fn (args |&gt; List.ofSeq )</code></pre></div> <p>Now it's possible to dynamically call any FSharp function!</p> <p>A quick word on error handling. This function can fail if something other than a function is invoked. Sadly there's no <code class="language-text">IAmAFunction</code> marker interface. So the only option is to use a runtime check and return a <code class="language-text">ObjectWasNotAFunction</code> <code class="language-text">InvokeResult</code>.</p> <p>This is an explicit failure of this function and therefore an explicit result is returned. Exceptions caused by invoking the function, however, are exceptional, and never caught (except at the application boundary), so they pass right through.</p> <p>If you found this post useful, I'd love to hear about it. So leave a comment if you found this post interesting or if it helped you out! </p><![CDATA[Comparing MicroBus and MediatR]]>https://daniellittle.dev/comparing-microbus-and-mediatrhttps://daniellittle.dev/comparing-microbus-and-mediatrSat, 07 Jan 2017 02:09:43 GMT<p>Mediators are an excellent addition to the developer toolbox. Allowing you to define a pipeline that is decoupled from any particular framework. Having a pipeline makes it easy to deal with cross cutting concerns like security, transaction, validation and others. For these reasons and more using a Mediator has become quite a popular choice. They are also used to improve other aspects of an application in regards to structure and architecture. </p> <p>Recently there have been a few such Mediator libraries pop-up for .NET including MediatR, GreenPipes and MicroBus. I started MicroBus back in 2015 and have used it in a number of projects since. So I thought now would be great to talk a bit about MicroBus and what it does. In this post, I will be comparing MicroBus and MediatR, so that you can see the similarities and differences. </p> <p>But before I begin, I'd like to say; I think both MediatR and MicroBus are great solutions to these problems. I've made some different choices along the way, however, both these projects had similar origins (aka doing it numerous times before making a package), have similar goals and tackle similar problems.</p> <h2>Wire Up</h2> <p>I'll start with how to wire-up the Mediators, which involves firstly registering them to a dependency injection container.</p> <p>With MicroBus I wanted to ensure the experience was the same regardless of which container you prefer. It's syntax, is, therefore, a little more succinct than out of the box MediatR.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus autofacContainerBuilder.RegisterMicroBus(busBuilder);</code></pre></div> <p>MediatR takes the approach of zero dependencies and provides the following sample for setting up MediatR with Autofac.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MediatR var builder = new ContainerBuilder(); builder.RegisterSource(new ContravariantRegistrationSource()); builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly).AsImplementedInterfaces(); builder.RegisterAssemblyTypes(typeof(Ping).GetTypeInfo().Assembly).AsImplementedInterfaces(); builder.RegisterInstance(Console.Out).As&lt;TextWriter&gt;(); builder.Register&lt;SingleInstanceFactory&gt;(ctx =&gt; { var c = ctx.Resolve&lt;IComponentContext&gt;(); return t =&gt; c.Resolve(t); }); builder.Register&lt;MultiInstanceFactory&gt;(ctx =&gt; { var c = ctx.Resolve&lt;IComponentContext&gt;(); return t =&gt; (IEnumerable&lt;object&gt;)c.Resolve(typeof(IEnumerable&lt;&gt;).MakeGenericType(t)); });</code></pre></div> <p>However that's not entirely fair, the actual implementation for MicroBus is relatively similar under the covers. MicroBus also currently only provides an Autofac extension. Although you can set-up any other container manually. The Autofac implementation itself consists mainly of this file <a href="https://github.com/Lavinski/Enexure.MicroBus/blob/master/src/Enexure.MicroBus.Autofac/ContainerExtensions.cs">ContainerExtensions.cs</a> and uses a resolver and scope class similar to ASP.NET MVC instead of factories for resolving dependencies. If you'd like to request a particular container, then feel free to open a GitHub issue.</p> <p>MicroBus wire-up is slightly more complex in two places, validation, which ensured command and requests only have a single handler and Registrations which support singleton and transient registrations, which is useful for transparently doing complex registrations that can completely change how handlers work. MicroBus uses this to provide Saga support something I'll write more on in a later post.</p> <h2>Pipeline and Handler Registration</h2> <p>Next, we'll take a look at how to register handlers and how to create a pipeline.</p> <p>Again I wanted to ensure that registration for MicroBus was consistent across containers and that the concept of a pipeline was a first class citizen. There are two main types of handlers in MicroBus, Global/Delegating Handlers which execute for every message and Message handlers which sit at the end of the pipeline.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus var busBuilder = new BusBuilder() // Global Handlers run in order so these are explicitly registered .RegisterGlobalHandler&lt;LoggingHandler&gt;() .RegisterGlobalHandler&lt;SecurityHandler&gt;() .RegisterGlobalHandler&lt;ValidationHandler&gt;() .RegisterGlobalHandler&lt;TransactionHandler&gt;() // Scan an assembly to find all the handlers .RegisterHandlers(assembly);</code></pre></div> <p>Global handlers run in the order they are registered then Message Handlers are executed. The Delegating Handlers are also Task-based which uses <code class="language-text">async</code> in contrast to before and after methods. Again this is very similar to ASP.NET WebApi and ASP.NET Core, which use a similar approach.</p> <p>Another one of the goals I had in mind when building MicroBus was Safety. To help prevent you from doing the things you probably don't want to be doing anyway. MicroBus supports three message types, commands, events and queries. Each of these types have different semantics which are enforced through validation. Only a single command handler can be registered for a command. The same goes for queries. Events, however, can have multiple handlers (polymorphic handlers are also supported) but no return types.</p> <p>Registration via MediatR up until very recently (about two days ago) didn't provide any abstractions, so registrations were made directly via the container with decorators. Leaving the pipeline to the container removed a fair amount of complexity from MediatR and delegates it to the container. The trade-off here though is that the user may have to deal with the complexity instead.</p> <p>MediatR 3.0 now also provides support for pipelines which makes registration much easier for all containers.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MediatR builder.RegisterGeneric(typeof(IPipelineBehavior&lt;,&gt;)).As(typeof(LoggingBehaviour&lt;,&gt;)); builder.RegisterGeneric(typeof(IPipelineBehavior&lt;,&gt;)).As(typeof(SecurityBehaviour&lt;,&gt;)); builder.RegisterGeneric(typeof(IPipelineBehavior&lt;,&gt;)).As(typeof(ValidationBehaviour&lt;,&gt;)); builder.RegisterGeneric(typeof(IPipelineBehavior&lt;,&gt;)).As(typeof(TransactionBehaviour&lt;,&gt;));</code></pre></div> <h2>The API</h2> <p>The primary interface you use to send commands to MicroBus is the <code class="language-text">IMicroBus</code> interface.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus public interface IMicroBus { Task SendAsync(ICommand busCommand); Task PublishAsync(IEvent busEvent); Task&lt;TResult&gt; QueryAsync&lt;TQuery, TResult&gt;(IQuery&lt;TQuery, TResult&gt; query) where TQuery : IQuery&lt;TQuery, TResult&gt;; }</code></pre></div> <p>This interface is strongly typed and enforces that a given message type is used with the matching method. MicroBus also provides a secondary generic <code class="language-text">IMicroMediator</code> interface which can be used with untyped MessageHandlers, we'll look at these a bit later. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus public interface IMicroMediator { Task SendAsync(object message); Task PublishAsync(object message); Task&lt;TResult&gt; QueryAsync&lt;TResult&gt;(object message); }</code></pre></div> <p>With most choices in MicroBus, I've gone for the opinionated option to get better compile-time safety or better validation. This interface, however, offers much fewer guarantees. In some brownfield projects especially those which already followed a similar pattern but had messages that didn't use the MicroBus marker interfaces, this is extremely useful. </p> <p>The MediatR interface is very similar to the IMicroBus interface. It has the three primary methods for Commands, Request/Queries and Events but using different names. One nice feature here is the support for CancellationTokens. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MediatR public interface IMediator { Task&lt;TResponse&gt; Send&lt;TResponse&gt;(IRequest&lt;TResponse&gt; request, CancellationToken cancellationToken = default(CancellationToken)); Task Send(IRequest request, CancellationToken cancellationToken = default(CancellationToken)); Task Publish&lt;TNotification&gt;(TNotification notification, CancellationToken cancellationToken = default(CancellationToken)) where TNotification : INotification; }</code></pre></div> <p>These interfaces are probably the most similar part of the two libraries. It's also interesting to see that MediatR also took the type-safe route here. One thing I did find slightly confusing was that MediatR uses IRequest with no Response for its commands.</p> <h2>Message Handlers</h2> <p>So far we've covered how to register handlers, and how to send messages to them. Next up is how they are defined. In MicroBus there are three typed handler interfaces and one generic handler interface for the IMicroBus and IMicroMediator interfaces.</p> <p>The three typed interfaces are for each of the message types, commands, queries and events.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus ICommandHandler&lt;Command&gt; IQueryHandler&lt;Query, Result&gt; IEventHandler&lt;Event&gt;</code></pre></div> <p>Here is what a command handler would look like in MicroBus. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus class CommandHandler : ICommandHandler&lt;Command&gt; { public async Task Handle(Command command) { Console.WriteLine(&quot;Command handled!&quot;); } }</code></pre></div> <p>It's worth mentioning that EventHandlers support polymorphic dispatch so a <code class="language-text">IEventHandler&lt;AnimalEscaped&gt;</code> and <code class="language-text">IEventHandler&lt;LionEscaped&gt;</code> would fire if <code class="language-text">LionEscaped</code> inherits from <code class="language-text">AnimalEscaped</code> (MediatR also supports this). </p> <p>The generic handlers are also quite similar. However, in this case, there's only one interface because it's impossible to know what the message will be based on its type. If you're implementing a command or event, you would typically return Unit.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus class Handler : IMessageHandler&lt;Message, Unit&gt; { public async Task&lt;Unit&gt; Handle(Message message) { return Unit.Unit; } }</code></pre></div> <p>MicroBus is also split up into four main parts.</p> <ul> <li>The core package</li> <li>Infrastructure contracts, which include <code class="language-text">IMicroBus</code> and the <code class="language-text">IHandler</code> interfaces</li> <li>Message contracts, which includes <code class="language-text">ICommand</code>, <code class="language-text">IQuery</code>, <code class="language-text">IEvent</code> and <code class="language-text">IMessage</code></li> <li>Dependency Injection Extensions</li> </ul> <p>Splitting up MicroBus into multiple packages is a nice feature that lets you selectively include the parts of MicroBus you depend on. Most commonly you see Message Contracts defined in a library that depends only on <code class="language-text">MicroBus.MessageContracts</code>.</p> <p>MediatR's Handler are quite similar the main distinction being that MediatR provides both async and synchronous versions of each interface. The example below shows an async command handler.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MediatR class CommandHandler : IAsyncRequestHandler&lt;Command&gt; { public async Task Handle(Command message) { Console.WriteLine(&quot;Command handled!&quot;); } }</code></pre></div> <p>Overall you can see a lot of similarities with a few defining features.</p> <h2>Delegating Handlers</h2> <p>We've already talked a bit about Pipeline and Handler registration and this one of the most useful features of a Mediator. MicroBus has first class support for pipelines and makes writing cross-cutting code effortless.</p> <p>To start, you implement IDelegatingHandler which has a similarly looking handle method. One of the nice things about IDelegatingHandler is that don't need a constructor, and if you need dependencies, you don't need to worry about where the "inner" handler goes. Instead, the next handler is passed along through <code class="language-text">Handle</code> keeping the scope of the variable as small as possible. Delegating Handlers are also registered globally which means that you'll only need to register them once and they'll run for every type of message.</p> <p>The example below shows how you could create a global handler which wraps every message handler in a database transaction. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MiroBus public class DatabaseTransactionHandler : IDelegatingHandler { public async Task&lt;IReadOnlyCollection&lt;object&gt;&gt; Handle(INextHandler next, object message) { using (var transaction = database.NewTransaction()) { return await next.Handle(message); transaction.Commit(); } } }</code></pre></div> <p>Delegating Handlers also make use of async and await which means you can make using of <code class="language-text">using</code> and <code class="language-text">try</code> as opposed to having a before and after method.</p> <p>MediatR didn't have a global pipeline until recently. Before which made registering cross-cutting code for every handlers somewhat tedious. The latest version 3.0 puts it on par in this respect and the handlers which are called Behaviours are again quite similar. The snippet below shows an example of a behaviour in MediatR.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MediatR public class MyBehavior&lt;TRequest, TResponse&gt; : IPipelineBehavior&lt;TRequest, TResponse&gt; { public async Task&lt;TResponse&gt; Handle(TRequest request, RequestHandlerDelegate&lt;TResponse&gt; next) { //Before var response = await next(); // After return response; } }</code></pre></div> <h2>What's next</h2> <p>Mediators are a great addition to the developer toolbox letting you deal with cross cutting concerns without tying your application to a UI, web or service framework. We've looked at wire-up, declaring and registering handlers, usage, and pipelines while comparing MicroBus and MediatR. </p> <p>I hope I've been able to show you a bit about MicroBus and what makes it different. So if you're used a mediator before (or if you haven't) I'd recommend trying MicroBus out for yourself, I'm always looking for feedback and suggestions. You can get the get the bits on github here <a href="https://github.com/Lavinski/Enexure.MicroBus">Enexure.MicroBus</a>.</p><![CDATA[Event Sourcing: What properties should Domain Events have?]]>https://daniellittle.dev/event-sourcing-what-properties-should-domain-events-havehttps://daniellittle.dev/event-sourcing-what-properties-should-domain-events-haveMon, 31 Oct 2016 08:46:13 GMT<h2>What I learned since last time</h2> <p>A while ago I wrote about <a href="/generating-read-models-with-event-sourcing/">Generating Read Models with Event Sourcing</a> where I suggest adding derived properties to the persisted domain events also known as Enriched Events. Since writing that post, I have been using this approach. However, over time I found that this was not the solution I was hoping for. In short enriching events also has some problems and recently I have switched over to using only delta style events for persisted events. In this article, I will cover the problems that come from enriching events and suggest a (better) alternative solution to the question "What properties should Events have?".</p> <h2>What problem is Event Enriching meant to solve?</h2> <p>When a Domain Event is raised, it is published to several interested handlers. The first of these is the Apply Method whose job it is to update the state of the Aggregate. Because the Aggregate is the primary source of an event, it has access to all the updated state. The problem stems from needing to pass some of this data to the other interested handlers.</p> <p>If we look at a bank account, the event would be a transaction resulting in a changed account balance. The other interested handlers could be Read Model Generators, other event handlers or even other services. Some of these are almost certainly interested in the current balance of an account. In this case, Enriching the <code class="language-text">Transaction Added</code> event would involve adding the Current Balance to the events. Enriching solved the issue of easily providing information to all the interested handlers. More importantly, though, it ensured that there is only one place where derived state is calculated.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 468px;" > <a class="gatsby-resp-image-link" href="/static/bbccbcce497d6b6be0967e8039604999/bb106/Before.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.41025641025641%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABoElEQVQoz2VSQU/bMBTOnx0XEBIgBFKvTBrjgDjvMu3Aph1hSJvGhdNU1BYqioRQYSVQ0sSxn+0kdpo4Ni+tKAWsJ/k9P32f3/fZnrVuFlVlnXN5PqaUJUkqZcK5EELyepPGVNjFJI4pA14UpfcejKdRRBgDKSQwAOCEEADxDBZBEIyCkVLaQwDGK4qaoV7GOl6656o+t5NCVU4jj3WenTUna74sKnubFPPdmte6WBuWGyw9VIgy0jTFMTD0uDwZir++OL4XR3f8cMB/+/yPz38NoBMm0zFYXvFxLcFD2MNwGDwGhNAYtSXqc49uX8LHC9Y4j1fbZLlFVlpk4ZR8uaLO1hg6A8/mnO5ZXuz24u0e+9SjO5escUbWO2SzgxTR12s6VfUCfmOYqeyDUHdc+VzdguqS1J/kA8hImk9venWztS8+zRtWIlFWvrcT3oyNtnEhE5nqvDj4z7/34ecN/OjDfp9hjsm3a3YylIWpjLWhNjAP1lr7vo+vD0m21SUb7ajRidZa4WIzXGqGy83ww79w7yIayHGgzH1WavwD1j0Bj+ZnoLDmuAEAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Diagram, Derived properties are calculated in the behaviour" title="Diagram, Derived properties are calculated in the behaviour" src="/static/bbccbcce497d6b6be0967e8039604999/bb106/Before.png" srcset="/static/bbccbcce497d6b6be0967e8039604999/064a4/Before.png 225w, /static/bbccbcce497d6b6be0967e8039604999/44727/Before.png 450w, /static/bbccbcce497d6b6be0967e8039604999/bb106/Before.png 468w" sizes="(max-width: 468px) 100vw, 468px" loading="lazy" /> </a> </span></p> <p>Sending derived properties to other handlers and services is an important problem that Enriching Events was able to resolve. So it is equally important to ensure that the new solution solves this problem as well. But first, we'll look into what the problems with Enriching Events are.</p> <p>As a side note, there are still cases where other handlers for an event keep track of their own running totals or tallies (derived state). However, this is usually because it is data that the Aggregate does not care about and does not already calculate or store. In which case, no logic is being duplicated anyway.</p> <h2>Ok so what’s wrong with Enriching Events</h2> <p>There are a few problems that come from enriching Events which you can avoid by using delta only Events.</p> <h3>Redundant Data</h3> <p>One of the core ideas in event sourcing is storing a list of all the changes that have happened to an Aggregate. By playing back these events you can determine the state of the Aggregate at a point in time. Because the system is deterministic, you will arrive at exactly the same state every time.</p> <p>For a bank account given all the deposits and withdrawals ever made can determine what the current balance is. If you were to store the current balance along with every transaction, you would have to store much more data for little benefit. In fact, it stops us from using other nice features of Event Sourcing.</p> <h3>You can’t do Replay Testing</h3> <p>Replay testing allows you to use all your current production data as test data for your application. The derived state will be re-calculated using the events as they are replayed. Comparing the results of different versions can then be used to spot any divergences and fix them before they make it to production.</p> <p>The one downside to this is that we must do slightly more work when replaying events. However, processing events in memory is extremely quick and loading the data is usually the bottleneck anyway. Lots of events can still slow things down, but you can use Snapshotting to win back even more performance.</p> <h3>No Concurrency for Aggregates</h3> <p>Concurrency is probably the biggest issue with Enriched Events. Looking at the <code class="language-text">Transaction Added</code> event for a bank account. If the balance total is part of the event, then it forces you to process all behaviours in serial. This is what it looks like if we add the current balance to the event.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Event Amount Total TransactionAdded 50 50 TransactionAdded -20 30 TransactionAdded 10 40 Total 40</code></pre></div> <p>But what happens when both the second and third event occurs at the same time.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Event Amount Total TransactionAdded 50 50 TransactionAdded! -20 30 TransactionAdded! 10 60 Total 60 // Should be 40</code></pre></div> <p>If we do not handle concurrency at all, the total from the first event will get overridden by the total from the second event. This would be terrible! Optimistic Concurrency is the next level and a good default, in this scenario, a concurrency exception is thrown instead. This works well for cases where you cannot do work in parallel.</p> <p>However, if the model does not need the totals to process transactions (at least not in a completely consistent manner), then the order does not matter anymore. You will still end up with 40 regardless of the order you process the behaviours in. So, we can be a bit clever and for transactions that do not conflict, try to insert it again automatically. Speeding up the time it takes to process events.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Event Amount TransactionAdded 50 TransactionAdded -20 TransactionAdded 10 Total 40</code></pre></div> <p>Even if behaviours cannot be processed in parallel such if we needed the balance to be completely consistent inside the aggregate, we can derive the totals so we can still avoid persisting them.</p> <h3>Unfocused Events</h3> <p>Enriched Events contain all the derived properties as well as the deltas which can leave you with quite large events. I have found that in most cases individual handlers will only care about one or the other, deltas or totals. For our bank account example if we want to publish the current balance we could have two events instead of one giant event. The first event would still be <code class="language-text">Transaction Added</code> and the second would be <code class="language-text">Balance Changed</code>. If you were updating a SQL Read Model you would probably have two tables (transaction and balances) and an event handler for each table, so two events align perfectly.</p> <h2>Multiple events to prevent duplicating logic</h2> <p>Using multiple events is also how we will deal with sending derivable state to other handlers. The second event, which includes the derived state, won't be persisted at all. I'll call this a transient event. The Persisted Domain Events that the behaviour creates are created as normal. However, Transient events need to be handled a little differently because they need the internal state from after the <code class="language-text">Apply</code> method is called. Adding a Handle method for behaviours that executes after the Apply method gives us a chance to let the world know about derived or calculated data.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 468px;" > <a class="gatsby-resp-image-link" href="/static/1d3fc22890389a84327493ec52eb08e0/bb106/DomainEvents-1.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.41880341880342%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACUklEQVQ4y4VU2W7TQBT1h/LAKwioyhPQFiJU+owqvgUBRSpla9SSNG1KhYQUmsTOxHbG8b7bhzuTpaljxJVOrudOfHLuFqUsgQWKopQ+TTPwCYfreXBdD9OpDdt2CDY9TxHHKYRFUQzDMMH5FEEQyneVOsIsy+mLBkxzAsdxYHELljWlsyljcTIjjOMYmqqBMUakXMYUQbIOLI344WZAfhNCMf/xxb0/vxQxBRUrS6xZz03XLuSRPsK0gOrP7oUQJQgCRGFE8hMJkW7b8PBZc/B95Ep/MLSl/0I4IjSZiySbyYqyEizMpFSpsN/vYzgYQtcNjNgYvudj/4pjt2thr8vx9GyCxy0Tj04NbBAenJrYahtwo2ROWIAFK4TVVIXCN1cTvLyw8IoI9y4tIufY7kzwjMj/S1jXlF/cR0v3cE6pdwjHlKLw4tymeNf0kBKRIJEpVwlX613XFBbm68ESN4SrNZzNXTZrCs1XnhdS3aFKDaGmHGkuPg4dfNJEg1zpj281pYBWrWEYhuj1/uD6ug+PNmO3Y+Bec4yNEx33yd/9xpa485XhYXNEJfCl8gGNjCEyqKa83BZSKBS8H9hS2QHhbd+W5w8DB+/IH6oO/CRDSu+meXlr05TFwxI1NRxHBeqsbm2VoljfgGmUQg8olTl+2zHGfgIzTCU4IZ8TLIQsFXo0yOpQhUpLLmootmb/0sCTH2M8b+vYITTOyLfG2CJsnjA0WgzefA6rJVNEV8XfUEhEIfmMOv36J21Ix8KLC46dc07ekn6bsNmaoEFD/i/Cv6P8uuNWxlyGAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Diagram" title="Diagram" src="/static/1d3fc22890389a84327493ec52eb08e0/bb106/DomainEvents-1.png" srcset="/static/1d3fc22890389a84327493ec52eb08e0/064a4/DomainEvents-1.png 225w, /static/1d3fc22890389a84327493ec52eb08e0/44727/DomainEvents-1.png 450w, /static/1d3fc22890389a84327493ec52eb08e0/bb106/DomainEvents-1.png 468w" sizes="(max-width: 468px) 100vw, 468px" loading="lazy" /> </a> </span></p> <p>Now, when a behaviour is run the persisted event is raised, Apply updates the state, and the Handle method will run. Giving you a place to raise transient events as well. After the behaviour is finished all these events are then published.</p> <p>Rebuilding the Read Model will also require the transient events to be regenerated. However, we can completely skip the Handle method when Hydrating an Aggregate from an event stream.</p> <h2>Persisted Domain Events</h2> <p>Now we have small delta only events in our event store, the door is open to leveraging the real power of Event Sourcing. It is much easier to keep other handlers informed and avoid duplicate code. Events are more focused, smaller and easier to work with. There are more options for dealing with concurrency. And you can make use of Replay Testing to eliminate a broad range of regressions.</p> <p>So, what properties should Events have? Persisted events should only store what they need, typically only the change or the delta. The rest can be derived from there.</p> <hr> <p>I am currently building a more Functional Event Sourcing library for C# called <a href="https://github.com/Lavinski/Eventual">Eventual</a>. It's my playground for Event Sourcing ideas and a good place to dig into some real code. It is, however, an early alpha and still a work in progress, so it doesn't cover everything in this post. Nevertheless, I still recommend you take a look if you want a peek under the covers.</p><![CDATA[Links to Get Started with React and Redux]]>https://daniellittle.dev/links-to-get-started-with-react-and-reduxhttps://daniellittle.dev/links-to-get-started-with-react-and-reduxWed, 12 Oct 2016 22:38:46 GMT<p>Getting started to React and want to get right to it? These are the links you're looking for.</p> <h3>What you need!</h3> <p>First up you’ll need Node: <a href="https://nodejs.org.au/">https://nodejs.org.au/</a></p> <p>You can get the React tooling here: <a href="https://github.com/facebookincubator/create-react-app">https://github.com/facebookincubator/create-react-app</a></p> <p>Once you have React you’ll want Redux: <a href="https://github.com/reactjs/react-redux">https://github.com/reactjs/react-redux</a></p> <p>That’s all you need to get started!</p> <h3>Browser Extensions</h3> <p>React Developer Tools, great for debugging state: <a href="https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en">https://chrome.google.com/webstore/detail/react-developer-tools</a></p> <p>Redux Developer Tools, amazing for debugging state and time travel debugging: <a href="https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en">https://chrome.google.com/webstore/detail/redux-devtools</a></p> <h3>Extra Resources</h3> <p>The how and why of React apps: <a href="https://css-tricks.com/learning-react-redux/">https://css-tricks.com/learning-react-redux/</a></p> <p>A random super simple example Redux app: <a href="https://github.com/tstringer/create-react-app-with-redux">https://github.com/tstringer/create-react-app-with-redux</a></p> <h3>Extra packages for better redux apps</h3> <p>If you need to make ajax calls this is the best was to do it: <a href="https://github.com/yelouafi/redux-saga">https://github.com/yelouafi/redux-saga</a></p> <p>For caching updates to speed things up: <a href="https://github.com/reactjs/reselect">https://github.com/reactjs/reselect</a></p> <p>Remove magic strings in actions and reducers: <a href="https://github.com/pauldijou/redux-act">https://github.com/pauldijou/redux-act</a></p> <p>Happy coding! :)</p><![CDATA[There is always time to write clean code]]>https://daniellittle.dev/there-is-always-time-to-write-clean-codehttps://daniellittle.dev/there-is-always-time-to-write-clean-codeSun, 22 May 2016 00:40:02 GMT<p>The number one most important thing you can do in software development. Always leave the code base cleaner than when you found it. Always aim to improve things.</p> <p>I recently stumbled on a <a href="https://www.thebesttechpodcastintheworld.com/2016/05/21/episode-001/">fantastic podcast</a> by <a href="https://twitter.com/sitapati">Joshua Wulf</a> featuring <a href="https://twitter.com/DamianM">Damian Maclennan</a> who brilliantly described why this is so important.</p> <blockquote> <p>If you see a professional chef vs. a home cook, they enjoy cooking, but they end up with a mess all over the kitchen bench, but if you watch a professional work they'll chop something and then they'll wipe the board down, do something else and clean up a little bit. All along the way they're cleaning up. So they never get this massive build up of crap. Because once you've got that build up of crap you can't move. You end up with this tiny five by five centimeter square of space and you need to chop an onion and all of a sudden onion is going everywhere. That's what software development can be like, that's what code bases get like. You need to clean as you go.</p> </blockquote> <blockquote> <p>You need to always take that professional mindset. A lot of companies think there's no time to do that. You just need to smash out features, and then you get to the point where people go to their manager and say we've got all this technical debt we need to stop what we're doing and fix our technical debt. And the managers kind of hit the roof over that. We're under all this pressure. I've heard people give these excuses; there's never any time to do it right. But if you go into a hospital they're generally fairly slammed for time as well but you would never see a surgeon say "you know I really should wash my hands but I'm kind of busy, there's no time". They just do it. It's part of their professional ethics to do it. To use hygiene and do things right. And again you'll get fired as a chef if you're not fast enough because you don't clean as you go. But in software it's kind of this top down beat people with a stick approach telling them to go faster and then you wondering why you end up with a mess.</p> </blockquote> <p>Good software development teams clean as they go and the developers understand their professional responsibilities. You have to keep on eye on the future, on the impacts your decisions today will have. And it doesn't have to be at the expense of the short term. In fact, the future is often closer that it appears. Cleaning up as you go and doing things right can help you as soon as tomorrow. Now don't get me wrong, these aren't rules that apply to all code, we still have throwaways and prototypes. There are still trade-offs to make. But the baseline is set. If you're not cleaning as you go, it's slowing you down.</p><![CDATA[Announcing MicroBus 3]]>https://daniellittle.dev/announcing-microbus-3https://daniellittle.dev/announcing-microbus-3Wed, 09 Mar 2016 20:47:00 GMT<p>Awesome! MicroBus 3, what does that mean? Well, I've been using Semver (mostly, sometimes a little Ferver creeps in) for my package versions so it means in this release there's a few breaking changes. Now, first off, this is a much bigger update than 2.0 was and redefines a few of the MicroBus concepts.</p> <p>There are three main changes, firstly the Registration API has been reworked, global handlers have been smoothed out and there's a new <code class="language-text">IMicroMediator</code> interface (useful for sending any type as a message). But before I get into the details first here's a little bit of background.</p> <h2>The Story So Far</h2> <p>MicroBus has been a fantastic project to work on. I've been lucky enough to be able to use it quite substantially in my workplace. However, some things didn't turn out quite the way I expected them to. So it was time for a few changes.</p> <p>Since the beginning, MicroBus has always had the concept of a pipeline which contains two types of handlers. The first was Message Handlers that resided at the end of the pipeline which do the real work for a given message. The second type of handlers were Pipeline Handlers which could be used to intercept a message as it travelled down the pipeline.</p> <p>In the first version of MicroBus, the Pipeline Handlers are were explicitly added to the message handlers when registering them. However, even though you assigned the Pipeline Handlers individually, they behaved as if they were global. You could only ever have one set of Pipeline handlers for any one message, even if there were multiple different Message Handlers. It had to be the same instance of the Pipeline. </p> <p>In version 2 support for having a global pipeline was added. However, these handlers were restricted to only running once, so they wouldn't run a second time if you sent messages from inside message handlers. Which was super useful, but slightly confusing with regards so naming.</p> <h2>What's Changed</h2> <p>So it was time to clean up a few things. Version 3 started with wanting a bit more flexibility out of MicroBus. If your message contracts implemented <code class="language-text">ICommand</code>, <code class="language-text">IEvent</code> or <code class="language-text">IQuery</code> then everything was fine. However, there were a few cases, such as handling existing messages that didn't use these interfaces, where handlers needed to support any type of object.</p> <h3>IMicroMediator interface</h3> <p>This new interface has the same three methods (send, publish, query) as <code class="language-text">IMicroBus</code> except that messages can be any .NET <code class="language-text">object</code>. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public interface IMicroMediator { Task SendAsync(object message); Task PublishAsync(object message); Task&lt;TResult&gt; QueryAsync&lt;TResult&gt;(object message); }</code></pre></div> <p>To handle messages that don't implement our interfaces, a new handler <code class="language-text">IMessageHandler</code> interface has been added. The <code class="language-text">Handle</code> method of this interface takes a message of any type and returns an <code class="language-text">object</code>.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">class Handler : IMessageHandler&lt;Message, Unit&gt; { public async Task&lt;Unit&gt; Handle(Message message) { return Unit.Unit; } }</code></pre></div> <p>Traditional MicroBus message types can also be sent using the <code class="language-text">IMicroMediator</code> interface and can be handled by either the type safe or generic message handler interfaces.</p> <h3>Registration API</h3> <p>The next big change was the Registration API, there are two main changes here. Firstly when registering MicroBus to the Container Builder, instead of having to register everything inside a lambda, you can now pass in a <code class="language-text">BusBuilder</code> like so.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var busBuilder = new BusBuilder(); containerBuilder.RegisterMicroBus(busBuilder);</code></pre></div> <p>The second change to the Registration API is to the handler registration methods themselves. Previously the registration code looked like this.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">busBuilder .RegisterCommand&lt;TestCommand&gt;().To&lt;TestCommandHandler&gt;() .RegisterCommand&lt;TestEvent&gt;().To&lt;TestEventHandler&gt;();</code></pre></div> <p>The main reason the API was originally designed this way was to make it easier to register events.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">busBuilder .RegisterEvent&lt;Event&gt;().To(x =&gt; { x.Handler&lt;EventHandler&gt;(); x.Handler&lt;EventHandler2&gt;(); });</code></pre></div> <p>In this version of the API you only have to specify the message type once when registering multiple handlers. However, this required quite a lot of code for not much benefit, especially when most of the time you could just use assembly scanning registration methods instead.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">.RegisterHandlers(x =&gt; x.FullName.Contains(&quot;BusMessageTests&quot;), assembly);</code></pre></div> <p>The explicit handler registration API is now much more flat, and combines the <code class="language-text">Register</code> and <code class="language-text">To</code> methods into a single method in <code class="language-text">BusBuilder</code>.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">busBuilder .RegisterQueryHandler&lt;IsItTimeToGetOutOfBedQuery, Result, IsItTimeToGetOutOfBedQueryHandler&gt;() .RegisterQueryHandler&lt;BreakfastEvent, MakeBaconHandler&gt;() .RegisterQueryHandler&lt;BreakfastEvent, EventHandler&gt;()</code></pre></div> <h3>Global Handlers</h3> <p>The last big change is Global handlers. I talked about the problems with the way handlers previously worked. Mainly that pipeline Handlers were Global handlers in disguise except individually registered. In v3 these handlers have been pulled out of the individual registrations and replaced with real global handlers, that are globally registered. These handlers will run for every message sent over MicroBus. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">busBuilder .RegisterGlobalHandler&lt;InnerHandler&gt;()</code></pre></div> <p>Global handlers use the new <code class="language-text">IDelegatingHandler</code> interface which has one main difference to the old <code class="language-text">IPipelineHandler</code> interface mainly the use of <code class="language-text">INextHandler</code> instead of a <code class="language-text">Func</code> to invoke the next handler in the pipeline.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">class DoNothingHandler : IDelegatingHandler { public async Task&lt;object&gt; Handle(INextHandler next, object message) { return await next.Handle(message); } }</code></pre></div> <p>Overall global handlers are now much more consistent and much easier to use.</p> <p>However, this means the global handlers now run all the time, for every message. Needing handlers that know if they're at the Top Level of the call stack is still something I really wanted. So I've brought it back as dependency you can use to tell if it's an outer Handler or not.</p> <p>Adding <code class="language-text">IOuterPipelineDetector</code> to the constructor of a handler will provide an instance via Dependency Injection. The <code class="language-text">IOuterPipelineDetector</code> interface has a single property called <code class="language-text">IsOuterPipeline</code> which you can use to prevent a handler running a second time if the MicroBus pipeline runs inside an earlier instance of the pipeline.</p> <h2>Conclusion</h2> <p>It's been quite a bit release, with a few new features that will make MicroBus more powerful and easier to use. The new <code class="language-text">IMicroMediator</code> makes it easier to work with any message types, registration is simplified and global handlers are easier to build. </p> <p>So there you have it, all the changes in MicroBus 3! Make sure you try it out the new version. Of if you're installing for the first time use the command below. I'm also always on the lookout for feedback so leave a suggestions or issues on the GitHub page. Happy messaging!</p> <blockquote> <p>PM> Install-Package <a href="https://www.nuget.org/packages/Enexure.MicroBus.Autofac/">Enexure.MicroBus.Autofac</a></p> </blockquote><![CDATA[Porting MicroBus to DotNetCore]]>https://daniellittle.dev/porting-microbus-to-dotnetcorehttps://daniellittle.dev/porting-microbus-to-dotnetcoreSat, 30 Jan 2016 13:28:04 GMT<p>When the new .net core reached RC it looked like the perfect time to start to port some of the <a href="https://www.nuget.org/profiles/lavinski">Nuget packages</a> I've made starting with <a href="https://github.com/Lavinski/Enexure.MicroBus">MicroBus</a>. I've been watching most of the <a href="https://live.asp.net/">aspnet standups</a> so I've always been relatively familiar with what was going on, but there were still a few challenges along the way. I usually like to have everything figured out before I write about it, but for this post, I want to give a good picture of the experience as I found it.</p> <p>I started out using <a href="https://blog.marcgravell.com/2015/11/the-road-to-dnx-part-1.html">The Road to DNX</a> by Marc Gravell as a guide, which was great for figuring out exactly where to start.</p> <h2>Porting the project</h2> <p>He starts off moving all the old framework specific csproj files so he can build the project the old way as well as with dnx. I ended by just deleting these as I probably won't be using them again even though it's still an RC. So my first step was creating the project.json files, after that you can add them to the solution and Visual Studio will create some xproj files for you.</p> <p>I almost missed the super important part where the blog explains how to include them.</p> <blockquote> <p>IMPORTANT: as soon as you add a project.json to a sln you get a second file per project.json for free: {YourProject}.xproj; these should be included in source control.</p> </blockquote> <p>It breaks the flow a little bit to point it out as an important note but in doing so I guess I missed it on my first read through.</p> <p>The next part was getting the project building. One of the first things I discovered was that dnx was not just a runtime it's also a build system. And it supports targeting multiple frameworks in the one project file. I wanted to compile my project for both <code class="language-text">.net 4.5.1</code> and the new portable <code class="language-text">dotnet</code> targets. This turned out alright, but there was a lot of digging to figure out exactly which monikers I needed, <a href="https://stackoverflow.com/questions/31834593/target-framework-dnx451-or-net451-in-class-library-projects">and the name changes didn't help</a>.</p> <p>One of the biggest changes I had to make was moving to the new reflection API. I'd used the new API before, but I'm sure I ran into every issue again. The two main things to be aware of here is most of the stuff has moved to <code class="language-text">TypeInfo</code> and methods like <code class="language-text">GetInterfaces()</code> are now properties like <code class="language-text">ImplementedInterfaces</code>. Google didn't help as much here as I expected which probably means it's still a part of .net that is still rarely used.</p> <h2>Getting the Tests working</h2> <p>For the tests, the first thing I tried to do was leave them exactly as they were (as .net 4.5.1 tests) and use a test runner executable just like before. However, it quickly became apparent that this wouldn't work well. When I build each project with dnx I would get the .net451 dlls I needed however the output directories only contain the artifacts for that project. Unlike the previous build system which would also copy all the dependencies. I'm still not sure how it discovers project dependencies, but I'm guessing it's related to the projects being siblings on disk.</p> <p>I then ported my tests to XUnit so I could use the commands. The IDE lets you then select which commands you want to run. However, you have to have that project selected as the startup project to see it's options. Running the tests this way will still run the tests via the console.</p> <h2>Setting up the Build Server (AppVeyor)</h2> <p>I've been committing my packages to source control recently. The idea of super-deterministic builds is a nice idea. Plus on a build server like AppVeyor restoring packages for each build makes the whole process take much longer than just a git pull.</p> <p>I tried a few things to get this working first committing the packages folder which doesn't seem to contain all the dependencies. Then I looked into committing the lock files as well. I was having issues just getting the project to build on the server. So after a few attempts, I abandoned the approach in favor of just getting it working first.</p> <p>I had a few issues getting package restore working. Some project dependencies and package dependencies would just fail with "Unable to resolve dependency". At this point, I was trying to figure out if dnx had the equivalent of the solution file. It does have the concept of <code class="language-text">global.json</code> but not 100% clear on all the cases it gets used for. I did find that calling dnu restore with the solution path resoved my dependency resolving issue <code class="language-text">dnu restore $solutionDir</code>. I remember reading somewhere it would search child directories for projects, possibly using the <code class="language-text">global.json</code> to guide the search.</p> <p>All this was using the rc1 clr version of the runtime. Initially, it was hard to know what version of the clr I should be using. I actually started out trying to use coreclr for everything, but that can't build .net451. I then switched over to using the clr version and was able to get the project building. However, once I got to the tests, they would then fail. The tests are using <code class="language-text">dnxcore50</code>, and you can only run them using the new coreclr. So what you have to do is build the project with the <code class="language-text">clr</code> then use <code class="language-text">dnvm</code> and switch over to <code class="language-text">coreclr</code> to run the tests.</p> <p>The last things to note is that restore and build are <a href="https://ci.appveyor.com/project/Daniel45729/enexure-microbus/build/93">incredibly verbose</a>.</p> <h2>Conclusion</h2> <p>Eventually, I got everything working, packages build with <code class="language-text">dnx pack</code> are pushed to NuGet with the extra support for dotnetcore!</p> <p>Looking back, I'm not sure if I would have waited until the new dot net cli is ready. There's still a lot of changes happening, and some things could definitely be smoother. It was great to finally get hands on with the new tools, though. Visual studio hid a few things that quickly become apparent when trying to get a project building on a build server. Overall though it feels like a good start although it still feels beta-ish in a few places.</p> <p>Now that MicroBus is building again it's time to start work on the next release.</p><![CDATA[Querying AD Groups with PowerShell]]>https://daniellittle.dev/querying-ad-groups-with-powershellhttps://daniellittle.dev/querying-ad-groups-with-powershellThu, 22 Oct 2015 02:33:15 GMT<p>Getting the list of the AD groups if nice and easy in PowerShell. All the CmdLets are located in the <code class="language-text">ActiveDirectory</code> module which you might not have installed on your system.</p> <p>To install the module you'll need these Windows features</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Add-WindowsFeature RSAT-AD-PowerShell, RSAT-AD-AdminCenter</code></pre></div> <p>Then you can import the module</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Import-Module ActiveDirectory</code></pre></div> <p>Then query the user you want to see the groups for. This command can also list the groups for other groups in case of inheritance.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Get-ADPrincipalGroupMembership &quot;username&quot; | select name</code></pre></div><![CDATA[Building a MicroBus application]]>https://daniellittle.dev/building-a-microbus-applicationhttps://daniellittle.dev/building-a-microbus-applicationSat, 19 Sep 2015 05:31:08 GMT<p>I often like to think of software architecture as the art of structuring software. It's goal being to meet requirements while at the same time being resistant to falling into the state most commonly referred to as a Big Ball of Mud. To fight back against this, applications can use a well-defined architecture along with consistency and readability to ensure they don't become a sprawling, duct-tape-and-baling-wire, spaghetti code jungle. Instead, applications can be structured in such a way as to reduce unnecessary coupling between components. And have a strong foundation that provides consistency, structure and an ideology of the application.</p> <h2>What is MicroBus</h2> <p>MicroBus is a small library designed to help structure applications using the concepts of the Message Bus and Mediator patterns. The mediator pattern focuses on reducing coupling by communicating through a mediator, and the bus depicts the style of communication. These two aspects enable the application to be constructed as a series of pipelines each responsible for its own vertical of functionality.</p> <h2>Sending Messages</h2> <p>MicroBus is centered around sending messages. As an example of what this looks like, here is an example of sending and processing a command.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">await bus.Send(new AddItemToCartCommand(cartId, itemId));</code></pre></div> <p>The command, in this case, is adding an item to some shopping cart. The message itself is a data only object that implements <code class="language-text">ICommand</code>. MicroBus also supports events and queries as first class citizens and enforces their semantics though type safety where possible. For instance, events are the only message types that can have multiple handlers registered to them, and queries are the only message types that can return data. The methods to send events and queries are also slightly different to enforce the notion that each has an explicit purpose.</p> <p>To publish an event to all it's handlers the <code class="language-text">Publish</code> method is used, the event must implement the <code class="language-text">IEvent</code> interface.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">await bus.Publish(new Event(...));</code></pre></div> <p>Queries also have their own method that returns the result for the given query. Queries must implement <code class="language-text">IQuery&lt;TQuery, TResult&gt;</code> where TQuery is itself, and TResult is the result. The Result must also implement <code class="language-text">IResult</code>. This enforces the notion that queries must have a result and also enables type inference to work seamlessly for calls to <code class="language-text">bus.Query()</code>.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var result = await bus.Query(new Query(...));</code></pre></div> <p>In this case, the type of <code class="language-text">result</code> would be inferred from the query type.</p> <h2>Handling messages</h2> <p>Once the message has been put on the bus, then the handlers take over. More generally, handlers contain core logic of the application. Above we sent a <code class="language-text">AddItemToCartCommand</code> command onto the bus so now to handle the command we need a command handler. This is a class that implements the interface <code class="language-text">ICommandHandler&lt;T&gt;</code>. So our command handler would look something like this.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">class AddItemToCartCommandHandler : ICommandHandler&lt;TestCommand&gt; { ctor ⇥ ⇥ public async Task Handle(AddItemToCartCommand command) { var cart = repository.Load(command.CartId); cart.AddItem(command.ItemId); repository.Save(cart); } }</code></pre></div> <p>Similarly, events will use <code class="language-text">IEventHandler&lt;T&gt;</code> and queries will use <code class="language-text">IQueryHandler&lt;TQuery, TResult&gt;</code>.</p> <p>After creating the message and handler you then need to register them to the bus. Here is what a registration would look like when using Autofac. In this case handlers will be registered to Autofac with the <code class="language-text">InstancePerLifetimeScope</code> scope.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">container.RegisterMicroBus(busBuilder =&gt; busBuilder .RegisterCommand&lt;Command&gt;().To&lt;CommandHandler&gt;(...) .RegisterEvent&lt;Event&gt;().To&lt;EventHandler&gt;(...) );</code></pre></div> <p>It's also fairly easy to support any other container, and you can even use it without one at all.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var bus = new BusBuilder() .RegisterQuery&lt;Query, Result&gt;().To&lt;QueryHandler&gt;(...) .BuildBus();</code></pre></div> <p>In this case, the built-in BusBuilder is used to create a bus without any IOC container.</p> <h2>The Pipeline</h2> <p>Messages and Handlers are the bread and butter of MicroBus, but the real power comes from the Pipeline. The pipeline consists not only of just the end handler but lets you place any number of intermediary pipeline handlers between receiving the message and handling it.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 609px;" > <a class="gatsby-resp-image-link" href="/static/8cb3b8cd18f859a34ea93022a96e48ee/672f7/MicroBus_PipelineHandlers.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 10.83743842364532%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAIAAADXZGvcAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAhUlEQVQI1wF6AIX/AF+c02Ge1VWW0ajJ5s/g8ajJ52Of1Wyk13ir2sTZ7cre73+w3Gyk12Sf1aHE5Mjc7rTQ6lmZ02Sg12Gb0ABamdNoo9lWmNOhxOTA1+2fw+VlodhxqNt2q9u40um81et9sN1vp9poo9mawOK40emsy+dendZvqNtcmM/sNlO1jiJJHAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Pipeline Handlers" title="Pipeline Handlers" src="/static/8cb3b8cd18f859a34ea93022a96e48ee/672f7/MicroBus_PipelineHandlers.png" srcset="/static/8cb3b8cd18f859a34ea93022a96e48ee/064a4/MicroBus_PipelineHandlers.png 225w, /static/8cb3b8cd18f859a34ea93022a96e48ee/44727/MicroBus_PipelineHandlers.png 450w, /static/8cb3b8cd18f859a34ea93022a96e48ee/672f7/MicroBus_PipelineHandlers.png 609w" sizes="(max-width: 609px) 100vw, 609px" loading="lazy" /> </a> </span></p> <p>Pipeline handlers let you intercept messages as they are passed through to the message handlers, and then the responses as they bubble back up through the pipeline. This makes pipeline handlers the ideal place to handle all the cross-cutting concerns in an application. Such as logging, security, unit-of-work/transactions to name a few.</p> <p>Here is an example of a pipeline handler responsible for starting and committing a Unit of Work.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">class TransactionHandler : IPipelineHandler { private readonly UnitOfWork unitOfWork; public PipelineHandler(UnitOfWork unitOfWork) { this.unitOfWork = unitOfWork } public async Task&lt;object&gt; Handle(Func&lt;IMessage, Task&lt;object&gt;&gt; next, IMessage message) { try { var response = await next(message); unitOfWork.Commit(); } catch { unitOfWork.Rollback(); } } }</code></pre></div> <p>The same <code class="language-text">IPipelineHandler</code> interface is used for all messages. This enables the use of the same pipeline can be used across all types of messages. This interface is fairly typical, but there's one thing worth point out here which is the first parameter of the Handle method. This method takes a <code class="language-text">Func&lt;IMessage, Task&lt;object&gt;&gt;</code> which instantiates or resolved the next handler in the pipeline and calls its handle method. This is a kind of Russian doll model in that each handler contains the next handler.</p> <p>Creating a pipeline just consists of creating a new <code class="language-text">Pipeline</code> object and adding a series of pipeline handlers to it.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var pipeline = new Pipeline() .AddHandler&lt;PipelineHandler&gt;();</code></pre></div> <p>Once the pipeline has been created you can use it for as many different messages as you want. For example here the same pipeline is used to register a command and a query.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">container.RegisterMicroBus(busBuilder =&gt; busBuilder .RegisterCommand&lt;Command&gt;().To&lt;CommandHandler&gt;(pipeline) .RegisterQuery&lt;Query&gt;().To&lt;QueryHandler&gt;(pipeline) );</code></pre></div> <h2>Compared to MVC/WebApi</h2> <p>So far we've seen MicroBus handling messages and handling cross-cutting concerns using the pipeline. While most frameworks, such as <em>ASP.NET Web API</em>, <em>ASP.NET MVC</em>, and <em>Nancy</em> will let you do something similar with handlers and action filters. One of the advantages behind the MicroBus is that it allows the application code to define the pipeline itself as opposed to embedding it in the frameworks themselves. These frameworks many also have other concerns going on besides the very simple “message in, message out” pattern.</p> <p>Decoupling the application from these frameworks also has the added benefit of being able to use the same code for multiple different entry points. For example, you have a web app that can also consume messages from a service bus. Because all the cross cutting concerns are handling by MicroBus, it becomes trivial to support.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 631px;" > <a class="gatsby-resp-image-link" href="/static/babc28e0d496643752db42db23a4a8c3/eef7a/MicroBus_Invokers.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 34.389857369255154%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABVklEQVQY032QzUvCcBzGf39fB6FDRIF4iOjipaBDpy6BUFCHQjdfsFGGLl8w37aVLt9yTiJzlbrU+UIHEbroEtz2+zXTgxH05XN5nud7eHiAySmYL6tGx8tRQkIIQYggmjM7iH45ixLseOsHEWkv0MDve9NMU5E6ROpoymQMdRQZKUOkjJAiT+Xka56qMrClOie0dJhoUZX+WEFNsY75M1iw4AzlG9nYgAvfxFlnuIiFuDRz+8mFyyxlCzzYgoWrSBbohc0eceO8Zom2XJmeO1pcOn1dxt8NZwLmS3qD9C7BGy/aq25pn8i5ScZBJg2YuOJqmuzPAGe71mTnmJYYYaDX/mi3yHj+muYDDNd/ZOQyxbI5P1Mi6dJTLj2pxEUu5aN4kuJjdwVg9lS3veIWUbWmuj+D6UOoM1SIdCDUZlKDmgKRtvAA1nBhk6itO94sMenvtv87374xXt6ohi5nAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Multiple invokers" title="Multiple invokers" src="/static/babc28e0d496643752db42db23a4a8c3/eef7a/MicroBus_Invokers.png" srcset="/static/babc28e0d496643752db42db23a4a8c3/064a4/MicroBus_Invokers.png 225w, /static/babc28e0d496643752db42db23a4a8c3/44727/MicroBus_Invokers.png 450w, /static/babc28e0d496643752db42db23a4a8c3/eef7a/MicroBus_Invokers.png 631w" sizes="(max-width: 631px) 100vw, 631px" loading="lazy" /> </a> </span></p> <p>Entry points can also include Tests making Integration and Unit testing much easier. Part of the reason for this is each feature already maps to one command and handler pair. Integration tests can simply use the bus as is with the existing pipeline, and Unit Tests can focus on handlers as a unit.</p> <h2>MicroBus Lifecycle</h2> <p>Lastly, I wanted to touch a little bit on Object Lifecycles in MicroBus. For a Bus setup using Autofac, most components will be registered as instance per lifetime scope except the bus itself. The bus is registered as transient and will create a new lifetime scope for each message. So even without using Autofac in WebAPI, each request would get a new instance of the bus and the pipeline.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 631px;" > <a class="gatsby-resp-image-link" href="/static/874835d18305241d477815b7b566b9d2/eef7a/MicroBus_Pipeline.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 14.263074484944532%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAwklEQVQI1wG3AEj/AKnJ6KLG5rrT6/n9/+vl46GtvJqtwparwc28tPPIrM28tJqtwp2uwqOvv+bEruzFrbGzu5iswparwb65vABnotldndZwptidw+Wnus1Zm9ZVnuBHlt2MqMSlsMCYrMNXoeFrq+Rgn9mcrL+nsb93pM9Vn+BQneGJp8cAn8Tlm8Hkss/o9Pr/5uLhlqq/kKrFjKjExrm27satxrm2kKrFlq3GmqzC4cKv5sOuqLC9jqnFjKjFt7e9NKh/9v8qFb4AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="MicroBus Pipeline Lifecycle" title="MicroBus Pipeline Lifecycle" src="/static/874835d18305241d477815b7b566b9d2/eef7a/MicroBus_Pipeline.png" srcset="/static/874835d18305241d477815b7b566b9d2/064a4/MicroBus_Pipeline.png 225w, /static/874835d18305241d477815b7b566b9d2/44727/MicroBus_Pipeline.png 450w, /static/874835d18305241d477815b7b566b9d2/eef7a/MicroBus_Pipeline.png 631w" sizes="(max-width: 631px) 100vw, 631px" loading="lazy" /> </a> </span></p> <p>Things get a little more complicated when handlers themselves send messages. In that case, no new scope is created so lifetime scope registrations can be shared across nested pipelines as well. It's also possible to override when MicroBus creates new scopes by implementing the <code class="language-text">IDependencyScope</code> and <code class="language-text">IDependencyResolver</code> interfaces.</p> <h2>Getting Started</h2> <p>So there you have it. MicroBus, a tiny in memory message bus that can help you structure your app, reuse your cross-cutting concerns and decouple it from communication concerns.</p> <p>I hope you enjoyed learning a little bit about what MicroBus is and how it can help you. If you're, keep to see more make sure you check out the <a href="https://github.com/Lavinski/Enexure.MicroBus">MicroBus GitHub page</a>. Or just go right ahead and install the NuGet package and have a play yourself.</p> <blockquote> <p>PM> Install-Package <a href="https://www.nuget.org/packages/Enexure.MicroBus/">Enexure.MicroBus</a></p> </blockquote> <p>For more examples, you can also check out the <a href="https://github.com/Lavinski/Enexure.MicroBus/tree/master/src/Enexure.MicroBus.Tests">Enexure.MicroBus.Tests</a> project.</p><![CDATA[Generating Read Models with Event Sourcing]]>https://daniellittle.dev/generating-read-models-with-event-sourcinghttps://daniellittle.dev/generating-read-models-with-event-sourcingTue, 21 Jul 2015 22:28:00 GMT<p>Event sourcing is a very powerful tool that allows you to capture information you didn't even know you wanted. One of the things you usually find yourself doing when event sourcing is applying the principle of CQRS. CQRS effectively splits your application into two parts, a read side for queries and a write side for commands. These two sides are kept in sync by events that the read side listens to, which represent the results of the commands. One of the issues I've tackled recently is how to go about generating the read model from these events.</p> <div class="alert alert-danger"> Update! I've learnt a lot since writing this article and no longer recommend the conclusion I came to here. In short enriching events had unforeseen problems and I would instead recommend using only delta style events in a persisted event streams. To learn more read <a href="/event-sourcing-what-properties-should-domain-events-have">Event Sourcing: What Properties should Domain Event have?</a> </div> <p>So to set the scene, imagine a bank account, it contains a series of transactions and the total for the account. The two main events that we have to handle here are credits and debits. I'll skip over why they're not just one transaction event for this post. The part I want to focus on is what properties these events need. My first thought was that these events should just represent the deltas of the system. So my credit event would only need to specify the amount. The event would then be saved to the event store and published so any other potential listeners could handle it as well.</p> <h2>Handlers keeping track themselves</h2> <p>Ok, now it's time to update the read model! My read model is a typical set of database tables, accounts and transactions. I'll start with transactions because it's easy, all I need to do here is write in my event. Now for the tricky bit. My accounts table has a balance total column that I need to update in response to the event as well, but I don't know what the new total is. Could I use the existing value in the read model and just add my amount to it? No, that doesn't feel right at all, worse my values could drift between models. There's also another problem. If another service wanted to listen for these events and keep track of the total. They'd have to deal with the same problem, doing the calculation again themselves. They might not even have persisted memory to keep track of the total.</p> <blockquote> <p>The Credit Added event containing just the amount to add</p> </blockquote> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">/* CreditAddedEvent */ { &#39;amount&#39;: 10.0 }</code></pre></div> <blockquote> <p>With deltas each listener has to duplicate the work done</p> </blockquote> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Who needs the total: - Domain model - Read model to display total - Reporting</code></pre></div> <h2>Using the domain model's current state</h2> <p>It would be fantastic if I somehow had access to the information when the credit event is raised. The model in the write side keeps track of the balance total already. Can I get the information from the model when processing the event? This could work, but it would require exposing the total via a property so the handler could access it. </p> <blockquote> <p>I could get the information from the model when processing the event</p> </blockquote> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// Maybe something like this public void Handle(Metadata&lt;CreditAddedEvent&gt; metadataEvent) { metadataEvent.DomainEvent.Amount metadataEvent.DomainModel.Total }</code></pre></div> <p>This didn't quite sit well with me either, one of the great things about the models in CRQS+ES is they can shed all their properties and properly encapsulate their state. If I expose properties here command handlers would then have access when they really shouldn't. There's also one other concern, tests. I also need to check the total in my tests and exposing this makes testing harder because my model is exposing more of its implementation. So either I can't change my model, or my tests become more prone to change. </p> <h2>Enriching the event</h2> <p>My last option to get the total is to put the total on the event itself (enriching the event). So that the event would then contain the amount of credit and the new total for the balance. I'd been avoiding this because the total could be derived from the events that just contained the credits and debits. Adding the derived totals would then mean they had to be persisted in the event store. However looking back this gives us exactly what we want and solves some other problems along the way.</p> <blockquote> <p>Enriching the event means that it now represents the state change</p> </blockquote> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">/* CreditAddedEvent */ { &#39;amount&#39;: 10.0, &#39;newTotal&#39;: 70.0 }</code></pre></div> <p>Enriching the event means that it now represents the state change of the aggregate. Therefore, the state change becomes completely explicit and simplifies usage of the event stream immensely. Consumers don't have to keep track of any state themselves, in my case keeping their own tally. Enriching the events also helps keep my code dry, all my calculations take place in the behaviours of my models. This also makes replaying my events blisteringly fast because only have to set fields; no other calculations are needed. This would be even more beneficial if derived values were computationally expensive. As for the idea of exposing properties, enriching the event means I don't need to expose any properties for tests or to generate the real model. Everything they need is on the events, and the aggregates completely encapsulate all their internal state. The domain models should only need to process commands and emit events as side effects. This also helps unit tests become more resilient to change while giving me more freedom to change the internals of the models. You'll also find that some state doesn't even need to be kept in the memory of the models but may only be used in the events and the read model.</p> <h2>Enriching the event but not storing it</h2> <p>However, there's one more possible path I could have taken. Which is to have two different events. The delta that is stored in the event store and the enriched event that is only in memory. There are also problems with this approach, but I want to include it for completeness. While this gives me most of the benefits from just having one event, replaying the events becomes a much more expensive operation. I'd also have to write two events instead of just one which adds a whole bunch of other complexities and raised a whole bunch of questions. Would the events have the same identity? Would I need to store things that are not deltas anyway, such as answers from external services? What would I call the new event? They are the same event but have different models, it feels awkward giving two events the same name. I'd much rather just store the extra data and have just one event. </p> <h2>In the end</h2> <p>Enriching my domain events and saving them in the event store lets me generate the read model I need easily and avoids unnecessary complexity. Thus keeping the application in a maintainable state. I get the benefits of fast replaying of events, having all state change explicitly represented in the events and fully encapsulated state in my domain models. I could also data mine the raw event stream much more easily without using my application to process the events or duplicating the logic in it. </p><![CDATA[The Perfect Pot]]>https://daniellittle.dev/the-perfect-pothttps://daniellittle.dev/the-perfect-potSat, 24 Jan 2015 06:25:49 GMT<p>Whether it's building software, a business, or some other project, chances are you'll almost never get it right the first time. Years ago, I heard a story of a pottery teacher that tried an experiment on the class to find out the best way to teach pottery to the students.</p> <blockquote> <p>A high school pottery teacher was addressing the class, regarding their new assignment. The teacher told half of the class that they had the semester to create their best pot, which they would submit to be graded. To the other half of the class, the teacher said they would have to make 50 pots and that they would be graded on their best pot.</p> </blockquote> <p>Who do you think produced the best pot? If you said the second half of the class, you'd be correct. I think the story applies well to the art of software development and I don't mean just building 50 of something. So lets explore this a little bit, why did they do better?</p> <h2>Practice</h2> <p>This is the classical answer, and it has a lot to do with the way the mind works. Practice strengthens the neural pathway in the brain. When you first learn something, it requires a very conscious effort. But as you practice, you become more efficient until you can perform the task almost without thinking. Regardless of whether you're doing pottery or writing software, this not only makes you faster, but when you can do these things "without thinking," you can spend more time thinking about other things. In other words, it will free up your mind so you can focus on the finer details.</p> <h2>Blinded by Perfection</h2> <p>The first group were too busy trying to decide what makes the perfect pot, and they are never able to make it because they don't have the necessary skill to achieve their goal. However, the second half of the class was forced to make pot after pot and refine their process.</p> <p>In software, this is commonly referred to as analysis paralysis. Where you spend so long trying to figure out everything, you never get around to actually starting or finishing. However, when you're forced to spend more time just building things and finishing things, you get to experience a wider range of problems and solutions.</p> <h2>Destination Unknown</h2> <p>To me, this was the most important point. But what do I mean by destination unknown? Well, the first group did not know what the perfect pot would look like or how to make it. They did not know what would make the pot collapse and what would make it beautiful. They had a vague idea of what they wanted to make it but lacked the skills to get there. So, by focusing on building the perfect pot, they did not get the opportunity to learn as much. The second group, on the other hand, started out in the same place but through trial and error they built on their knowledge. They were free to experiment and refine their process as they went.</p> <p>The same applies to software development as well. Jumping in and building things lets you discover how a solution should look and how to build it. As you progress and encounter real issues, you can find the solutions as you need them. This is a much better way for us to learn, as we can see the reasons behind them much more clearly. You also don't need to solve everything upfront, which may be too much to hold in your head at one time. It's impossible to exactly know what to do upfront, you have to discover it along the way.</p> <blockquote> <p>The first half of the pottery class spent hours on a single pot, throwing it and rethrowing it. But by the end, none of them had made a perfect pot. Students that had to make 50 pots, on the other hand, made so many pots that they figured out what worked and what didn't. By the end of the semester, they could all throw a perfect pot.</p> </blockquote> <p>When writing software, the only time I knew what I should have done is after I've already tried something. You can't think of everything upfront. The best way to learn something is to try and do it.</p><![CDATA[Calling a Rest (Json) API with PowerShell]]>https://daniellittle.dev/calling-a-rest-json-api-with-powershellhttps://daniellittle.dev/calling-a-rest-json-api-with-powershellTue, 11 Nov 2014 04:39:46 GMT<p>PowerShell makes working with rest API's easy. In PowerShell version 3, the cmdlets <code class="language-text">Invoke-RestMethod</code> and <code class="language-text">Invoke-WebRequest</code> where introduced. These cmdlets are a huge improvement coming from the .NET model you had to work with previously turning a request into a concise one liner similar to curl (Which is also an alias for <code class="language-text">Invoke-WebRequest</code> in PowerShell).</p> <p>The difference between the two is quite small, <code class="language-text">Invoke-RestMethod</code> simply being a slightly more convenient wrapper around <code class="language-text">Invoke-WebRequest</code> as it only returns the content, omitting the headers.</p> <p>The most common case I tend to use this method for is querying or posting to a json rest API's. I usually end up just using <code class="language-text">Invoke-RestMethod</code> so I'll focus on it.</p> <p>The simplest call you can make is to just provide the URL. This will default to a <code class="language-text">GET</code> request, and any unsupplied optional parameters are omitted from the request. For example, this <code class="language-text">GET</code> request won't have a content type. However, if this parameter is omitted and the request method is <code class="language-text">POST</code>, <code class="language-text">Invoke-RestMethod</code> sets the content type to "application/x-www-form-urlencoded". Invoke-RestMethod -Uri $uri</p> <p>The value returned will be automatically parsed depending on the content type of the response. For a json endpoint, I'll automatically get a PowerShell object (hashtable) that represents the json response.</p> <p>So getting data from an endpoint is pretty easy but most rest APIs require an authentication token in order to verify your request. The most common way of supplying the token is via a HTTP header, which looks like this.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$apiKey = &quot;SomeKey&quot; $resource = &quot;http://localhost/api/books&quot; Invoke-RestMethod -Method Get -Uri $resource -Header @{ &quot;X-ApiKey&quot; = $apiKey }</code></pre></div> <p>Now we can query a json endpoint, but what about sending json. PowerShell objects can be represented using hashtables in a similar way to Javascript objects. PowerShell 2.0 also provides two functions (<code class="language-text">ConvertTo-Json</code> and <code class="language-text">ConvertFrom-Json</code>) for easily converting back and forth between JSON and PowerShell objects. The final step is to just construct a PS object and convert it.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$body = @{ Name = &quot;So long and thanks for all the fish&quot; } Invoke-RestMethod -Method Post -Uri &quot;$resource\new&quot; -Body (ConvertTo-Json $body) -Header @{&quot;X-ApiKey&quot;=$apiKey}</code></pre></div> <p>So in just four lines of code you an submit a simple POST to any HTTP endpoint. If you want some further reading, you can also find the documentation for <code class="language-text">Invoke-RestMethod</code> at Microsoft TechNet.</p><![CDATA[MVC Architecture]]>https://daniellittle.dev/mvc-architecturehttps://daniellittle.dev/mvc-architectureThu, 25 Sep 2014 09:40:14 GMT<p>The typical scaffolding tool and sample applications for MVC web apps are usually based on simple CRUD like systems. They'll, usually, have Views written in a templating language, with some kind of ORM and Models for persistence and Controllers to tie the two together.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 870px;" > <a class="gatsby-resp-image-link" href="/static/310746e4411235a72b4c6d5114f142ce/386eb/Basic-MVC.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 21.724137931034484%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAABnWAAAZ1gEY0crtAAAAoUlEQVQI1yVPCQ7DMAjr/1/aNc3JkYSmMLIhgWSDMRy6RDFaL151su3QnQONsvWqmOxd9m9M3nCT0ZYcDnRQR1iDFGIXhFFU9a1Xx0rQJJ8mgwRIUOF+sCK0hVm5HtvwkZTbnNM4V74L365dLaRSPyFxuuwZmUObxSgxwhmiEFhvh9tqC8bFt75U1LbrvhDi7+ym9fTXXqed9AEINpy8XPgFjnLnfxxyQyUAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="View, Controller and Model" title="View, Controller and Model" src="/static/310746e4411235a72b4c6d5114f142ce/386eb/Basic-MVC.png" srcset="/static/310746e4411235a72b4c6d5114f142ce/064a4/Basic-MVC.png 225w, /static/310746e4411235a72b4c6d5114f142ce/44727/Basic-MVC.png 450w, /static/310746e4411235a72b4c6d5114f142ce/386eb/Basic-MVC.png 870w" sizes="(max-width: 870px) 100vw, 870px" loading="lazy" /> </a> </span></p> <p>But there's a problem with this layout, and it's causing the Controllers to grow out of control. Because this scenario is based on CRUD the design here has found it's way into all kinds of applications, such as applications that need more than trivial amounts of business logic. Hopefully, now we can start to see the issue. All this logic ends up being placed in the Controllers which as a result become bloated. This also negatively impacts the Model, which effectively becomes just a data access layer.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 870px;" > <a class="gatsby-resp-image-link" href="/static/c1ea0e24e2093e282adf02797dce7547/386eb/Big-Controller.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 30.459770114942526%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAABnWAAAZ1gEY0crtAAAAxklEQVQY02VQi67DIAjt/39pt+m6IoKowLBLlt1cY0jgPDyy+f+j0/D555ZsnS/MfombjRaY88swG5eFN7R6uGm4fKoJaUkL4hI0b2AlhXBbxkKEOIVjxIM0GK3EE7zGdc7QjxCzStReoQDM+jI6tysS5ZwbV8dcBCaDN1T3/Dxu9yR9uM1ZHjiCkAiOfd97OXyJOymmlaTmMLMrm8LdhvgU1+6jKZ163gJSXjTvGBFMePt83X4XocNWKliasCNYrdB3YV/yG29dXh/YTZQ9AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Big Controller MVC" title="Big Controller MVC" src="/static/c1ea0e24e2093e282adf02797dce7547/386eb/Big-Controller.png" srcset="/static/c1ea0e24e2093e282adf02797dce7547/064a4/Big-Controller.png 225w, /static/c1ea0e24e2093e282adf02797dce7547/44727/Big-Controller.png 450w, /static/c1ea0e24e2093e282adf02797dce7547/386eb/Big-Controller.png 870w" sizes="(max-width: 870px) 100vw, 870px" loading="lazy" /> </a> </span></p> <p>So what's the alternative?</p> <p>In MVC, the Model is often confused with various other similar concepts such as DTOs or a data layer. However, the Model is a more general concept that refers to the entire set of concepts your application is modelling. Persistence isn't a concern of the MVC pattern. So you can think of the Model as the entire domain, which includes the behaviours (business logic) and state. It's also useful to remember that the MVW (Model View Whatever) patterns are user interface patterns and do not attempt to describe or constrain any of these parts other than to split the View from the Model.</p> <p>Moving the majority of application logic into the Model frees the Controller and View from dealing with those concerns and leaves them to focus on their primary role; which is to act as an interface to the outside world. This allows the Model to focus on the domain. Letting it properly encapsulate internal concepts, and exposing it's own facades where needed. It can even be self-contained with a well defined API of its own. With that in mind, the purpose of the controller becomes a bit clearer. Its job is simply to translate a request for the Model and any results back for the views.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/8f817d93325150f0512c6924a3e91bdd/feebe/Big-Model.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 28.04232804232804%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAABnWAAAZ1gEY0crtAAAAoklEQVQY042Q2woDIQxE9/+/tN3WJGq8rRobhRaWbaFhXmQ8kyHbOI0sXUemkbww9CUJKIE2fY/khI1k/vxUYyQa0U5XVlyr4p+jHaPXpSZ236RE9r4nVt4VomSklmZ3S2QJK957zRAfHEGzNIRDcN7PFQyb5EAIR5jLbUGXcdRDYQQA86x4U9jEPSaadRT2jERv+Gdtq7rUrqfafx5sfDvYC4o0XlfP9km+AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Big Model MVC" title="Big Model MVC" src="/static/8f817d93325150f0512c6924a3e91bdd/fea0e/Big-Model.png" srcset="/static/8f817d93325150f0512c6924a3e91bdd/064a4/Big-Model.png 225w, /static/8f817d93325150f0512c6924a3e91bdd/44727/Big-Model.png 450w, /static/8f817d93325150f0512c6924a3e91bdd/fea0e/Big-Model.png 900w, /static/8f817d93325150f0512c6924a3e91bdd/feebe/Big-Model.png 945w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>In new applications, it's tempting to use the Models to generate the views and bind changes directly back onto the Models. However, this tends to lead back to large controllers that do too much, and <a href="https://www.infoq.com/news/2012/03/GitHub-Compromised">has other problems</a> as well. To avoid these issues instead of binding directly onto the Model (which may not even be possible such as when doing Domain Driven Design) data is bound onto a ViewModel. While View Models can sometimes look similar to objects in the Model they are distinct and ideally are never referenced from the Model. Separating them have a number of benefits including security, separation of concerns (think web validation) and most importantly decouple the Model from the View.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/7f65b0a07e82bc985e991ee390bb340a/b47b0/ViewModels.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.81497797356828%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAABnWAAAZ1gEY0crtAAAAsUlEQVQI1xWP27LDIAhF8/9f2clJ47E1XqKoKELJEzPsvZjFxjS5eGmJyyWjLZaxeLIQCy/iGjWSGrkXEWGsDFq+GYKsuXFNGrTWqGbM9ozFuGS+4e0heEMQAKDltLJrC1e5Bty6Wa0oqHDU4S+H6er3eYS8H/a1H/snft0fRmvN6e1J0QI1zq76j/03VCJD3HjqvSBYVJ4RxpI+GUk6Cc3+aA94nqo3q3YvygjCoz3xB8ux5gHWrCWjAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="View Models" title="View Models" src="/static/7f65b0a07e82bc985e991ee390bb340a/fea0e/ViewModels.png" srcset="/static/7f65b0a07e82bc985e991ee390bb340a/064a4/ViewModels.png 225w, /static/7f65b0a07e82bc985e991ee390bb340a/44727/ViewModels.png 450w, /static/7f65b0a07e82bc985e991ee390bb340a/fea0e/ViewModels.png 900w, /static/7f65b0a07e82bc985e991ee390bb340a/b47b0/ViewModels.png 908w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>Decoupling the Model is extremely important as not doing so will severely limit how easy it is to make changes to the system. As the View will diverge from the Model in most systems. A simple example would be a markdown editor where you stored both the original Markdown and generated HTML in the Model as an optimisation. Sharing the Model with the View would have effectively limited the application to basic CRUD as the View must always mirror the Model.</p> <p>However, there's still a problem even after introducing View Models. Applications not only diverge between the Model and the View Models. They also Diverge depending on the action you're performing. For example, when creating a record you may wish to include several fields that are read-only after that point. So updates need to use a different View Model from creates. They may even diverge depending on if the View Model is used for Input or Output. Using the same example, we may want to then show these fields as read-only when updating. Which would require them to exist in the Output Update View Model but not the Input Update View Model. In practice, I've found these View Models can start out looking very similar to your Models. But as time goes on and they diverge it becomes apparent the input (parameter) and output (return value) of each Action in the controller can be deserving of its own View Model.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/352c87a56ca733b2e73c1c8d5696d19f/b47b0/Split-ViewModels.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 37.55506607929516%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAABnWAAAZ1gEY0crtAAABEklEQVQY04WRbUsDMQzH7/t/NQXBN4Jzzo3bw12vd23Sh7S9JnZjoAhqSAIJgfzyTyfCNxdmMT5rl2aXWoaQ5Wp8d+afJUsn914FirPLYO1m+w6IChLVUqXK79YxThIhmAMu54uht/3p+WX7ujuOkCOOftkLIaPiFK47ghU/C1m2A2fqOEWPWHJinOu63kH4RokqNBILcVE1LK44BkXBWYACWsh1LZZpjA7ETaUUKjWvTKk0YgEFehwvZxz61bebnMAQ0bROXi6NqGOnJXlnDmDOkysa/Mdx0BBGKKGNwklyYK8537AjSDCS3fWQQl+CIVETqe/7h8en3f4w2hQKVeG/BPv+KuvTBFEjKRuMT/++6hPzo8+cPmy5QwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Splitting the View Models" title="Splitting the View Models" src="/static/352c87a56ca733b2e73c1c8d5696d19f/fea0e/Split-ViewModels.png" srcset="/static/352c87a56ca733b2e73c1c8d5696d19f/064a4/Split-ViewModels.png 225w, /static/352c87a56ca733b2e73c1c8d5696d19f/44727/Split-ViewModels.png 450w, /static/352c87a56ca733b2e73c1c8d5696d19f/fea0e/Split-ViewModels.png 900w, /static/352c87a56ca733b2e73c1c8d5696d19f/b47b0/Split-ViewModels.png 908w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>Because of the similarities that View Models can have with the Model it can be possible to automate this process of converting between the two. In the past, I've used <a href="https://automapper.org/">AutoMapper</a> to do exactly this. However, as the View Models inevitably diverge you end up with so many mapping rules that it becomes easier to do the mappings explicitly. To read more about why using a mapper should be avoided check out the post <a href="https://www.uglybugger.org/software/post/friends_dont_let_friends_use_automapper">Friends don't let friends use AutoMapper</a>.</p> <p>So to recap, the aim of MVC is to separate the View from the Model of the application. The Model should be where the bulk of your application lies and is effectively your application without the user interface. The View and the View Models represent the user's representation of the system. The controller then sits between the two and is the glue that brings these two parts together. This results in increased flexibility due to the decoupling between the two sides. Which means changes to the application are both easier and faster as you don't have to fight the Model to fit the design.</p><![CDATA[Avoid null with Containers]]>https://daniellittle.dev/avoid-null-with-container-typeshttps://daniellittle.dev/avoid-null-with-container-typesWed, 27 Aug 2014 22:42:52 GMT<p>In C# It's often recommended that you should avoidi using nulls wherever possible. Avoiding nulls is a great concept that can simplify your code. Even so, nulls (or some such equivalent concept) will always have their place, such as to convey data is not available.</p> <p>However, one case where I always pay close attention to using nulls is when working with what object-oriented developers call Containers. A container simply wraps around an instance or multiple insances of some type. This includes types such as Enumerable<T>, List<T>, Lazy<T>, Observable<T>, Task<T>, Nullable<T> (which is partially a special case because it never throws a NullReferenceException) arrays and other similar non-generic types. Typically in these cases returning an empty list or an empty Task over returning null makes the code much more clean and clear. By not returning null, you don't have to check for nulls and hence your code does not need to follow a different path based on the return value. </p> <p>Comparing between the two even in a simple case greatly increases the complexity of the code. The first example is a standard foreach over an enumerable.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">foreach (var item in enumerable) { item.Dump() }</code></pre></div> <p>Which when you need to worry about nulls would become the following</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">if (enumerable != null) { foreach (var item in enumerable) { item.Dump() } }</code></pre></div> <p>And for Tasks, here is the what it looks like without nulls</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var result = await DoAsync()</code></pre></div> <p>And when the function can return nulls you loose type inference or end up with deeply nested code.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">object result; var resultAwaitable = await DoAsync(); if (resultAwaitable != null) { result = await resultAwaitable; }</code></pre></div> <p>There are two main cases where you still might want to return a null value. Such as to be explicit about the difference between unavailable data and no data. The other is to avoid extra memory allocations in high-performance scenarios. However, I find both of these cases to be relatively rare.</p> <p>In the end, the most important thing is usually maintainability and standardizing on empty containers offers more reliable and concise code.</p><![CDATA[Example Web.Config files (3.5 and 4.5)]]>https://daniellittle.dev/example-web-config-files-3-5-and-4-5https://daniellittle.dev/example-web-config-files-3-5-and-4-5Mon, 04 Aug 2014 07:00:35 GMT<p>These are the default generated Web.Config files from Visual Studio 2013 Update 3.</p> <ul> <li><a href="#Framework451">Web.Config for .NET Framework 4.5.1</a></li> <li><a href="#Framework35">Web.Config for .NET Framework 3.5</a></li> </ul> <p>Other variations are all quite similar but if you think I'm missing one that's useful leave a comment.</p> <p><a name="Framework451"><strong>Web.Config for .NET Framework 4.5.1</strong></a></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt; &lt;!-- For more information on how to configure your ASP.NET application, please visit https://go.microsoft.com/fwlink/?LinkId=301880 --&gt; &lt;configuration&gt; &lt;configSections&gt; &lt;!-- For more information on Entity Framework configuration, visit https://go.microsoft.com/fwlink/?LinkID=237468 --&gt; &lt;section name=&quot;entityFramework&quot; type=&quot;System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&quot; requirePermission=&quot;false&quot; /&gt; &lt;/configSections&gt; &lt;connectionStrings&gt; &lt;add name=&quot;DefaultConnection&quot; connectionString=&quot;Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WebApplication45-20140804053515.mdf;Initial Catalog=aspnet-WebApplication45-20140804053515;Integrated Security=True&quot; providerName=&quot;System.Data.SqlClient&quot; /&gt; &lt;/connectionStrings&gt; &lt;appSettings&gt; &lt;add key=&quot;webpages:Version&quot; value=&quot;3.0.0.0&quot; /&gt; &lt;add key=&quot;webpages:Enabled&quot; value=&quot;false&quot; /&gt; &lt;add key=&quot;ClientValidationEnabled&quot; value=&quot;true&quot; /&gt; &lt;add key=&quot;UnobtrusiveJavaScriptEnabled&quot; value=&quot;true&quot; /&gt; &lt;/appSettings&gt; &lt;system.web&gt; &lt;authentication mode=&quot;None&quot; /&gt; &lt;compilation debug=&quot;true&quot; targetFramework=&quot;4.5.1&quot; /&gt; &lt;httpRuntime targetFramework=&quot;4.5.1&quot; /&gt; &lt;/system.web&gt; &lt;system.webServer&gt; &lt;modules&gt; &lt;remove name=&quot;FormsAuthenticationModule&quot; /&gt; &lt;/modules&gt; &lt;/system.webServer&gt; &lt;runtime&gt; &lt;assemblyBinding xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot;&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.Helpers&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; /&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-3.0.0.0&quot; newVersion=&quot;3.0.0.0&quot; /&gt; &lt;/dependentAssembly&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.Mvc&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; /&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-5.1.0.0&quot; newVersion=&quot;5.1.0.0&quot; /&gt; &lt;/dependentAssembly&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.Optimization&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; /&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-1.1.0.0&quot; newVersion=&quot;1.1.0.0&quot; /&gt; &lt;/dependentAssembly&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.WebPages&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; /&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-3.0.0.0&quot; newVersion=&quot;3.0.0.0&quot; /&gt; &lt;/dependentAssembly&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;WebGrease&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; /&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-1.5.2.14234&quot; newVersion=&quot;1.5.2.14234&quot; /&gt; &lt;/dependentAssembly&gt; &lt;/assemblyBinding&gt; &lt;/runtime&gt; &lt;entityFramework&gt; &lt;defaultConnectionFactory type=&quot;System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework&quot;&gt; &lt;parameters&gt; &lt;parameter value=&quot;v11.0&quot; /&gt; &lt;/parameters&gt; &lt;/defaultConnectionFactory&gt; &lt;providers&gt; &lt;provider invariantName=&quot;System.Data.SqlClient&quot; type=&quot;System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer&quot; /&gt; &lt;/providers&gt; &lt;/entityFramework&gt; &lt;/configuration&gt;</code></pre></div> <p><a name="Framework35"><strong>Web.Config for .NET Framework 3.5</strong></a></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&lt;?xml version=&quot;1.0&quot;?&gt; &lt;configuration&gt; &lt;configSections&gt; &lt;sectionGroup name=&quot;system.web.extensions&quot; type=&quot;System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;&gt; &lt;sectionGroup name=&quot;scripting&quot; type=&quot;System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;&gt; &lt;section name=&quot;scriptResourceHandler&quot; type=&quot;System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; requirePermission=&quot;false&quot; allowDefinition=&quot;MachineToApplication&quot;/&gt; &lt;sectionGroup name=&quot;webServices&quot; type=&quot;System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;&gt; &lt;section name=&quot;jsonSerialization&quot; type=&quot;System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; requirePermission=&quot;false&quot; allowDefinition=&quot;Everywhere&quot; /&gt; &lt;section name=&quot;profileService&quot; type=&quot;System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; requirePermission=&quot;false&quot; allowDefinition=&quot;MachineToApplication&quot; /&gt; &lt;section name=&quot;authenticationService&quot; type=&quot;System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; requirePermission=&quot;false&quot; allowDefinition=&quot;MachineToApplication&quot; /&gt; &lt;section name=&quot;roleService&quot; type=&quot;System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; requirePermission=&quot;false&quot; allowDefinition=&quot;MachineToApplication&quot; /&gt; &lt;/sectionGroup&gt; &lt;/sectionGroup&gt; &lt;/sectionGroup&gt; &lt;/configSections&gt; &lt;appSettings /&gt; &lt;connectionStrings /&gt; &lt;system.web&gt; &lt;compilation debug=&quot;true&quot;&gt; &lt;assemblies&gt; &lt;add assembly=&quot;System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089&quot;/&gt; &lt;add assembly=&quot;System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089&quot;/&gt; &lt;add assembly=&quot;System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add assembly=&quot;System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089&quot;/&gt; &lt;/assemblies&gt; &lt;/compilation&gt; &lt;!-- The &lt;authentication&gt; section enables configuration of the security authentication mode used by ASP.NET to identify an incoming user. --&gt; &lt;authentication mode=&quot;Windows&quot; /&gt; &lt;!-- The &lt;customErrors&gt; section enables configuration of what to do if/when an unhandled error occurs during the execution of a request. Specifically, it enables developers to configure html error pages to be displayed in place of a error stack trace. &lt;customErrors mode=&quot;RemoteOnly&quot; defaultRedirect=&quot;GenericErrorPage.htm&quot;&gt; &lt;error statusCode=&quot;403&quot; redirect=&quot;NoAccess.htm&quot; /&gt; &lt;error statusCode=&quot;404&quot; redirect=&quot;FileNotFound.htm&quot; /&gt; &lt;/customErrors&gt; --&gt; &lt;pages&gt; &lt;controls&gt; &lt;add tagPrefix=&quot;asp&quot; namespace=&quot;System.Web.UI&quot; assembly=&quot;System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add tagPrefix=&quot;asp&quot; namespace=&quot;System.Web.UI.WebControls&quot; assembly=&quot;System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;/controls&gt; &lt;/pages&gt; &lt;httpHandlers&gt; &lt;remove verb=&quot;*&quot; path=&quot;*.asmx&quot;/&gt; &lt;add verb=&quot;*&quot; path=&quot;*.asmx&quot; validate=&quot;false&quot; type=&quot;System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add verb=&quot;*&quot; path=&quot;*_AppService.axd&quot; validate=&quot;false&quot; type=&quot;System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add verb=&quot;GET,HEAD&quot; path=&quot;ScriptResource.axd&quot; type=&quot;System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; validate=&quot;false&quot;/&gt; &lt;/httpHandlers&gt; &lt;httpModules&gt; &lt;add name=&quot;ScriptModule&quot; type=&quot;System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;/httpModules&gt; &lt;/system.web&gt; &lt;system.codedom&gt; &lt;compilers&gt; &lt;compiler language=&quot;c#;cs;csharp&quot; extension=&quot;.cs&quot; warningLevel=&quot;4&quot; type=&quot;Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&quot;&gt; &lt;providerOption name=&quot;CompilerVersion&quot; value=&quot;v3.5&quot;/&gt; &lt;providerOption name=&quot;WarnAsError&quot; value=&quot;false&quot;/&gt; &lt;/compiler&gt; &lt;/compilers&gt; &lt;/system.codedom&gt; &lt;!-- The system.webServer section is required for running ASP.NET AJAX under Internet Information Services 7.0. It is not necessary for previous version of IIS. --&gt; &lt;system.webServer&gt; &lt;validation validateIntegratedModeConfiguration=&quot;false&quot;/&gt; &lt;modules&gt; &lt;remove name=&quot;ScriptModule&quot; /&gt; &lt;add name=&quot;ScriptModule&quot; preCondition=&quot;managedHandler&quot; type=&quot;System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;/modules&gt; &lt;handlers&gt; &lt;remove name=&quot;WebServiceHandlerFactory-Integrated&quot;/&gt; &lt;remove name=&quot;ScriptHandlerFactory&quot; /&gt; &lt;remove name=&quot;ScriptHandlerFactoryAppServices&quot; /&gt; &lt;remove name=&quot;ScriptResource&quot; /&gt; &lt;add name=&quot;ScriptHandlerFactory&quot; verb=&quot;*&quot; path=&quot;*.asmx&quot; preCondition=&quot;integratedMode&quot; type=&quot;System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add name=&quot;ScriptHandlerFactoryAppServices&quot; verb=&quot;*&quot; path=&quot;*_AppService.axd&quot; preCondition=&quot;integratedMode&quot; type=&quot;System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add name=&quot;ScriptResource&quot; preCondition=&quot;integratedMode&quot; verb=&quot;GET,HEAD&quot; path=&quot;ScriptResource.axd&quot; type=&quot;System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; /&gt; &lt;/handlers&gt; &lt;/system.webServer&gt; &lt;runtime&gt; &lt;assemblyBinding appliesTo=&quot;v2.0.50727&quot; xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot;&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.Extensions&quot; publicKeyToken=&quot;31bf3856ad364e35&quot;/&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-1.1.0.0&quot; newVersion=&quot;3.5.0.0&quot;/&gt; &lt;/dependentAssembly&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.Extensions.Design&quot; publicKeyToken=&quot;31bf3856ad364e35&quot;/&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-1.1.0.0&quot; newVersion=&quot;3.5.0.0&quot;/&gt; &lt;/dependentAssembly&gt; &lt;/assemblyBinding&gt; &lt;/runtime&gt; &lt;/configuration&gt;</code></pre></div><![CDATA[Unlocking locked files in Windows]]>https://daniellittle.dev/locked-files-in-windowshttps://daniellittle.dev/locked-files-in-windowsFri, 01 Aug 2014 09:21:35 GMT<p>Every developer has run into this issue at least once. There are a few different tools you can use to find out what process is locking a file. In the past I've used a few different tools.</p> <p>My favorite tool today is <a href="https://lockhunter.com">Lock Hunter</a> which is powerful and easy to use. It's packed with a bunch of useful features, integrates nicely into explorer and installs without any "bonus" software. I can't recommend it enough.</p> <p>Before Lock Hunter I used <code class="language-text">Unlocker</code> by Empty Loop as my go to solution but today it's bundled with a toolbar and isn't early as pleasant as Lock Hunter.</p> <p>If you're already using <a href="https://technet.microsoft.com/en-au/sysinternals/bb896653.aspx">Process Explorer</a> it can be a great solution. You can use it's <code class="language-text">Find Handle or DLL</code> to locate the culprit. On the downside (or maybe the upside depending on your point of view) there are is no explorer integration.</p> <p><a href="https://technet.microsoft.com/en-us/sysinternals/bb896655.aspx">Handle</a> is another tool by Systernals but aimed solely at the command like. This tool focus on the basics and leaves the action up to the user.</p> <p>Missed a tool you love to use? Leave a comment!</p><![CDATA[Debugging Rx with Seq]]>https://daniellittle.dev/debugging-rx-with-seqhttps://daniellittle.dev/debugging-rx-with-seqMon, 21 Jul 2014 08:34:02 GMT<p>Debugging Reactive Extensions can sometimes be a bit tricky. When you have a few stream to watch, pinpointing failures is time consuming, and a can easily become a burden.</p> <p>Catching first-chance exceptions can be extremely helpful when debugging Rx. However, it's much more useful to see how events progress over time. After coming across a thread about <a href="https://social.msdn.microsoft.com/Forums/en-US/a0215434-8ad6-45e1-9f21-ed2f14d7317a/a-simple-trace-method?forum=rx">tracing in Reactive Extensions</a> I thought I could make a few improvements to their tracing methods by making use of Seq and <a href="https://serilog.net/">Serilog</a>.</p> <p><a href="https://getseq.net/">Seq</a> is fantastic tool that lets you visualise and explore log data quickly and easily. You can get Seq up and running within minutes. Just download the NuGet for <a href="https://github.com/serilog/serilog/wiki/Getting-Started">Serilog</a> and install <a href="https://getseq.net/Download">the latest version of Seq</a>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/5fbb67b11bac623886dbc97906e380ad/2ab4f/Seq.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 57.96676441837732%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACcklEQVQoz5WSWU/bQBSF819LN1XqIvUftFKrPvUZqTyAKkEoqlCBUBChhYTisJhA2JIQiOOxY2dzNqeQ5et1gMJDXzqaT+famnPmPExoJfyRtbkxVmdHWZ8fY/P7ONrSxDXLE8TkXyzyGT0+x/7mAsnNiJz/xMrkO1anBNGV8HuWR98S+fCa0MuZFA8mDxkJmDriYfiYR+GTv4xMHjESzvBktiAYPPumeDp9wvOvgnhfTCd59SXJ45kT3oyHCVW8Jo2WT7PdoeUHesfwWyi6LlbRRtkWVa9OpebhNX0a4vGabbxGi4bfJZWIEtK0BPF4DG1zg6KVQhk6tkpRyIua+5j5nSHK2MU412h4BWzLZj+5R3JPZ3dnm+2tBNmzHHuxeQnUD9jY2kHb1clL2IWYcrltsllN5gQX+QPOjRSGOsWqOJRbLWrSUimFaZpDLJmDlnpsgVCtC/UrqF4OyJcrnBbLZIQzt8KJXcJu9bB8UO0B9R7U5Ozvyys6HR/fv6HdptsHfV0aVi4lrDOg3OmSVzZZVcbrXhtL/oBzp4pZbWF5PqX2Fa7QH/DPtRsE1iW5ITcHt7vNS5zGFZ6EBZT9nlxQIm06ZEyXC9dD1dr0gsTBQPYN/f5d4FbyEG1HZzu5j+3mMO1TClZayFKuOThlE1U0hhRLinq7ybDg/cDBvcBoNMpiJMLy0iK5dIz0UZTM8U+ZNfq9buAcmrk1CoEGrW613+/dBM4Riv/S+LG2TnwjjmMfokwdS56LbR3zv2tvY5GQcXZMPivPIntISWWE9I1mqDoGNbdALdDhbFARta08jnlGsZClYF5IiXOKjiKxMs0fVs5gVYoFZzAAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Rx events in Seq" title="Rx events in Seq" src="/static/5fbb67b11bac623886dbc97906e380ad/fea0e/Seq.png" srcset="/static/5fbb67b11bac623886dbc97906e380ad/064a4/Seq.png 225w, /static/5fbb67b11bac623886dbc97906e380ad/44727/Seq.png 450w, /static/5fbb67b11bac623886dbc97906e380ad/fea0e/Seq.png 900w, /static/5fbb67b11bac623886dbc97906e380ad/2ab4f/Seq.png 1023w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span> <em>Some events in Seq.</em></p> <p>To hook this up in your application grab this updated <code class="language-text">Trace</code> extension method using Serilog.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public static IObservable&lt;TSource&gt; Trace&lt;TSource&gt;(this IObservable&lt;TSource&gt; source, string name) { var id = 0; return Observable.Create&lt;TSource&gt;(observer =&gt; { var itemId = ++id; Action&lt;string, object&gt; trace = (m, v) =&gt; Log.Information(&quot;{name}{id}: {method}({value})&quot;, name, itemId, m, v); trace(&quot;Subscribe&quot;, null); IDisposable disposable = source.Subscribe( v =&gt; { trace(&quot;OnNext&quot;, v); observer.OnNext(v); }, e =&gt; { trace(&quot;OnError&quot;, e); observer.OnError(e); }, () =&gt; { trace(&quot;OnCompleted&quot;, null); observer.OnCompleted(); }); return () =&gt; { trace(&quot;Dispose&quot;, null); disposable.Dispose(); }; }); }</code></pre></div> <p>Next wire up the trace.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Observable .Interval(100).Trace(&quot;Interval&quot;) .Take(2).Trace(&quot;Take&quot;) .Count();</code></pre></div> <p>Then just register Seq with Serilog and log away.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Log.Logger = new LoggerConfiguration() .WriteTo.Seq(&quot;http://localhost:5341&quot;) .CreateLogger();</code></pre></div><![CDATA[Making great Octopus PowerShell step templates]]>https://daniellittle.dev/making-great-octopus-powershell-step-templateshttps://daniellittle.dev/making-great-octopus-powershell-step-templatesMon, 14 Jul 2014 07:52:44 GMT<p>Step templates, introduced in <a href="https://octopusdeploy.com/blog/2.4">Octopus Deploy 2.4</a>, are a great way to share and reuse useful PowerShell scripts.</p> <p>Anyone can make a step template and submit it via a pull request <a href="https://github.com/OctopusDeploy/Library">over at Github</a>. I've come up with a few tricks to make writing step templates easier.</p> <p>I wanted to make sure I could do a few things easily like testing the script outside of Octopus, handle errors as well as defaults and provide some structure around the layout of the script.</p> <p>The first thing I do is declare the parameters I want the script to have. Note the inclusion of the <code class="language-text">whatIf</code> switch parameter which makes it easy to test potentially dangerous scripts with a dry run.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">param( [string]$parameter1, [int]$parameter2, [switch]$whatIf )</code></pre></div> <p>By default PowerShell will attempt to continue to run a script after any errors so next I like to change that so an error will stop the script. <em>Note this is just for running outside Octopus, as Octopus also sets this for you.</em></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$ErrorActionPreference = &quot;Stop&quot;</code></pre></div> <p>Next I declare a helper function called <code class="language-text">Get-Param</code>. This function makes it much easier to run scripts outside Octopus by checking for an Octopus parameter and automatically falling back to use a variable. Additionally it also handles errors for required parameters and default values for optional ones.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">function Get-Param($Name, [switch]$Required, $Default) { $result = $null if ($OctopusParameters -ne $null) { $result = $OctopusParameters[$Name] } if ($result -eq $null) { $variable = Get-Variable $Name -EA SilentlyContinue if ($variable -ne $null) { $result = $variable.Value } } if ($result -eq $null) { if ($Required) { throw &quot;Missing parameter value $Name&quot; } else { $result = $Default } } return $result }</code></pre></div> <p>Following that you can then declare any other functions that you need.</p> <p>Finally, and most importantly is the main body of the script. It's executed last because of PowerShell requires you declare a function before you can use it. The body is a <a href="/self-executing-anonymous-function-in-powershell/">self executing anonymous function</a> similar to how you would do so in JavaScript. This lets you provide a child scope for the parameters and variables your script uses. Declaring the parameters here also ensures that the parameters have the correct types for both Octopus and script parameters.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&amp; { param( [string]$parameter1, [int]$parameter2 ) Write-Host &quot;Script Title&quot; Write-Host &quot;PrameterName1: $parameter1&quot; Write-Host &quot;PrameterName2: $parameter2&quot; # Main body of the script goes here! } ` (Get-Param &#39;parameter1&#39; -Required) ` (Get-Param &#39;parameter2&#39; -Default 10)</code></pre></div> <p>If you're wondering about the backticks, they allow the command to span multiple lines.</p> <p>Here's the whole script.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text"># Running outside octopus param( [string]$parameter, [switch]$whatIf ) $ErrorActionPreference = &quot;Stop&quot; function Get-Param($Name, [switch]$Required, $Default) { $result = $null if ($OctopusParameters -ne $null) { $result = $OctopusParameters[$Name] } if ($result -eq $null) { $variable = Get-Variable $Name -EA SilentlyContinue if ($variable -ne $null) { $result = $variable.Value } } if ($result -eq $null) { if ($Required) { throw &quot;Missing parameter value $Name&quot; } else { $result = $Default } } return $result } # More custom functions would go here &amp; { param( [string]$parameter ) Write-Host &quot;Script Title&quot; Write-Host &quot;PrameterName: $parameter&quot; # Main body of the script goes here! } ` (Get-Param &#39;parameter&#39; -Required)</code></pre></div><![CDATA[Powershell typeof]]>https://daniellittle.dev/powershell-typeofhttps://daniellittle.dev/powershell-typeofMon, 14 Jul 2014 07:00:16 GMT<p>Coming from C#, it provides the built in function <code class="language-text">typeof()</code> that you can use to get the <code class="language-text">Type</code> of a class. Powershell also makes it easy to get Type information.</p> <p>Wrapping the type in square brackets <code class="language-text">[TypeName]</code> evaluates to an instance of <code class="language-text">System.Reflection.TypeInfo</code>. Which you can then use to compare it as per normal.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">PS&gt;&quot;&quot;.GetType() -Eq [string] True PS&gt;(1).GetType() -Eq [int] True PS&gt;(1.0).GetType() -Eq [int] False</code></pre></div> <p>You can also assign the value to a variable if needed.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">PS&gt;$x = [bool] PS&gt;$x IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Boolean System.ValueType</code></pre></div> <p>I hope this will make it easier to find next time!</p><![CDATA[Octopus Deploy]]>https://daniellittle.dev/octopus-deployhttps://daniellittle.dev/octopus-deployTue, 27 May 2014 21:43:04 GMT<p>I'm happy to announce that I've joined forces with the amazing developers at Octopus Deploy. It's a fantastic product and if you havn't heard of them yet make sure you <a href="https://octopusdeploy.com/">take a look</a>.</p> <p>Deployments are such an important part of every project, yet they're often overlooked until the last minute. Even the best of us make mistakes and when we're under the pressure of a new deployment things can easily be rushed or forgotten. Often resulting in more deployments. Which is just one reason why automated deployments and Octopus Deploy is such an important part of my toolset.</p> <p>I think that all deployments should be automated. Once you start automating deployments, you can guarantee they're consistently fast and reliable. Automating deployments isn't just about making them faster either. It opens up possibilities that simply weren't there before.</p> <p>I'm glad I'll get to contribute some of my ideas in this space, and help make automated deployments a part of everyone's toolset.</p><![CDATA[An update on background tasks in ASP.NET]]>https://daniellittle.dev/an-update-on-background-tasks-in-asp-nethttps://daniellittle.dev/an-update-on-background-tasks-in-asp-netThu, 15 May 2014 10:16:12 GMT<p>There are two types of background tasks that you'd want to use in .NET. Long running tasks which include things like background services that run every 5, 10 minutes or another interval. Long running tasks could be continuously running, possibly spanning several days. Then there are Short lived tasks which are great for running smaller asynchronous tasks. Long running tasks are not supported in ASP.NET however short lived tasks have always been possible, and just got a little easier. </p> <p>But first, To recap on why long-running tasks are problematic. The main issue is that IIS is a request driven web server. Which means, if there's no one hitting your website nothing will happen. You could work around the problem as Phil Haack describes in his post <a href="https://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/#feedback">The Dangers of Implementing Recurring Background Tasks In ASP.NET</a> although you still need some kind of request to trigger the website. In the end, it's much better to just pull the background "Service" out of your website and run it as a Windows Service instead.</p> <p>On the other hand, ASP.NET provides much better support for reliable short lived tasks through <code class="language-text">HostingEnvironment.RegisterObject</code>. Using <code class="language-text">RegisterObject</code> lets you register objects in IIS so it can provide a warning when the App Domain is being shutdown. Letting you finish up your work and terminate these background threads gracefully. This is extremely useful when you need to run asynchronous tasks like sending a batch of emails on a separate thread. However, implementing this interface is tedious and overly complicated.</p> <p>In ASP.NET 4.5.2 this has become much easier with the introduction of <code class="language-text">HostingEnvironment.QueueBackgroundWorkItem</code> which provides a much simpler alternative. By making use of the Task library for .NET you can invoke a lambda as a short running task. Two overloads are provided for the function. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text"> 1. Action&lt;CancellationToken&gt; 2. Func&lt;CancellationToken, Task&gt;</code></pre></div> <p>These methods are both functionally equivalent, fire and forget async. The first simply takes an Action and executes it in the background. The second is exactly the same but returns a <code class="language-text">Task</code> which is required in order to use <code class="language-text">async</code> lambda's, like so.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text"> HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken =&gt; {     // Perform task });</code></pre></div> <p>Under the covers the QueueBackgroundWorkItem method still uses <code class="language-text">HostingEnvironment.RegisterObject</code> along with <code class="language-text">ThreadPool.QueueUserWorkItem</code> to execute the tasks. Meaning you'll still only get 30 seconds to finish what you were doing if cancellation is requested. Even so, this is still an addition that will be greatly appreciated.  </p><![CDATA[Implementing Domain Driven Design]]>https://daniellittle.dev/implementing-domain-driven-designhttps://daniellittle.dev/implementing-domain-driven-designMon, 28 Apr 2014 01:55:35 GMT<p>I've talked about <a href="https://lavinski.me/domain-driven-design/">what Domain Driven Design is</a> and what kind of benefits you can expect from it.</p> <p>The next concept to explore is what the implementation looks like. I'll be focusing on the architecture of such a system more than how to model a domain, which <a href="https://dddcommunity.org/book/evans_2003/">Eric Evans covers in his book</a>.</p> <p>The domain in DDD contains all the business logic in the application. Its equivalent in a layered system would be the domain/business layer. A typical domain implementation can be said to look like this:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 474px;" > <a class="gatsby-resp-image-link" href="/static/fc99c86b0ae156caefb964c67eb7f752/37e1f/Domain-Driven-Design-Concepts.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 64.13502109704642%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABFUlEQVQoz5WRiW6EMAxE+f8/JbuQg9x2kk4S1BYkVu0ossD4xWa8KKWEeGmtW2u1VsTyZy0hBCml1sZaG7xHJObPDDO3oSWlhOZSql3uxhghBDIY4YkEA3jOuBCRsxbMuq5qDN+eyYnh4YRzziEmqYzURhl7OH+4QKXy5TTEnuQyTfmBY+bXtq/i9X7v2hy4hWrleQZM3PnEeOA7nJGrzfqA6lIbTkwE+2ZDCEaiag58h1OmbdvgWTejNu/DKtYQ41yeVjt0etG7XGEi7KZ67/FLY8jSU31hvW1hypRBTiPvMDPZw2Bf+NrqucNR3H4JL6fPFxh3H8Y4Z0dNac+6w9jztKHf3TvXz/B37LD9p2CNcy4OfQHxffu1oE6meAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Domain Driven Design Concepts Diagram" title="Domain Driven Design Concepts Diagram" src="/static/fc99c86b0ae156caefb964c67eb7f752/37e1f/Domain-Driven-Design-Concepts.png" srcset="/static/fc99c86b0ae156caefb964c67eb7f752/064a4/Domain-Driven-Design-Concepts.png 225w, /static/fc99c86b0ae156caefb964c67eb7f752/44727/Domain-Driven-Design-Concepts.png 450w, /static/fc99c86b0ae156caefb964c67eb7f752/37e1f/Domain-Driven-Design-Concepts.png 474w" sizes="(max-width: 474px) 100vw, 474px" loading="lazy" /> </a> </span></p> <p>In Domain Driven Design there are three main types of objects the <code class="language-text">Aggregate Root</code>, <code class="language-text">Entities</code> and <code class="language-text">Value Objects</code>. These are objects in the typical object orientated sense and represent a concept from the domain/business. The other two concepts show are <code class="language-text">Aggregates</code> and <code class="language-text">Bounded Context</code>, which relate to the logical grouping of these domain objects.</p> <h3>Entities</h3> <p><code class="language-text">Entities</code> are a model of an object or concept in the domain and always have a distinct Id, usually a <code class="language-text">Guid</code>. An <code class="language-text">Entity</code> could be anything from such as a user, a product, or any other object. The <code class="language-text">Aggregate Root</code> shown is actually also an entity but it sits at the root of the hierarchy and has no direct references to it.</p> <p><code class="language-text">Entities</code> are a model of the business, but what does an <code class="language-text">Entity</code> actually look like? They are objects like, Product, Customer and Order which contain the behaviours (methods) of domain objects they are modeled after. These behaviours are owned by the <code class="language-text">Entities</code>, not stowed away in a manager or service. This also means that <code class="language-text">Entities</code> don't need to expose all those properties that services or managers would otherwise need. Instead, the state is encapsulated inside the object. <code class="language-text">Entities</code> are not <code class="language-text">Data Transfer Objects</code> and they should have very few, if any, properties. It also makes the behaviours discoverable, more expressive and more consistent as they are all local members of objects.</p> <p>Take the following two lines for example:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">company.Hire(newEmployee);</code></pre></div> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">companyService.Hire(company, newEmployee);</code></pre></div> <p>When <code class="language-text">Hire</code> is simply another behaviour of the company it becomes easy to find and clear to read.</p> <p>So if <code class="language-text">Entities</code> don't have any Properties how do you perform queries? The answer is; by using a read model not the domain model. The domain is primarily concerned with the business logic. It is only used to change the state of the domain. All queries are separated from the domain and instead a thin read layer is used. This is also known as Command and Query Responsibility Segregation or CQRS, which I'll talk about in a future post.</p> <p>Once entities have behaviours they sometimes need to use services or take other dependencies. However, an entity should never have any dependencies injected into it. Instead, it's better to make things explicit. It's actually the behaviours that have dependencies, not the <code class="language-text">Entities</code>. Therefore, when a service is needed, it can be provided as an argument in the method where it is used.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">user.ChangePassword(hashingService, newPassword);</code></pre></div> <p>In regards to validation in the domain, we can view it as just another aspect of the behaviour. Once the entities have behaviours it's quite straightforward to check the arguments are valid and invariants and are maintained. Then the entity itself can ensure it is never put into an invalid state. This also applies for any constructors, which really are just another behaviour.</p> <p>The final concern to address is persistence of the domain. The domain model should be persistence ignorant as it’s only concerned with the domain. Object relational mappers tend to make this more difficult although it is possible. However, I tend to use Domain Events to handle persistence and avoid ORMs altogether.</p> <h3>Values</h3> <p><code class="language-text">Values</code> on the other hand are just data and never have an Id. Their equality is determined as the sum of its parts. For example the value Position could contain Latitude and Longitude components. Two values where all the components are equal are also equal. For this reason <code class="language-text">Values</code> are usually also immutable.</p> <p>Now that I've explained <code class="language-text">Entities</code> and <code class="language-text">Values</code> I'll move up to <code class="language-text">Aggregates</code> and the <code class="language-text">Bounded Context</code>.</p> <h3>Aggregates</h3> <p>An <code class="language-text">Aggregate</code> is a boundary around one or more Entities. This boundary is also a transactional boundary. Such that all <code class="language-text">Entities</code> in one <code class="language-text">Aggregate</code> cannot directly reference <code class="language-text">Entities</code> in another. An <code class="language-text">Aggregate</code> would represent a single unit, for example a Tree. The aggregate is composed of the tree or trunk (the <code class="language-text">Aggregate Root</code>) and leaves (the other <code class="language-text">Entities</code>). <code class="language-text">Aggregates</code> are also the basic element of data storage, much like in a document database. You only save or load whole <code class="language-text">Aggregates</code>.</p> <p>I mentioned earlier that you cannot directly reference <code class="language-text">Entities</code> in another <code class="language-text">Aggregate</code>. Any references from outside the aggregate should only go to the aggregate root, as you cannot cross the <code class="language-text">Aggregate</code> boundary. Unlike references inside an <code class="language-text">Aggregate</code> that link directly to an instance. References to another <code class="language-text">Aggregate Root</code> will only use its identifier. This would also apply to circular references to the <code class="language-text">Aggregates</code> own <code class="language-text">Aggregate Root</code>.</p> <h3>Contexts</h3> <p>Context is extremely important in Domain Driven Design. An entity could logically exist in multiple <code class="language-text">Bounded Contexts</code> or even <code class="language-text">Aggregates</code> with different representations. As an Example, Human Resources sees a person as a resource with a different set of information and behaviours than Accountant would. In an online store items in a user’s cart could be different to items in their order, even though conceptually they're the same thing.</p> <p>Modeling one concept as multiple <code class="language-text">Entities</code> is more common in larger domain where it becomes much more difficult to find a single unified model. Especially when different groups of people need different things from the model.</p> <h3>Other Concepts</h3> <p>There are three other concepts I didn't fully cover here; Repositories, Domain Events and Services.</p> <p>Repositories are a very simple concept and simply load or save <code class="language-text">Aggregates</code>.</p> <p>I did briefly mention Domain Events; the basic premise here is that instead of an ORM implicitly tracking changes <code class="language-text">Events</code> are used to describe what changes happened.</p> <p>The concept of <a href="https://stackoverflow.com/questions/2268699/domain-driven-design-domain-service-application-service">services</a> which could be application, domain or infrastructure services.</p> <h3>In Conculsion</h3> <p>These are the core concepts of a Domain Driven Design implementation. The design of the domain model is built around the concepts of <code class="language-text">Aggregates</code> and <code class="language-text">Entities</code>. Modelling a domain in this way is results in code that is much more expressive, clear and cohesive.</p><![CDATA[Internet Explorer Won't Save Cookies On Domains With Underscores In Them.]]>https://daniellittle.dev/internet-explorer-wont-save-cookies-on-domains-with-underscores-in-themhttps://daniellittle.dev/internet-explorer-wont-save-cookies-on-domains-with-underscores-in-themTue, 15 Apr 2014 23:41:23 GMT<p>All versions of Internet Explorer (version 5.5 all the way to version 11) will discard all cookies if the domain has an underscore in it. This can lead to the following issues, which can be quite difficult to debug:</p> <ul> <li>Cookies are not set on the client system.</li> <li>ASP.NET Session variables are lost.</li> </ul> <p>When debugging web applications I can't recommend <a href="https://www.telerik.com/fiddler">Fiddler</a> enough. It will be able to pick up these kinds of issues and in this case provides the following warning.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">!! WARNING !!: Server hostname contains an underscore and this response sets a cookie. Internet Explorer does not permit cookies to be set on hostnames containing underscores. See https://support.microsoft.com/kb/316112.</code></pre></div> <p>It's perfectly legal for a domain to have an underscore in it, so this issue goes against the standard (See <a href="https://www.ietf.org/rfc/rfc1034.txt">RFC 2181</a>, section 11, "Name syntax"). Part of the reason it is hard to debug is that the domain will work fine in all other browsers.</p> <p>The support article has the following to say about the issue:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">PRB: Session Variables Do Not Persist Between Requests After You Install Internet Explorer Security Patch MS01-055 A potential security vulnerability exists in Internet Explorer versions 5.5 and 6.0 in which a malicious user could create a URL that allows a Web site to gain unauthorized access to cookies that are stored on a client computer and then (potentially) modify the values that are contained in these cookies. Because some Web sites use cookies that are stored on client computers to store sensitive information, this security vulnerability could expose personal information.</code></pre></div> <p>So this issue is caused to prevent a security issue on a deprecated version of Internet Explorer. I think it's about time this restriction was removed.</p> <p>You can vote to fix this issue at <a href="https://connect.microsoft.com/IE/feedback/details/853796/internet-explorer-wont-save-cookies-on-domains-with-underscores-in-them">Microsoft Connect</a>.</p><![CDATA[Self executing anonymous function in Powershell]]>https://daniellittle.dev/self-executing-anonymous-function-in-powershellhttps://daniellittle.dev/self-executing-anonymous-function-in-powershellFri, 11 Apr 2014 02:40:27 GMT<p>One of the great features of JavaScript is the self-executing anonymous function. It's extremely useful because you can avoid polluting the global scope and express your dependencies in an explicit manner.</p> <p>PowerShell lets you do something similar by taking advantage of <code class="language-text">blocks</code>, the <code class="language-text">param</code> keyword and the call operator <code class="language-text">&amp;</code>.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&amp; { param($msg) Write-Host $msg } &quot;Hello World&quot;</code></pre></div> <p>This function will be automatically invoked with the string <code class="language-text">&quot;Hello World&quot;</code>.</p><![CDATA[Ninject Modules]]>https://daniellittle.dev/ninject-moduleshttps://daniellittle.dev/ninject-modulesFri, 04 Apr 2014 21:08:50 GMT<p><a href="https://github.com/ninject/ninject/wiki/Dependency-Injection-With-Ninject">Ninject</a> is a fantastic Dependency Injection framework for the .NET framework. You can bind to the kernel whenever you want however you usually want to setup all your binding in once place right, at the start of your application. Ninject provides the perfect place to declare all you bindings in a single place in the form of a <code class="language-text">NinjectModule</code>.</p> <p>To create a Kernel using a Module it is passed as a constructor parameter.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var kernel = new StandardKernel(new ApplicationBindingsModule());</code></pre></div> <p>Then you can simply declare the Module which requires you to implement the abstract <code class="language-text">Load</code> method.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public class ApplicationBindingsModule : NinjectModule { public override void Load() { Bind&lt;IClock&gt;().To&lt;Clock&gt;().InSingletonScope(); // If you use Ninject.Extensions.Convention you have to use `this` to use the extension method syntax. //this.Bind(x =&gt; x.FromThisAssembly()... } }</code></pre></div> <p>Using Modules allows you to easily swap out bindings when creating a Kernel and provides a standard location for all your bindings.</p><![CDATA[What is Domain Driven Design?]]>https://daniellittle.dev/domain-driven-designhttps://daniellittle.dev/domain-driven-designMon, 31 Mar 2014 08:57:51 GMT<p>In 2004, Erick Evans coined the term Domain Driven Design in his book also called <a href="https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215">Domain Driven Design</a>.</p> <p>Since then there has been lots of talk about using Domain Driven Design to tackle high complexity business problems, but what about everyday development. Just like all software there are tradeoffs. The difference between projects not complex enough for Domain Driven Design and projects that are is not discrete and is entirely superficial; the domain itself is much more important. I'm hoping I can look at some key ideas presented in the Domain Driven Design space and see how they apply to everyday software.</p> <p>Traditionally when we set out to design a system we'd start by looking at the database. Relational databases have been so ingrained into us that it's become the only way that we have thought about our applications. We'd model our systems after the tables and their columns. As a result, the business logic was spread between all kinds of manager objects and in the heads of the users.</p> <p>The focus of Domain Driven Design is to <a href="https://martinfowler.com/bliki/UbiquitousLanguage.html">develop a consistent language</a> that describes both entities and their <em>behaviours</em> in the domain. Identifying and modelling the behaviours, instead of properties and data, makes the system self describing allowing us to clearly see the business requirements. This is fantastic for the developers as it becomes much easer to see intent. The second thing it provides developers is the ability to use encapsulation instead of exposing all their data via properties. I'll explain why this leads to better software in a later post. On the business side it enables developers and the domain experts to share the same understanding of the domain and communicate effectively. This is very valuable because changing business requirements map very easily back into the application.</p> <p>Domain Driven Design has the potential to provide many benefits to business and to developers. If your software is the driving force in your business, Domain Driven Design is definitely worth looking into.</p><![CDATA[Why use NuGet]]>https://daniellittle.dev/why-use-nugethttps://daniellittle.dev/why-use-nugetSat, 22 Mar 2014 03:04:31 GMT<p>I've had a few people ask me why they should use NuGet and the occasional person that's never heard of it. If you are currently developing software without a package manager, here is why you should be interested.</p> <h2>What is NuGet?</h2> <p><a href="https://www.nuget.org/">NuGet</a> is the official package manager for .NET managed by the <a href="https://www.outercurve.org/">Outercurve Foundation</a>.</p> <p>But firstly what is a package manager?</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">In software, a package management system, also called package manager, is a collection of software tools to automate the process of installing, upgrading, configuring, and removing software packages.</code></pre></div> <p>A typical NuGet Package consists simply of a metadata file and some <code class="language-text">dll</code> files for the supported .NET versions.</p> <div style="width: 200px"> ![Package structure](https://pfcjjq.dm2302.livefilestore.com/y2pCBjkRcauQ0pM0ZHiJea7P_cFZgdGtfN6PqYQNV5ldF7nphagBs5D_TNrlGoctoObNNSvNZ_qj82nD3EhJ-LAW4TebxfVtb5GC0_eEYGf7fM/NuGet.png) </div> <p>These packages don't just have to contain dlls, they can also contain content such as JavaScript libraries and other text files.</p> <h2>I've never needed NuGet before, what's wrong with just referencing them directly like it's always been?</h2> <p>Let’s say you just started working on a new project. You want to use a library to help you out. It could be an SQL Generation library to help write a dynamic report viewer.</p> <p>So you search around for a library and find a one you're happy with. Next you locate and download the binaries for the library and copy them to your project. Now you can reference them from Visual Studio and start work.</p> <p>The next thing you'll need to worry about is updating that library. If you run into a bug and or want to update the project to get the latest updates or features you have to go through most of the download process again. You'll also never be able to tell if there's an update ready without going to their website.</p> <p>The worst part is you have to do this for every library you want to use. This is a lot of work.</p> <p>It gets even worse if that library happened to depend on another project, such as logger, which you or any other projects might also want to depend on.</p> <h2>How does NuGet make it easier for me?</h2> <p>NuGet can provide consistency, every library you need can be added with just one click. All configuration you need is automatic and any dependencies are automatic added as well.</p> <p><img src="https://plcceq.dm2302.livefilestore.com/y2pzM2P0BBh5gNBIpVJ8B1HICQ7yvbJOVg35sT30cEwzU-IDtAARn2cBdlRzxPvBq192Qd-D4ACNei9ldB-bLdJe51Q1aKBEDj5mIIECE38jUo/NuGet_Window.png?psid=1" alt="Package Manager"></p> <p>Every library you have can be updated with one command. With each package automatically updated to the correct version taking into account each package that depends on it.</p> <h2>Is NuGet perfect?</h2> <p>Nothing is without flaws and NuGet is no exception. NuGet is community driven and while this is great it also means packages, just like libraries, are only as good as their creators.</p> <p>It's also leaky abstraction, which just means you still need to know how assemblies work and get referenced.</p> <h2>Who is actually using it?</h2> <p>The .NET framework team itself <a href="https://blogs.msdn.com/b/dotnet/archive/2013/10/16/nuget-is-a-net-framework-release-vehicle.aspx">has been adopting NuGet</a> as the primary method of delivery over the last few years. The ASP.NET and EntityFramework teams have been leading that trend. The core .NET team started using NuGet in 2012 and have now been releasing parts of the <code class="language-text">Base Class Library</code> with NuGet.</p> <p>Along with a community including thousands of projects NuGet has become the standard method of delivering and using .NET libraries.</p> <h2>How do I get started?</h2> <p>Once you open Visual Studio and create a new project you're already using NuGet.</p> <p>To check out the packages you're using and to add new ones select <code class="language-text">Manage NuGet Packages...</code> from the References menu.</p> <p><img src="https://qfcceq.dm2304.livefilestore.com/y2pmX8RSm6h-KYvyAvxeysD9vrM8suDBMBkNJ6ney-svPuGxDL_9bdtBh84BXh9z-bAJacCUthnj6OvMcdBY4Lp_PxLMLfG8YlJSCDkKls4AlM/NuGet_Open.png?psid=1" alt="Package Manager"></p> <p>From here you can browse through and install the great range of available packages.</p> <p>NuGet allows people to share and take advantage of numerous fantastic projects. Allowing the .NET community to innovate and deliver at an accelerated rate. So next time you're looking for a great library, check NuGet first.</p><![CDATA[What's in a Buzzword]]>https://daniellittle.dev/whats-in-a-buzzwordhttps://daniellittle.dev/whats-in-a-buzzwordFri, 14 Mar 2014 11:08:12 GMT<p>It's sometimes tempting to dismiss things as the next Fad or Buzzword. There's never enough time to learn everything and some things are genuinely bad but if you get into the habit of dismissing everything you're also going to miss a lot of good things.</p> <p>Next time you see a new name or word that's buzzing, take the time to investigate what it's about and make your own choices. Names help us to convey our ideas. Terms like <code class="language-text">Domain Driven Design</code> and <a href="https://martinfowler.com/articles/microservices.html"><code class="language-text">Microservices</code></a> hold with them a host of <a href="https://blog.8thlight.com/craig-demyanovich/2014/07/09/pattern-language-of-thieves.html">implicit knowledge</a>. Wrapping up a bunch of existing concepts and providing it to us a concise whole.</p> <p>Don't feel bad because you don't know a word, everyone has to say <a href="https://blog.42floors.com/i-dont-know/">i don't know</a> every once in a while.</p> <p>So next time you see a new library, pattern or architecture take a deeper look. Who knows, you might just learn something.</p><![CDATA[OWIN and System.Web.Optimizations]]>https://daniellittle.dev/post-posthttps://daniellittle.dev/post-postSat, 01 Feb 2014 05:37:07 GMT<p>I struck out to see if I could make use of the Microsoft ASP.NET Web Optimization Framework (version 1.1.2) in my self hosted OWIN Nancy application.</p> <p>The only real resource I could find on the topic was the page <a href="https://github.com/NancyFx/Nancy/wiki/How-to-use-System.Web.Optimization-Bundling-with-Nancy">How to use System.Web.Optimization Bundling with Nancy</a> in the Nancy wiki on GitHub. Which looked good at first sight untill I looked a little deeper. This page is not only wildly out of date but didn't even get me close to a working solution.</p> <p>The System.Web.Optimization project unfortunately has a large dependency on System.Web. Which for all practicle purposes makes it unusable when using Microsoft.Owin.Hosting.</p> <p>While might still be possible to get it working without IIS by replacing the <code class="language-text">BundleHandler</code>, providing a <code class="language-text">HttpContext</code> and emulating a virtual directory for the app domain. Which would look something like the this...</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var domain = Thread.GetDomain(); domain.SetData(&quot;.appDomain&quot;, &quot;&quot;); domain.SetData(&quot;.appVPath&quot;, &quot;/&quot;); domain.SetData(&quot;.appPath&quot;, &quot;/&quot;); domain.SetData(&quot;.appId&quot;, &quot;&quot;);</code></pre></div> <p>I think I'll just wait for some official OWIN support and see how <a href="https://getcassette.net/">Cassette</a> goes in the meantime.</p><![CDATA[Git - When to Merge]]>https://daniellittle.dev/git-when-to-mergehttps://daniellittle.dev/git-when-to-mergeThu, 12 Sep 2013 01:00:00 GMT<p>Many people use git pull and merge frequently in an effort to keep a branch up to date while working a feature. However it's actually recommended not to merge into a feature branch until it's complete and ready to be integrated back into the development branch. </p> <p>The reason for this is that merge is a is a semantic action and actually has additional meaning than just update this branch. For example a feature branch should only be concerned with adding a single feature to a point in time. This makes development easier, you don't want the system changing around you as you develop a feature. Merge does a great job at integrating branches when they're ready (As long as you're project isn't completely different [if it is you have bigger problems]). It also lets you become more flexible, branches can merge with other branches or features without getting changes they're not interested in.</p> <p>It's also good to remember if you just want to sync with a remote such as the origin you can use fetch which avoids the implicit merge of pull.</p><![CDATA[TechEd Australia 2013]]>https://daniellittle.dev/teched-at-2013https://daniellittle.dev/teched-at-2013Wed, 04 Sep 2013 01:00:00 GMT<p>The first day at TechEd offered two main sessions the developer kick off and the Keynote. The developer kick off touched on a new Visual Studio 2013 feature called Browser Link for ASP.NET and Team Foundation Service.</p> <p>The kick off started by introducing One ASP.NET which is the unification of all web related .NET technologies, frameworks and libraries like MVC, SignalR and Web Forms can be mixed and matched however you like and all fall under the one ASP.NET umbrella. There has been a range of improvement to intellisense across the board particularly in html and CSS editors. The main highlight was the introduction to Browser Link by the creator of Web Essentials for Visual Studio.</p> <p>Brower link enables a persistent link from Visual Studio to whatever web browser you use. It enables a few interesting scenarios the first of which being changes made to CSS are instantly reflected in all the browsers connected by Browser Link. Edits to razor files require a little more than a save (one key combo) because behind the scenes you're telling each connected browser to refresh the page but you neve have to leave Visual Studio. Imagine you're trying to iron out a few CSS quirks across two or more browsers. You can have two browsers open at the same time and CSS changes appear instantly on both browsers as soon as you save the file making comparisons efficient and easy.</p> <p>Browser link also lets you do the inverse, you can use the web browser to jump to the exact line in your razor template that an element corresponds to via the inspector (Ctrl-Alt-I). You can also go one step further, ctrl-alt-d enables edit mode which can let you do thinks link edit html or Action Links and other <code class="language-text">Html</code> helpers which are updated in real time and this all works in any browser.</p> <p>The next session introduced Team Foundation Service which has a set of features coming to the next version of Team Foundation Server. There are a few interesting features including git support, a free tier for up to 5 users, a scrum style backlog and Trello-esk cards. Also notably was the addition of an integrated persistent chat room through which you can share news and chat with other members but also see general activity in the project such as build and code review events.</p> <p>The primary keynote had a few speakers, the main talk was from the CEO of Yammer. This was the one of the best talks I've seen and it talked about organisations and change. The theme was Blink and you'll miss it. The rate at which technology is changing is happening so fast that it's becoming even more important for people and organisations to be able to learn and react faster. If you wait too long it's already irrelevant. This means instead of long release cycles where failure means 2-3 years of work goes down the drain, moving to pushing updates every month. This means the cost of failure is much smaller as well. What's worse changing one month of work or one year's worth. This is so important for organisations and this quote by Jack Welch describes it perfectly.</p> <p>"If the rate of change on the outside exceeds the rate of change on the inside, the end is near."</p> <p>There have been an increasing number of disruptive changes happening in the last 5 or so years. Communication has enabled modern society to move ideas and information much faster than ever before. The problem we see in companies these days is that people inside organisations don't communicate very well, especially across departments. The outside world is moving so fast because it's a network of self motivated people and we need to bring that into our companies and organisations. These types of organisations are called Responsive Organisations and you can read more about what it means to be one at <a href="https://www.theresponsiveorg.com/manifesto">https://www.theresponsiveorg.com/manifesto</a>.</p><![CDATA[John Carmack Keynote]]>https://daniellittle.dev/john-carmack-keynotehttps://daniellittle.dev/john-carmack-keynoteSat, 03 Aug 2013 01:00:00 GMT<p>John Carmack's keynote this year was a fantastic talk about software engineering. Parts <a href="https://www.youtube.com/watch?v=93GwwNLEBFg">three</a> and <a href="https://www.youtube.com/watch?v=1PhArSujR_A">four</a> of the keynote touched on all the key hot topics including Code Quality, Functional Programming, Static Typing vs Dynamic Typing, Static Analysis and Garbage Collection. Defiantly worth watching if you're into professional development, and if not it's still worth watching.</p><![CDATA[My PowerShell Profile]]>https://daniellittle.dev/my-powershell-profilehttps://daniellittle.dev/my-powershell-profileWed, 03 Jul 2013 01:00:00 GMT<p>This is my PowerShell profile, it does a few nice things such as add <code class="language-text">open</code> and <code class="language-text">edit</code> commands to the shell. Most importantly though it customizes my prompt to shorten it while still showing how deep I am in the directory hierarchy. I've also set up <code class="language-text">poshgit</code> as well as a few other helpers and functions.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">function Open($path) { explorer $path } function Edit { [CmdletBinding()] Param( [Parameter(Mandatory = $False, ValueFromPipeline = $True, ValueFromRemainingArguments = $True, Position = 0)] $File ) Process { $app = &quot;C:\Program Files (x86)\Notepad++\notepad++.exe&quot; if ($File -ne $null) { $parameters = &#39;&quot;&#39; + $File + &#39;&quot;&#39; $options = New-Object &quot;System.Diagnostics.ProcessStartInfo&quot; $options.FileName = $app $options.Arguments = $parameters $options.WorkingDirectory = $pwd $temp = [Diagnostics.Process]::Start($options).WaitForInputIdle(500) } Invoke-Item $app } } # This was already here function elevate-process { $file, [string]$arguments = $args; $psi = new-object System.Diagnostics.ProcessStartInfo $file; $psi.Arguments = $arguments; $psi.Verb = &quot;runas&quot;; $psi.WorkingDirectory = get-location; [System.Diagnostics.Process]::Start($psi); } set-alias sudo elevate-process; # WebGet function get-html([string]$url) { $webClient = (New-Object System.Net.WebClient); $webClient.DownloadString($url); } function shorten-path([string] $path) { $loc = $path.Replace($HOME, &#39;~&#39;) # remove prefix for UNC paths $loc = $loc -replace &#39;^[^:]+::&#39;, &#39;&#39; # make path shorter like tabs in Vim, # handle paths starting with \\ and . correctly return ($loc -replace &#39;\\(\.?)([^\\])[^\\]*(?=\\)&#39;,&#39;\$1$2&#39;) } function prompt { # our theme $cdelim = [ConsoleColor]::DarkCyan $chost = [ConsoleColor]::Green $cloc = [ConsoleColor]::Cyan $default = [ConsoleColor]::White # Reset color, which can be messed up by Enable-GitColors $Host.UI.RawUI.ForegroundColor = $default write-host (shorten-path (pwd).Path) &quot;&quot; -n -f $cloc Write-VcsStatus return &#39;&gt; &#39; } # gci . *.cs -Recurse | select-string . | Group Filename | Measure-Object Count -Min -Max -Average function CountLines($directory) { $pattern = &quot;*.cs&quot; $directories = [System.IO.Directory]::GetDirectories($directory) $files = [System.IO.Directory]::GetFiles($directory, $pattern) $lineCount = 0 foreach($file in $files) { $lineCount += [System.IO.File]::ReadAllText($file).Split(&quot;`n&quot;).Count } foreach($subdirectory in $directories) { $lineCount += CountLines $subdirectory } $lineCount } $msbuildPath = &quot;C:\Windows\Microsoft.NET\Framework\v4.0.30319\&quot; $gitPath = (Get-Item &quot;Env:LocalAppData&quot;).Value + &quot;\GitHub\PortableGit_93e8418133eb85e81a81e5e19c272776524496c6\cmd\&quot; $env:path += &quot;;$gitPath;$msbuildPath;&quot; function Enable-Git { . &#39;C:\Users\me\Documents\WindowsPowerShell\Modules\posh-git\profile.example.ps1&#39; } #Write-Host &quot;For git use &#39;Enable-Git&#39;&quot; function Load-Profile { . $Profile } function Edit-Profile { edit &quot;C:\Users\me\Documents\WindowsPowerShell\Profile.ps1&quot; } function Git-Log([switch]$OneLine, $Length) { $Length = 1000; if ($OneLine) { git log --pretty=oneline -n $Length } else { git log -n $Length } }</code></pre></div><![CDATA[Testing emails in .NET]]>https://daniellittle.dev/testing-emails-with-smtp4devhttps://daniellittle.dev/testing-emails-with-smtp4devMon, 29 Apr 2013 01:00:00 GMT<p>Testing emails can sometimes be a bit challenging. <a href="https://smtp4dev.codeplex.com/">smtp4dev </a>is a small program that intercepts all received emails so you can quickly send and view emails from any application that uses it as the SMTP server.</p> <p>For a .NET application just add this to the config file.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&lt;mailSettings&gt; &lt;smtp&gt; &lt;network host=&quot;localhost&quot;/&gt; &lt;/smtp&gt; &lt;/mailSettings&gt;</code></pre></div> <p>Now all emails that the application sends will appear for your viewing pleasure in the email list (pictured below).</p> <p><img src="https://media.tumblr.com/ae0bed5688e8d01ea2d03a68430b17cf/tumblr_inline_mm04feyvwV1qz4rgp.png"></p><![CDATA[Loading Settings From web.config]]>https://daniellittle.dev/loading-settings-dotnethttps://daniellittle.dev/loading-settings-dotnetSat, 20 Apr 2013 01:00:00 GMT<p>It's always a good idea to be as consistent as possible when you're writing code. So when you're using settings from a configuration file it's a good idea to avoid sprinkling <code class="language-text">ConfigurationManager.AppSettings[&quot;MySetting&quot;]</code> around the codebase, especially if you've making multiple calls to it.</p> <p>A great way to provide consistency and to remove this duplication is to create a settings class either one static global one or multiple instance classes which I'll then manage with dependency injection. Then I load all the settings from configuration into that class on start up.</p> <p>I've also written a little library that makes use of reflection to make this even easier.</p> <p>Once my settings are in my config file</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt; &lt;configuration&gt; &lt;appSettings&gt; &lt;add key=&quot;Domain&quot; value=&quot;example.com&quot; /&gt; &lt;add key=&quot;PagingSize&quot; value=&quot;30&quot; /&gt; &lt;add key=&quot;Invalid.C#.Identifier&quot; value=&quot;test&quot; /&gt; &lt;/appSettings&gt; &lt;/configuration&gt;</code></pre></div> <p>I make a static or instance class depending on my needs. For simple applications with only a few settings one static class is fine.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">private static class Settings { public string Domain { get; set; } public int PagingSize { get; set; } [Named(&quot;Invalid.C#.Identifier&quot;)] public string ICID { get; set; } }</code></pre></div> <p>Then using my library call either <code class="language-text">Inflate.Static</code> or <code class="language-text">Inflate.Instance</code> and the cool thing is I can use any key value source.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">using Fire.Configuration; Inflate.Static( typeof(Settings), x =&gt; ConfigurationManager.AppSettings[x] ); var settings = new SpecificSettings(); Inflate.Instance( settings, x =&gt; ConfigurationManager.AppSettings[x] );</code></pre></div> <p>All the code for this is in bitbucket at <a href="https://bitbucket.org/Lavinski/fire">https://bitbucket.org/Lavinski/fire</a></p> <p>There is even a nuget package <a href="https://nuget.org/packages/Fire/">https://nuget.org/packages/Fire/</a></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Install-Package Fire</code></pre></div><![CDATA[Wildcards hostname in your hosts file]]>https://daniellittle.dev/wildcard-hostnameshttps://daniellittle.dev/wildcard-hostnamesWed, 10 Apr 2013 01:00:00 GMT<p>If you've ever wanted to setup a wildcard entry in your hosts file so you don't have to add an entry for every IIS binding you'll be happy to know there is a way.</p> <p>The trick however is not to use the hosts file but a local DNS proxy instead. <a href="https://mayakron.altervista.org/wikibase/show.php?id=AcrylicHome">Acrylic DNS</a> is a free and open source which you can download <a href="https://mayakron.altervista.org/wikibase/show.php?id=AcrylicHome">here</a>. You use it in much the same way you would use a hosts file.</p> <p>Stackoverflow has a great answer detailing how to set it up:</p> <h3><a href="https://stackoverflow.com/posts/9695861/edit">Configuring Acrylic DNS Proxy</a></h3> <p><strong>To configure Acrylic DNS Proxy, install it from the above link then go to:</strong></p> <ol> <li>Start</li> <li>Programs</li> <li>Acrilic DNS Proxy</li> <li>Config</li> <li>Edit Custom Hosts File</li> </ol> <p><strong>Add the folowing lines on the end of the file:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">127.0.0.1 *.localhost 127.0.0.1 *.local</code></pre></div> <p><strong>Restart the Acrilic DNS Proxy service:</strong></p> <ol> <li>Start</li> <li>Programs</li> <li>Acrilic DNS Proxy</li> <li>Config</li> <li>Restart Acrilic Service</li> </ol> <p><strong>You will also need to adjust your DNS setting in you network interface settings:</strong></p> <ol> <li>Start</li> <li>Control Panel</li> <li>Network and Internet</li> <li>Network Connections</li> <li>Local Area Connection Properties</li> <li>TCP/IPv4</li> </ol> <p><strong>Set "Use the following DNS server address":</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Preferred DNS Server: 127.0.0.1</code></pre></div><![CDATA[Multiple https bindings in IIS7 for developers]]>https://daniellittle.dev/iis-multi-https-bindingshttps://daniellittle.dev/iis-multi-https-bindingsWed, 20 Mar 2013 02:00:00 GMT<p>When working with websites that require https (SSL) developers always ending up facing the problem: <strong>Why can't you use hostnames with https</strong>. This is because hostname is encrypted so IIS needs to establish the SSL connection before it can even read the hostname.</p> <p>However we can get around this problem by making use of a wildcard certificate. Then it won't matter what the hostname is and we can happily use SSL on all our internal dev sites.</p> <p>You can't actually use IIS to setup a wildcard certificate so I'll be using a bit of Powershell to move things along.</p> <p>The first step is to create the self signed certificate. Any clients will also have to trust this certificate.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$cert = New-SelfSignedCertificate -DnsName &quot;*.company.internal&quot; -CertStoreLocation cert:\LocalMachine\My Export-Certificate -Cert $cert -FilePath &quot;company.internal.cer&quot; $password = ConvertTo-SecureString -String &quot;SecretHeHe&quot; -Force –AsPlainText Export-PfxCertificate -Cert $cert -FilePath &quot;company.internal.pfx&quot; -Password $password</code></pre></div> <p>Next add the bindings to IIS, this script will add a http and https binding for each combination of site and environment.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$sites = @( &quot;website&quot; ) $envs = @( &quot;test&quot;, &quot;stage&quot; ) Import-Module WebAdministration foreach ($name in $sites) { foreach ($env in $envs) { $name = &quot;$name ($env)&quot; $siteName = &quot;$name ($env)&quot; New-WebBinding -Name $siteName -Port 80 -Protocol http -HostHeader &quot;$env.$name.company.internal&quot; New-WebBinding -Name $siteName -Port 443 -Protocol https -HostHeader &quot;$env.$name.company.internal&quot; } }</code></pre></div> <p>Just one thing left, setup IIS to use the certificate. To do that open IIS and import the certificate. Then select the open one of the https bindings and select the certificate (it won't matter which one, any site on that port will use it).</p><![CDATA[Properties Visual Studio passes to MSBuild]]>https://daniellittle.dev/visual-studio-msbuildhttps://daniellittle.dev/visual-studio-msbuildFri, 08 Mar 2013 02:00:00 GMT<p>It always takes me ages to kind what properties Visual Studio makes available to the MSBuild project files so here's the full set.</p> <pre style="max-height: 300px"> $(RemoteMachine) Set to the value of the Remote Machine property on the Debug property page. See Changing Project Settings for a C/C++ Debug Configuration for more information. $(Configuration) The name of the current project configuration (for example, "Debug"). $(Platform) The name of current project platform (for example, "Win32"). $(ParentName) (Deprecated.) Name of the item containing this project item. This will be the parent folder name, or project name. $(RootNameSpace) The namespace, if any, containing the application. $(IntDir) Path to the directory specified for intermediate files relative to the project directory. This path should have a trailing slash. This resolves to the value for the Intermediate Directory property. $(OutDir) Path to the output file directory, relative to the project directory. This path should have a trailing slash. This resolves to the value for the Output Directory property. $(DevEnvDir) The installation directory of Visual Studio 2010 (defined as drive + path); includes the trailing backslash '\'. $(InputDir) (Deprecated; migrated.) The directory of the input file (defined as drive + path); includes the trailing backslash '\'. If the project is the input, then this macro is equivalent to $(ProjectDir). $(InputPath) (Deprecated; migrated.) The absolute path name of the input file (defined as drive + path + base name + file extension). If the project is the input, then this macro is equivalent to $(ProjectPath). $(InputName) (Deprecated; migrated.) The base name of the input file. If the project is the input, then this macro is equivalent to $(ProjectName). $(InputFileName) (Deprecated; migrated.) The file name of the input file (defined as base name + file extension). If the project is the input, then this macro is equivalent to $(ProjectFileName). $(InputExt) (Deprecated; migrated.) The file extension of the input file. It includes the '.' before the file extension. If the project is the input, then this macro is equivalent to $(ProjectExt). $(ProjectDir) The directory of the project (defined as drive + path); includes the trailing backslash '\'. $(ProjectPath) The absolute path name of the project (defined as drive + path + base name + file extension). $(ProjectName) The base name of the project. $(ProjectFileName) The file name of the project (defined as base name + file extension). $(ProjectExt) The file extension of the project. It includes the '.' before the file extension. $(SolutionDir) The directory of the solution (defined as drive + path); includes the trailing backslash '\'. $(SolutionPath) The absolute path name of the solution (defined as drive + path + base name + file extension). $(SolutionName) The base name of the solution. $(SolutionFileName) The file name of the solution (defined as base name + file extension). $(SolutionExt) The file extension of the solution. It includes the '.' before the file extension. $(TargetDir) The directory of the primary output file for the build (defined as drive + path); includes the trailing backslash '\'. $(TargetPath) The absolute path name of the primary output file for the build (defined as drive + path + base name + file extension). $(TargetName) The base name of the primary output file for the build. $(TargetFileName) The file name of the primary output file for the build (defined as base name + file extension). $(TargetExt) The file extension of the primary output file for the build. It includes the '.' before the file extension. $(VSInstallDir) The directory into which you installed Visual Studio 2010. This property contains the version of the targeted Visual Studio, which might be different that the host Visual Studio. For example, when building with $(PlatformToolset) = v90, $(VSInstallDir) contains the path to the Visual Studio 2008 installation. $(VCInstallDir) The directory into which you installed Visual C++ 2010. This property contains the version of the targeted Visual C++, which might be different that the host Visual Studio. For example, when building with $(PlatformToolset) = v90, $(VCInstallDir) contains the path to the Visual C++ 2008 installation. $(FrameworkDir) The directory into which the .NET Framework was installed. $(FrameworkVersion) The version of the .NET Framework used by Visual Studio. Combined with $(FrameworkDir), the full path to the version of the .NET Framework use by Visual Studio. $(FrameworkSDKDir) The directory into which you installed the .NET Framework. The .NET Framework could have been installed as part of Visual Studio 2010 or separately. $(WebDeployPath) The relative path from the web deployment root to where the project outputs belong. Returns the same value as RelativePath. $(WebDeployRoot) The absolute path to the location of <localhost>. For example, c:\inetpub\wwwroot. $(SafeParentName) (Deprecated.) The name of the immediate parent in valid name format. For example, a form is the parent of a .resx file. $(SafeInputName) (Deprecated.) The name of the file as a valid class name, minus file extension. $(SafeRootNamespace) (Deprecated.) The namespace name in which the project wizards will add code. This namespace name will only contain characters that would be permitted in a valid C++ identifier. $(FxCopDir) The path to the fxcop.cmd file. The fxcop.cmd file is not installed with all Visual C++ editions. </pre> <p>Source: <a href="https://msdn.microsoft.com/en-us/library/c02as0cs.aspx">https://msdn.microsoft.com/en-us/library/c02as0cs.aspx</a></p><![CDATA[Switch from 'Entity Framework Linq' to 'Linq to Objects' with AsEnumerable]]>https://daniellittle.dev/ef-linq-as-emumerablehttps://daniellittle.dev/ef-linq-as-emumerableThu, 14 Feb 2013 02:00:00 GMT<p>Most people know what when writing a Linq query with Entity Framework that until that query is enumerated it won't call out to the database. Sometimes it's necessary to do some more work with the results such as use a method as part of the projection. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var result = from people in Context.People where people.DateOfBirth &lt; twentyYearsAgo select people; function GetAge(DateTime dateOfBirth) { ...</code></pre></div> <p>This is where <code class="language-text">AsEnumerable</code> comes in. This generic function allows you to switch from the <code class="language-text">IQueryable</code> source to <code class="language-text">IEnumerable</code> which will use Linq to Objects. Using AsEnumerable instead of <code class="language-text">ToList</code> allows us to still delay the execution of the query until it's needed.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var query = from people in Context.People where people.DateOfBirth &lt; twentyYearsAgo select people; var result = from people in query.AsEnumerable() select GetAge(people.DateOfBirth);</code></pre></div> <p>You could do the same thing by casting to the IEnumerable type but for anonymous objects you'll find you need to use AsEnumerable anyway to infer the type from the query.</p><![CDATA[Using ProviderName to get the database connection]]>https://daniellittle.dev/dbproviderfactorieshttps://daniellittle.dev/dbproviderfactoriesFri, 01 Feb 2013 02:00:00 GMT<p>When setting your connection string in a .NET config file you can make use of the <code class="language-text">providerName</code> attribute by using <code class="language-text">DbProviderFactories.GetFactory</code> and passing it the provider name. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var connectionStringSettings = ConfigurationManager.ConnectionStrings[&quot;DefaultConnection&quot;]; connection = DbProviderFactories.GetFactory(connectionStringSettings.ProviderName).CreateConnection(); connection.ConnectionString = connectionStringSettings.ConnectionString; connection.Open();</code></pre></div><![CDATA[Entity Framework and Foreign key constraint may cause cycles or multiple cascade paths]]>https://daniellittle.dev/ef-multiple-cascade-pathshttps://daniellittle.dev/ef-multiple-cascade-pathsMon, 21 Jan 2013 02:00:00 GMT<p>Today I ran into the <code class="language-text">Foreign key constraint may cause cycles or multiple cascade paths</code> issue for the first time. The first thing to note is the error isn't actually from Entity Framework it's from <a href="https://stackoverflow.com/questions/851625/foreign-key-constraint-may-cause-cycles-or-multiple-cascade-paths">SQL Server</a>.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Introducing FOREIGN KEY constraint &#39;ConstraintName&#39; on table &#39;TableName&#39; may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.</code></pre></div> <p>I was however using EF5 Code First so I fist needed to figure out why my model was giving me back this error. The error message itself pointed me to the Schema table referring to the Project table. Note my schema looks a bit like this:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Project { Id, Name } Schema { Id, ProjectId, ... } Node { Id, ProjectId, ... }</code></pre></div> <p>As you can see there are two relationships to the Projects table, which is usually fine. The issue comes from the fact that EF using the <code class="language-text">OneToManyCascadeDeleteConvention</code> convention my default. Which was not what I wanted for these two relationships.</p> <p>My EF model takes the convention and attribute approach, I try to avoid the fluent API to keep everything in the one place. However there is currently no attribute to turn off cascade delete.</p> <p>Here is how to do it using the fluent API:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">internal sealed class SchemaConfiguration : EntityTypeConfiguration&lt;Schema&gt; { public SchemaConfiguration() { this .HasRequired(x =&gt; x.Project) .WithMany() .WillCascadeOnDelete(false); } } /// &lt;summary&gt; /// Model Creating Event Handler. /// &lt;/summary&gt; protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new NodeConfiguration()); }</code></pre></div> <p><a href="https://stackoverflow.com/questions/5532810/entity-framework-code-first-defining-relationships-keys">Need more help</a></p><![CDATA[Ninject and Singletons in the WebAPI with Scopes]]>https://daniellittle.dev/ninject-webapihttps://daniellittle.dev/ninject-webapiFri, 11 Jan 2013 02:00:00 GMT<p>The new <a href="https://www.planetgeek.ch/2012/04/23/future-of-activation-blocks/#more-3392">Activation Blocks</a> in Ninject are great for automatically resolving dependencies in the request scope. However they suffer from one flaw which is they don't respect Constant or Singletons in fact they ignore the scope completely!</p> <p>In my application I needed a reference my dependency injection container in one of my objects. This would end up throwing <code class="language-text">Error loading Ninject component ICache</code> at the end of the request because now I had two kernels. Not good at all however I still had hope.</p> <p>Luckily there is one type of binding the <code class="language-text">ActivationBlock</code> can't ignore. The <code class="language-text">ToMethod</code> binding. So now I can make a small <code class="language-text">ScopedResolver</code> class which I can then inject into my class instead.</p> <p><strong>Binding</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">kernel.Bind&lt;ScopedResolver&gt;().ToMethod(x =&gt; { return new ScopedResolver((IActivationBlock)x.GetScope()); });</code></pre></div> <p><strong>ScopedResolver</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public class ScopedResolver { IActivationBlock resolver; public ScopedResolver(IActivationBlock resolver) { this.resolver = resolver; } public T TryGet&lt;T&gt;() { return resolver.TryGet&lt;T&gt;(); } }</code></pre></div><![CDATA[Silverlight Page Transition Complete Event]]>https://daniellittle.dev/silverlight-page-transitionhttps://daniellittle.dev/silverlight-page-transitionSun, 07 Oct 2012 01:00:00 GMT<p>While creating a mixed silverlight and xna WP7 application I started to add in page transitions with the silverlight toolkit. For the silverlight part of the application they work perfectly however when transitioning to the game screen the animation was not present.</p> <p>This is because in <code class="language-text">OnNavigatedTo</code> i'm obtaining the graphics device which overrides the rendering and this occurs <em>before</em> the animations starts.</p> <p>At this point you have two choices, implements a transition like effect manually in xna or delay obtaining the graphics device until the animation completes and display some content to transition with.</p> <p>I'm going to give a sample of how to do the latter.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public GamePage() { tansitionEnd = new RoutedEventHandler(GamePage_EndTransition); } protected override void OnNavigatedTo(NavigationEventArgs e) { TransitionService.GetNavigationInTransition(this).EndTransition += tansitionEnd; base.OnNavigatedTo(e); } protected void GamePage_EndTransition(object sender, RoutedEventArgs e) { TransitionService.GetNavigationInTransition(this).EndTransition -= tansitionEnd; }</code></pre></div> <p>The reason I picked the latter is because I will be using silverlight to render some parts of the UI. It's also important to note that as soon as you share the graphics device page level transitions will not render as xna takes over. However as stated above it's still possible to create a transition manually inside xna.</p><![CDATA[SharePoint WebConfig Modifications]]>https://daniellittle.dev/sharepoint-webconfig-modshttps://daniellittle.dev/sharepoint-webconfig-modsWed, 25 Jul 2012 01:00:00 GMT<p>Example for adding or removing a webconfig modification in SharePoint 2010. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">private void UpdateWebConfig(string name, string path, string owner, SPWebConfigModification.SPWebConfigModificationType type, string value, SPWebApplication app, bool removeModification) { if (removeModification) { var removals = app.WebConfigModifications.Where(item =&gt; item.Name == name).ToList(); foreach (var item in removals) { app.WebConfigModifications.Remove(item); } } else { SPWebConfigModification modification = new SPWebConfigModification(); modification.Name = name; modification.Path = path; modification.Owner = owner; modification.Sequence = 0; modification.Type = type; modification.Value = value; app.WebConfigModifications.Add(modification); } app.Update(); app.Farm.Services.GetValue&lt;SPWebService&gt;().ApplyWebConfigModifications(); }</code></pre></div> <p>Usage:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">UpdateWebConfig( &quot;add[@name=&#39;handlerName&#39;]&quot;, &quot;configuration/system.webServer/handlers&quot;, &quot;FeatureName&quot;, SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, &quot;&lt;add name=&#39;handlerName&#39; verb=&#39;*&#39; path=&#39;service.axd&#39; type=&#39;Namespace, Assembily, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0x0xx00000x00xx0&#39; /&gt;&quot;, webApplication, false );</code></pre></div><![CDATA[Inheriting SharePoint masterpages with Powershell]]>https://daniellittle.dev/sharepoint-masterpages-powershellhttps://daniellittle.dev/sharepoint-masterpages-powershellWed, 06 Jun 2012 01:00:00 GMT<p>If you want your subsites to inherit their masterpages from their parents the first thing you need to know is the difference between normal sites and publishing sites: Only publishing sites actually support inheriting masterpages. If you're site is not a publishing site you have to iterate over all the <code class="language-text">Webs</code> and set the property manually.</p> <p>If you have a publishing site your in luck SharePoint makes it easy for you but it's not completely obvious what to do. My first attempt at setting these properties to <code class="language-text">Inherit</code> was by setting the site property. And while this does make the UI say the right thing, it doesn't actually change the property <code class="language-text">CustomMasterUrl</code> in any way and you'll just get the old masterpage.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$web.AllProperties[&quot;__InheritsCustomMasterUrl&quot;] = &quot;True&quot; // This is wrong</code></pre></div> <p>What you have to do is update the <code class="language-text">CustomMasterUrl</code> as well, but then you're getting into unsupported functionality and it's also unnecessary work. Conveniently SharePoint already provides you with a <code class="language-text">PublishingWeb</code> class that supports inheritance for these properties.</p> <p>Here is an example:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$isPubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($web) if ($isPubWeb) { $pubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web) } if ($xmlNode.CustomMaster -ne $null) { if ($xmlNode.CustomMaster -eq &quot;Inherit&quot;) { if ($isPubWeb) { # https://msdn.microsoft.com/en-us/library/ms562472.aspx $pubWeb.CustomMasterUrl.SetInherit($true, $false) } else { Write-Host -Fore Red &quot;You cannot inherit without a publishing web!&quot; } } else { $url = $($site.ServerRelativeUrl + &quot;/_catalogs/masterpage/&quot; + $xmlNode.CustomMaster) if ($isPubWeb) { $pubWeb.CustomMasterUrl.SetValue($url, $false) } else { $web.CustomMasterUrl = $url } } }</code></pre></div><![CDATA[If you are going to do something, do it right]]>https://daniellittle.dev/do-it-righthttps://daniellittle.dev/do-it-rightSat, 26 May 2012 01:00:00 GMT<p>I love this quote and I think it really fits in with what I'm doing with this blog, and in my everyday life. Taking pride in your work is the only way to ensure that it's as good as it can be. Every day I like to feel that things are better than when I started. It's oftern the little things that count the most and here I have the opportunity to explain why.</p><![CDATA[Physics for games]]>https://daniellittle.dev/physics-for-gameshttps://daniellittle.dev/physics-for-gamesTue, 22 Nov 2011 02:00:00 GMT<p>I'm revisiting a lot of the physics and I predict trigonometry that was once a daily part of my life before graduating university.</p> <p>I'm surprised by how much I'd forgotten and writing it down always helps you remember it. Especially when it's on a blog and you can search for it later ;).</p> <p>The system I'll be focusing on is Rigid Body Dynamics so lets start with the basics.</p> <p>Any input into the system should be in the form of an impulse, which is basically a force against a point on a body. If all the impulses act against the center off mass we can deal with it just like a simple force.</p> <p>The formula for a force:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">force = mass x acceleration</code></pre></div> <p>Which can be rewritten as:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">acceleration = force / mass</code></pre></div> <p>Which is great because our input is a force and mass can be whatever fits for our simple system which gives us acceleration.</p> <p>The next thing we need is the velocity formula:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">velocity = acceleration x Δtime</code></pre></div> <p>Now for those of you that don't know Δ or in in English Delta means change or in this case change in time.</p> <p>You should keep track of your objects velocity and add to it whenever the body experiences acceleration.</p> <p>So now we have velocity and here comes position which we also keep track off and add to.</p> <p>Position formula:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">position = velocity x Δtime</code></pre></div> <p>Now we can do all the way from the initial push to there the body ends up after a known change in time. The same also applies to angular forces and motion but that's something I'll get to later. To be honest I'm still trying to wrap my head around <a href="https://en.wikipedia.org/wiki/Inertia_tensor">inertia tensors</a> which you need to</p> <p>Helpful links <a href="https://en.wikipedia.org/wiki/Dynamical_simulation">Dynamical simulation</a></p><![CDATA[WP7 Mango Unit Testing Framework "Cannot find a Resource with the Name/Key typeNameConverter"]]>https://daniellittle.dev/wp7-typenameconverterhttps://daniellittle.dev/wp7-typenameconverterTue, 18 Oct 2011 01:00:00 GMT<p>When trying to setup unit testing I was slightly dissapoited you couldn't test a silverlight library using a normal test project. However you can use the testing framework by using the <a href="https://www.jeff.wilcox.name/2010/05/sl3-utf-bits/">Silverlight 3 libraries here</a>.</p> <p>However you have to make sure you get the right version. I didn't and instead I found a link to an older tutorial and got the nice error <code class="language-text">Cannot find a Resource with the Name/Key typeNameConverter</code> and the only <a href="https://www.silverlightshow.net/news/A-Batch-File-for-Closing-Zune-and-Launching-the-WPConnect-Tool-Workaround-for-WP7-Mango-Unit-Testing-Framework-Cannot-find-a-Resource-with-the-Name-Key-typeNameConverter.aspx">real match</a> for the error had a broken link. The solution was simple though, find the source and update to the Mango version.</p><![CDATA[C# and casting]]>https://daniellittle.dev/c-castinghttps://daniellittle.dev/c-castingTue, 27 Sep 2011 01:00:00 GMT<p>I see alot of people using the <code class="language-text">as</code> keywork where they really just want to do a cast. Most of the time a cast will be what you want because it's faster and will fail early when somthing goes wrong.</p> <p>When should you <code class="language-text">cast</code>? You should cast when you already know what type the object is. A cast also will **not ** fail your value is null.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var value = (Apple)appleDictionary[key];</code></pre></div> <p>When should you use <code class="language-text">as</code>? When you don't know the type of object.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">bool makeA = true; BaseClass baseClass = null; baseClass = makeA ? new SuperClassA() : new SuperClassB(); SuperClassB val = baseClass as SuperClassB; if (val != null) { //...</code></pre></div> <p>You will almost always be compairing the value to <code class="language-text">null</code> after using as.</p> <p>It's important to know <code class="language-text">as</code> does not replace <code class="language-text">cast</code> in any way, always pick the one you need for your situation.</p><![CDATA[IIS Background Thread Abort Exception]]>https://daniellittle.dev/iis-background-threadshttps://daniellittle.dev/iis-background-threadsSat, 27 Aug 2011 01:00:00 GMT<p>One of my applications creates a background thread on startup which executes a series of tasks at a regular interval. However I get a <code class="language-text">ThreadAbortException</code> after my application pool is recycled.</p> <p>The problem is simply IIS is aborting my thread and my application is not handling it well. I found the solution in <a href="https://stackoverflow.com/questions/4347870/how-can-i-find-out-why-my-thread-is-being-stopped-in-asp-net">this Stack Overflow question</a>. You have to tell your thread to stop via the Application_End method in Global.asax.cs which gets called when the application is recycled.</p><![CDATA[C# and AOP (Aspect-oriented programming)]]>https://daniellittle.dev/c-apohttps://daniellittle.dev/c-apoFri, 26 Aug 2011 01:00:00 GMT<p>I just had a very interesting experience with AOP in C#. I have a function with a return type List<Update> which is being intercepted and that's all well and good. However the interceptor function is a validator style function and can prevent the real function by being called and returning the boolean false.</p> <p>So the code looks a little bit like this:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">List&lt;Update&gt; updates = Manager.ValidateAndCreate(); // protected void Save(List&lt;Update&gt; updates) { .... Save(updates);</code></pre></div> <p>The Method Interceptor looks like the following</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public class ExceptionAdvice : AopAlliance.Intercept.IMethodInterceptor { public object Invoke(AopAlliance.Intercept.IMethodInvocation invocation) { if (isValid(invocation)) { return invocation.Proceed(); } else { return false; } } private bool isValid( ... }</code></pre></div> <p>Now after validation fails the value of updates is actually a boolean not a List<Update>, I thought there would be some kind of runtime error here but there was not, so:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">updates.GetType().Name == &quot;Boolean&quot;</code></pre></div> <p>But:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">updates is bool == false</code></pre></div> <p>So save will still accept its mutated list of updates and will complain later on when you try to use it.</p> <p>So how is this possible in a type safe language like C#? btw it's spring-aop.</p> <p><a href="https://stackoverflow.com/questions/7200572/c-and-aop-aspect-oriented-programming-how-does-this-work">Link to the StackOverflow question</a></p><![CDATA[Object-Relational Mapper Exceptions]]>https://daniellittle.dev/orm-exceptionshttps://daniellittle.dev/orm-exceptionsFri, 19 Aug 2011 01:00:00 GMT<p>When working with Object-Relational Mappers like nhibernate and Entity Framework 4 it can seem like a good idea to setup a Session or Context at the start of a request and finalise it at the end of a request.</p> <p>This is exactly what I was doing until I figured out how wrong it was. I'll be using <em><a href="https://stackoverflow.com/questions/2478081/entity-framework-4-poco-where-to-start">Entity framework</a></em> for my examples so I'm not repeating myself. So the problem is basically that a Context is not your database access object but a <em>Unit of Work</em> that will be committed to the database. This is an extremely important point and this is because of exception handling.</p> <p>Now for a nice example, say you want to save a record to the users table but the username has a uniqueness constraint. If we're using one context per request and try to add a new user with an unavailable username we get a nice <em>UpdateException</em>. Now once this happens you can't use the context anymore. As a work around you can test for error states in a transaction before they happen, but that's allot of work and doesn't sound too nice.</p> <p>The solution therefore is to perform actions as a Unit of Work. That way if one doesn't work out you can handle it properly and recover.</p> <p>Take a look at this article to point you in the right direction <a href="https://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx">Using Repository and Unit of Work patterns with Entity Framework 4.0</a>.</p><![CDATA[Sharepoint People Picker Displays Selection as Html]]>https://daniellittle.dev/sharepoint-peope-picker-bughttps://daniellittle.dev/sharepoint-peope-picker-bugTue, 02 Aug 2011 01:00:00 GMT<p>When adding a people picker to a custom Html page I encountered an interesting error. When submitting the page the content would return hidden html from the control along with the message “You are only allowed to enter one item”.</p> <p>The html looks like this.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&lt; span id=’span xxxxx’ tabindex=’-1’ contentEditable=’false’ class=’ms-entity-resolved’ title=’xxxxx’ /&gt;</code></pre></div> <p>The issue seems to be I’m using IE 9 Standards mode, as SharePoint usualy runs in quirks mode.</p> <p>Similar issues: <a href="https://blog.richfinn.net/blog/CommentView,guid,4fce2e56-8e53-48cb-b6d9-6249af8e2141.aspx">https://blog.richfinn.net/blog/CommentView,guid,4fce2e56-8e53-48cb-b6d9-6249af8e2141.aspx</a></p><![CDATA[Sharepoint Permissions]]>https://daniellittle.dev/sharepoint-permissionshttps://daniellittle.dev/sharepoint-permissionsTue, 05 Jul 2011 01:00:00 GMT<p>The SharePoint permission model uses user impersonation, where a typical asp.net application will run under the permissions of the application pool SharePoint runs under the users credentials.</p> <p>The scenario we’ll be looking at is updating a sharepoint list programmatically.</p> <p>SharePoint has four default user groups, Read, Contributor, Designer and Full Control. Users would usually be in any of these groups or anything in between. This means that unless the users are also given explicit access to the list directly or via a group they may not have access to update a list even if allow unsafe updates is on.</p> <p>To resolve this issue there are two solutions.</p> <p>*The first is no revert back to the app pool, using this method means you have to identify the current user manually and by default all updates will appear as created or modified by the system account. *The second option is to assign users access to the list explicitly or create a group with access and add the group to the users (either automatically or manually via SharePoint).</p> <p>In my case I needed a solution where users could not access the list normally but using my custom solution allowed them to make updates. Therefore option one was the way to go for me.</p><![CDATA[Audit Data of Sharepoint List Items]]>https://daniellittle.dev/audit-data-sharepoint-list-itemshttps://daniellittle.dev/audit-data-sharepoint-list-itemsFri, 01 Jul 2011 01:00:00 GMT<p>Here is how to read list item data in sharepoint 2007.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var listItem = getMyItem(); string creator = listItem[&quot;Created By&quot;]; DateTime created = listItem[&quot;Created&quot;];</code></pre></div><![CDATA[AppHarbor - First Impressions]]>https://daniellittle.dev/appharbor-first-impressionshttps://daniellittle.dev/appharbor-first-impressionsTue, 28 Jun 2011 01:00:00 GMT<p>App Harbor is a great new cloud hosting service, which I’ve been trying out over the last few weeks. It deploys straight from source code using msbuild to transform your webconfigs, run your tests and deploy to the servers. </p> <p>However there’s a few things that I didn’t realise untill I’d started using it for a while. Firstly GIT support on windows if not the greatest and while it has been working fine Mercurial has been getting some popularity as an alternative and appharbor even has some support for working with it with bitbucket. </p> <p>Secondly its cloud based and when you try to get a CMS running you quickly realise they don’t work too well across multiple servers. As you need a central storage location for uploaded files, and CMS managed files. You can get it working and it’s something App Harbor is also looking into but it’s no simple deploy at the moment. </p><![CDATA[About Daniel Little]]>https://daniellittle.dev/abouthttps://daniellittle.dev/aboutFri, 23 Apr 2010 00:00:00 GMT<p>I'm a Software Engineer based in Brisbane Australia, with a focus on developing web based systems. I enjoy functional programming, domain driven design, distributed systems and event sourcing. But most of all I enjoy solving problems. As a developer I have the ability to create something from nothing. To make peoples jobs and lives, better and more enjoyable. It's an amazing feeling to make a real impact to companies and people everyday.</p> <p>In software development, you never get far alone. The best software is backed by amazing teams built on trust, empathy and humility. These teams know that working software is the best measure of progress; you must deliver working software frequently. They know technical excellence always aligns with the business objectives; you can't go faster by cutting corners. And they know communication is the most crucial element in software development.</p> <p>I value good work culture because people and technology are intrinsically intertwined. I know having context is key for building great software and I try to always optimise for people. I believe technical excellence always aligns with the business objectives and I value and strive to be more authentic to share and discover real stories.</p> <p>You can find me on twitter at <a href="https://twitter.com/daniellittledev">https://twitter.com/daniellittledev</a></p> <p>And at other places on the web such as:</p> <ul> <li><a href="https://stackoverflow.com/users/200442/daniel-little">Stackoverflow</a></li> <li><a href="https://github.com/daniellittledev">Github</a></li> <li><a href="https://www.linkedin.com/in/daniellittle">LinkedIn</a></li> </ul>
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
<title>
<![CDATA[ Daniel Little Dev ]]>
</title>
<description>
<![CDATA[ I write about building better software with a focus on Team Culture, Web Development, Type Safety, Functional Programming, Event Driven Systems. People first. ]]>
</description>
<link>https://daniellittle.dev</link>
<generator>GatsbyJS</generator>
<lastBuildDate>Sat, 20 Feb 2021 02:20:54 GMT</lastBuildDate>
<item>
<title>
<![CDATA[ Don't Ignore Your Functions ]]>
</title>
<description>
<![CDATA[ Ignoring return values can often be dangerous in subtle ways but you may be so used to doing it that you don't even notice anymore. It's… ]]>
</description>
<link>https://daniellittle.dev/dont-ignore-your-functions</link>
<guid isPermaLink="false">https://daniellittle.dev/dont-ignore-your-functions</guid>
<pubDate>Mon, 05 Oct 2020 20:00:00 GMT</pubDate>
<content:encoded><p>Ignoring return values can often be dangerous in subtle ways but you may be so used to doing it that you don't even notice anymore. It's likely that at some point you have run into an issue caused by forgetting to use the return value of a function. It's even more likely you throw away the return values of functions without thinking too much about it. Most of the time there's no real impact of doing so, and if there is it's certainly not immediate. But if you find yourself doing this often it is important to ask why. Presumably, the function is returning this value for a reason? Is there something wrong with the design of the API, or are you missing something important?</p> <h2>Adding to a date doesn't change it</h2> <p>Have you ever seen code like this?</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DateTime</span><span class="token punctuation">(</span><span class="token number">2000</span><span class="token punctuation">,</span> <span class="token number">01</span><span class="token punctuation">,</span> <span class="token number">01</span><span class="token punctuation">)</span><span class="token punctuation">;</span> date<span class="token punctuation">.</span><span class="token function">AddYears</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>$<span class="token string">"{date.ToShortDateString()}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>It looks pretty straightforward, but there's a bug in this code. If you're familiar with the dotnet <code class="language-text">DateTime</code> API it might be an obvious one but it can be subtle and confusing if you've never used it before.</p> <p>The issue is that when you call <code class="language-text">AddYears</code> it doesn't modify the date, instead it returns a brand new date. Therefore when <code class="language-text">WriteLine</code> is called the value will still say <code class="language-text">2000/01/01</code> instead of <code class="language-text">2001/01/01</code> like you may have expected.</p> <p>To get this to work correctly you'd have to capture the new date by assigning the new value to the date variable, like so.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> date <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DateTime</span><span class="token punctuation">(</span><span class="token number">2000</span><span class="token punctuation">,</span> <span class="token number">01</span><span class="token punctuation">,</span> <span class="token number">01</span><span class="token punctuation">)</span><span class="token punctuation">;</span> date <span class="token operator">=</span> date<span class="token punctuation">.</span><span class="token function">AddYears</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>$<span class="token string">"{date.ToShortDateString()}"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>So why does <code class="language-text">AddYears</code> return a new date object instead of adding a year to the existing date? It does this because date is an immutable type. This means that once you create a date you can never modify or change it, in any way. If you need a different date you'll always need to create a new one.</p> <p>Immutability itself is a very useful technique because it can help manage complexity due to limiting the possibilities you have to consider; there is only one way to change the date, replace it. However, issues like the example above can be hard to find if you're not looking for them. Wouldn't it be great if the C# compiler could detect issues like this and prevent you from making the mistake in the first place!</p> <h2>Async and you forgot to await</h2> <p>Let's look at a different problem for a moment. Say you had an async function which calls out to two async functions but you forget to await one of them.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">async</span> Task<span class="token operator">&lt;</span>ActionResult<span class="token operator">&lt;</span>Resource<span class="token operator">>></span> <span class="token function">GetResource</span><span class="token punctuation">(</span><span class="token keyword">string</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">AuditRequestAsync</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Forgot to await this, oops</span> <span class="token keyword">return</span> <span class="token keyword">await</span> <span class="token function">LoadResourceAsync</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>In this case, you'll get a warning from the C# compiler telling you that there might be a missing await. This is fantastic because the majority of the time this is almost certainly a bug. However, depending on how closely you monitor your warning, it's still possible to compile the app with the default compiler options. But what happens if we have the same function but without the async keyword, like so.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp">Task<span class="token operator">&lt;</span>ActionResult<span class="token operator">&lt;</span>Resource<span class="token operator">>></span> <span class="token function">GetResource</span><span class="token punctuation">(</span><span class="token keyword">string</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">AuditRequestAsync</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token function">LoadResourceAsync</span><span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>Semantically this function is exactly the same, it also suffers from the same bug but this time there's not even a warning. I've found this kind of issue to more common than it appears because a function can start off by only returning a task without needing the async keyword. In the example above if the <code class="language-text">AuditRequestAsync</code> function was added later on, or by a different author, they could forget to add the async keyword and the program will still happily compile.</p> <p>To make matters worst, the function might work in some cases, but fail in others. The <code class="language-text">AuditRequestAsync</code> function will still run, but without <code class="language-text">await</code> there is no guarantee the caller will still be around when it finishes. In some cases you might get an error regarding <code class="language-text">multiple active result sets</code> if they both make database calls. In others, you might not notice anything is wrong at all. Issues like these can often lie dormant until other changes trigger them, or result in indeterministic (or at the very least non obvious) behaviour making them extremely hard to track down and fix.</p> <h2>Implicitly ignoring functions is dangerous</h2> <p>What these examples have in common is that the value returned by a function (<code class="language-text">AddYears</code> and <code class="language-text">AuditResourceRequestAsync</code>) was implicitly ignored, resulting in a bug. If the compiler had issued a warning or an error indicating that the value was unused or implicitly ignored these issues could have been caught earlier or prevented entirely.</p> <p>There are also many more scenarios that suffer from this problem. For example using APIs like LINQ, Reactive Extensions, using Structs, and all immutable types, are cases where forgetting to use the value is almost certainly a bug. Even regular functions, particularly those that return values without side effects would benefit from making it obvious that a return value was ignored or forgotten.</p> <h2>Explicitly ignoring functions is safer</h2> <p>Instead of implicitly throwing away unused values, if we don't want to use a value we should explicitly discard it.</p> <p>To help catch unused values you could use a custom analyzer to create a warning for all unused values, not just a missing await inside an async function. There are no analyzers that do this yet, however, there are a few similar existing analyzers for some of these cases, such as <a href="https://docs.particular.net/nservicebus/operations/nservicebus-analyzer">async await</a>.</p> <p>Once there are warnings for unused return values it becomes clearer that an unused value is either a bug or something that can be explicitly discarded.</p> <p>A task, for example, would result in a warning about a possible missing await. If you do want to ignore the task then you can use a <code class="language-text">standalone discard</code> to let others know you don't care about it.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp">_ <span class="token operator">=</span> Task<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// Explicitly discard the result</span></code></pre></div> <p>This makes it clear that you made a conscious decision not to use the value. It shows other developers that a decision was made not to use the value as opposed to forgetting to use it.</p> <p>When someone else reads that code it is the difference between:</p> <ul> <li><em>Did they</em> <em>forget to use the return value? I'll need to investigate, versus...</em></li> <li><em>They've chosen to ignore the</em> <em>return value</em>. <em>I can move on.</em></li> </ul> <p>Making things more explicit will prevent bugs and save you and others a lot of time.</p> <h2>Would this really work</h2> <p>There's a lot of code out there today which was written without explicit discards in mind. And I don't expect the world of C# to change drastically overnight. Nevertheless, the aim of this article is to get more you interested in an analyzer that warns developers about unused return values in the same way your editor warns you about an unused variable today.</p> <p>You may still be wondering if so much C# code was written without explicit ignores in mind, would this be even practical to do in C#? Recently I've been doing a lot of dotnet development using F# which does emit compiler warning if a function return value is not used. So I can say that even with the dotnet as it exists today, I have been pleasantly surprised. I didn't need to discard half as many values as I thought I would.</p> <p>The large majority of code didn't need a single discard. There were only a few cases where I needed to use a discard, for example discarding the value at the end of a mutable fluent API.</p> <p>In that case, I would use an extension method to explicitly "cap off" the expression.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp">builder <span class="token punctuation">.</span><span class="token generic-method"><span class="token function">RegisterType</span><span class="token punctuation">&lt;</span><span class="token class-name">HttpClient</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AsSelf</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">InstancePerLifetimeScope</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">Ignore</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// &lt;- Takes a type &lt;T> and returns a void</span></code></pre></div> <p>I did however still run into at least one bug where I explicitly discarded a value that I shouldn't have. In the end, I found that even explicitly discarding values was something that should be done sparingly. Whenever I discarded a return value I found myself rethinking the code instead.</p> <p>I was more likely to use or log a status code or return code.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> response <span class="token operator">=</span> <span class="token keyword">await</span> httpClient<span class="token punctuation">.</span><span class="token function">PostAsync</span><span class="token punctuation">(</span>url<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> log<span class="token punctuation">.</span><span class="token function">Information</span><span class="token punctuation">(</span><span class="token string">"Responded with {StatusCode}"</span><span class="token punctuation">,</span> response<span class="token punctuation">.</span>StatusCode<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>If I wanted to run a task in the background I kept the task in a Task service and it simplified error handling for all background tasks.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp">BackgroundService<span class="token punctuation">.</span><span class="token function">Register</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// Instead of</span> _ <span class="token operator">=</span> Task<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// Hope you handled the exceptions in here</span></code></pre></div> <p>If I used the builder pattern or a fluent API I considered using an immutable API and returning the value instead of a using a mutable one. For example using LINQ vs using the List API.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">public</span> IEnumerable<span class="token operator">&lt;</span>Out<span class="token operator">></span> <span class="token function">GetResults</span><span class="token punctuation">(</span>IEnumerable<span class="token operator">&lt;</span>In<span class="token operator">></span> items<span class="token punctuation">)</span> <span class="token operator">=></span> items <span class="token punctuation">.</span><span class="token function">Where</span><span class="token punctuation">(</span>x <span class="token operator">=></span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> <span class="token operator">*</span><span class="token operator">*</span><span class="token punctuation">.</span><span class="token function">Select</span><span class="token punctuation">(</span>x <span class="token operator">=></span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">OrderBy</span><span class="token punctuation">(</span>x <span class="token operator">=></span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span></code></pre></div> <p>I'm also cautious of functions that don't return values but that's another story.</p> <h2>I'm interested but maybe not convinced</h2> <p>Whenever I first stumble across a new concept or technique I find that I need to play with it for a while to start to get a good feel for how it works. Have a go at building an analyzer and see where the warnings are. Try writing a program from scratch with the warnings on. Turn on warnings as errors so you aren't tempted to take shortcuts and follow where the analyzer takes you.</p> <p>But most importantly, if you find yourself discarding values without using them, ask yourself why.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Type-Safe Hypermedia Controls ]]>
</title>
<description>
<![CDATA[ Hypermedia Controls in REST provide links and actions with each response pointing to related resources. This concept is a powerful tool that… ]]>
</description>
<link>https://daniellittle.dev/type-safe-hypermedia-controls</link>
<guid isPermaLink="false">https://daniellittle.dev/type-safe-hypermedia-controls</guid>
<pubDate>Sun, 12 Jul 2020 08:00:00 GMT</pubDate>
<content:encoded><p>Hypermedia Controls in REST provide links and actions with each response pointing to related resources. This concept is a powerful tool that enables the server to remain in control of links and access. If you're not sure what I mean by this, take a moment to read my previous article on my approach regarding <a href="/practical-hypermedia-controls">Practical Hypermedia Controls</a>.</p> <p>Enter Typescript. Adding types to JavaScript allows us to write safer code, so naturally I wanted to figure out how to make a Hypermedia Controls type-safe. Typically when writing a type-safe API you might start out with something like this.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">const</span> <span class="token function-variable function">api</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">fetch<span class="token punctuation">:</span> Fetch</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> getAccount<span class="token punctuation">:</span> <span class="token keyword">async</span> <span class="token punctuation">(</span>id<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token parameter">AccountResource</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/account/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>id<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> jsonGetOptions<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> AccountResource<span class="token punctuation">;</span> <span class="token punctuation">}</span> updateAccount<span class="token punctuation">:</span> <span class="token keyword">async</span> <span class="token punctuation">(</span>account<span class="token punctuation">:</span> AccountResource<span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token parameter">AccountResource</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/account/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>account<span class="token punctuation">.</span>id<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> <span class="token function">jsonPutOptionsWith</span><span class="token punctuation">(</span>account<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> AccountResource<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre></div> <p>In this example, the <code class="language-text">Request</code> and <code class="language-text">Response</code> types are strongly typed but the URL is hardcoded and you can't tell when you'd have access or who has access to this endpoint. Using Hypermedia Controls can provide that missing context. Links and actions are related to a resource, and the server can dictate if or when the various links and actions are available.</p> <p>In order to see how to combine these two concepts, let's look at what the usage of type-safe Hypermedia controls would look like.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token comment">// Fetch a root resource</span> <span class="token keyword">const</span> account <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetchAccount</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span> <span class="token keyword">const</span> accountHypermedia <span class="token operator">=</span> <span class="token function">accountHypermedia</span><span class="token punctuation">(</span>account<span class="token punctuation">)</span> <span class="token keyword">const</span> accountUpdate <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token operator">...</span>account<span class="token punctuation">,</span> email<span class="token punctuation">:</span> <span class="token string">"daniellittle@elsewhere"</span> <span class="token punctuation">}</span> <span class="token comment">// Invoke the Update action</span> <span class="token keyword">const</span> updatedAccount <span class="token operator">=</span> <span class="token keyword">await</span> accountHypermedia<span class="token punctuation">.</span>actions<span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>updatedAccount<span class="token punctuation">)</span> <span class="token comment">// &lt;- Typechecked!</span></code></pre></div> <p>In this example the account email address is being updated and then the Hypermedia Controls are used to update the resource. Fetching the account resource contains the raw Hypermedia Controls but passing the resource into the <code class="language-text">accountHypermedia</code> function transforms the hypermedia into a type safe API style object. There are a few interesting things happening here, so let's peel back the covers.</p> <h2>Types for Links and Actions</h2> <p>First, Let's take a look at what the <code class="language-text">AccountResource</code> type looks like.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">export</span> <span class="token keyword">type</span> AccountResource <span class="token operator">=</span> <span class="token punctuation">{</span> id<span class="token punctuation">:</span> Identifier username<span class="token punctuation">:</span> <span class="token builtin">string</span> name<span class="token punctuation">:</span> <span class="token builtin">string</span> email<span class="token punctuation">:</span> <span class="token builtin">string</span> _links<span class="token punctuation">:</span> <span class="token punctuation">{</span> self<span class="token punctuation">:</span> Relationship <span class="token punctuation">}</span> _actions<span class="token punctuation">:</span> <span class="token punctuation">{</span> activate<span class="token operator">?</span><span class="token punctuation">:</span> Relationship deactivate<span class="token operator">?</span><span class="token punctuation">:</span> Relationship update<span class="token punctuation">:</span> Relationship <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>The Hypermedia Controls are statically defined inside of the <code class="language-text">_links</code> and <code class="language-text">_actions</code> properties which contain all the well known relationships. Looking at these relationships we can see the resource always contains a <code class="language-text">self</code> link and an <code class="language-text">update</code> action but optionally contains <code class="language-text">activate</code> and <code class="language-text">deactivate</code>. It's important to note that the types are only coupled to the names of the relationships (rels) and their optionality. The server still controls the URLs and the presence of optional relationships.</p> <p>Be cautious of making the types for the Hypermedia Controls too dynamic. On my first attempt at adding types for hypermedia, I used a more general dictionary type for links and actions. My thinking was that this would more accurately model the changing and dynamic hypermedia relationships a resource would have.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">type</span> Relationships <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span>rel<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">]</span><span class="token punctuation">:</span> Relationship <span class="token operator">|</span> <span class="token builtin">unknown</span> <span class="token punctuation">}</span></code></pre></div> <p>This assumption quickly turned out to be false and worked against the goal and benefits of strong typing. The relationships were not as dynamic as I had originally assumed. Links and actions don't change frequently, so you can safely define them as part of the type. Another downside was that you can't easily see what relationships are contextual and which ones are always present.</p> <p>Hypermedia is often taken a bit too far and is often associated with machine-readable metadata or form builders. My advice here is to avoid designing your types for general hypermedia clients. Instead, think of these types as representing a well defined and static contract between the client and the server.</p> <p>All links and actions use the <code class="language-text">Relationship</code> type which represents the relationship and its location. A relationship can be either a simple URL or a contain extra info such as the <code class="language-text">Method</code> or <code class="language-text">Title</code>.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">export</span> <span class="token keyword">type</span> Href <span class="token operator">=</span> <span class="token builtin">string</span> <span class="token keyword">export</span> <span class="token keyword">type</span> DetailedRelationship <span class="token operator">=</span> <span class="token punctuation">{</span> href<span class="token punctuation">:</span> Href method<span class="token operator">?</span><span class="token punctuation">:</span> Method title<span class="token operator">?</span><span class="token punctuation">:</span> <span class="token builtin">string</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">type</span> Relationship <span class="token operator">=</span> <span class="token operator">|</span> Href <span class="token operator">|</span> DetailedRelationship</code></pre></div> <p>I usually use the <code class="language-text">DetailedRelationship</code> type but sometimes it's conventient to only provide the URL for links, which typically use the <code class="language-text">GET</code> verb.</p> <h2>Contextual Relationships</h2> <p>In the <code class="language-text">AccountResource</code> above you can see there are three potential actions. The <code class="language-text">update</code> action is always available but <code class="language-text">activate</code> and <code class="language-text">deactivate</code> are optional so the client only has to check for the presence of the optional relationships. The server can then decide when these optional actions are available, enabling the actions for the client based on the state of the resource.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">const</span> account <span class="token operator">=</span> <span class="token function">fetchAccount</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span> <span class="token keyword">const</span> accountHypermedia <span class="token operator">=</span> <span class="token function">accountHypermedia</span><span class="token punctuation">(</span>account<span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>accountHypermedia<span class="token punctuation">.</span>deactivate<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// The account can be deactivated!</span> <span class="token keyword">await</span> accountHypermedia<span class="token punctuation">.</span><span class="token function">deactivate</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// &lt;- Also Typechecked, no request payload is needed!</span> <span class="token punctuation">}</span></code></pre></div> <p>In this sample, <code class="language-text">deactivate</code> has to be null checked before it can be used. The <code class="language-text">call</code> function also knows that <code class="language-text">deactivate</code> takes no payload and what the return type is.</p> <h2>Creating a Hypermedia Model</h2> <p>Next, let's look into the <code class="language-text">accountHypermedia</code> function, which does the heavy lifting of transforming the resource with hypermedia into a typed hypermedia model containing all the links and actions. To make the conversion easier I've also written a function <code class="language-text">createHypermediaModel</code> which helps to create the API for a resource.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">type</span> none <span class="token operator">=</span> <span class="token keyword">void</span> <span class="token comment">// Used when a Request requires no payload (function &lt;T>(arg: T) would need no arguments)</span> <span class="token keyword">const</span> accountHypermedia <span class="token operator">=</span> <span class="token function">createHypermediaModel</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resource<span class="token punctuation">:</span> AccountResource<span class="token punctuation">,</span> resolve</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span> links<span class="token punctuation">:</span> <span class="token punctuation">{</span> self<span class="token punctuation">:</span> resolve<span class="token operator">&lt;</span>none<span class="token punctuation">,</span> AccountResource<span class="token operator">></span><span class="token punctuation">(</span>resource<span class="token punctuation">.</span>_links<span class="token punctuation">.</span>self<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> actions<span class="token punctuation">:</span> <span class="token punctuation">{</span> deactivate<span class="token punctuation">:</span> resolve<span class="token operator">&lt;</span>none<span class="token punctuation">,</span> AccountResource<span class="token operator">></span><span class="token punctuation">(</span>resource<span class="token punctuation">.</span>_actions<span class="token punctuation">.</span>deactivate<span class="token punctuation">)</span><span class="token punctuation">,</span> update<span class="token punctuation">:</span> resolve<span class="token operator">&lt;</span>none<span class="token punctuation">,</span> AccountResource<span class="token operator">></span><span class="token punctuation">(</span>resource<span class="token punctuation">.</span>_actions<span class="token punctuation">.</span>update<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span></code></pre></div> <p>You can view this code as a mapping from the resource to a set of, ready to use, functions. The resolve function takes the relationship and returns an object containing a strongly typed <code class="language-text">call</code> function as well as the <code class="language-text">href</code> and <code class="language-text">title</code> if one was provided.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">resolve&lt;none, AccountResource&gt;(resource._links.self)</code></pre></div> <p><em>Note: In Typescript, you are able to pass through a generic function as a parameter. The <code class="language-text">resolve</code> parameter makes use of this to compose (an instance of) fetch and the request/response types.</em></p> <p>The <code class="language-text">ResolvedRelationship</code> makes it convenient to access the <code class="language-text">href</code> and other metadata if you only have access to the hypermedia model.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">export</span> <span class="token keyword">type</span> ResolvedRelationship<span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function-variable function">call</span><span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token parameter">request<span class="token punctuation">:</span> Request</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token builtin">Promise</span><span class="token operator">&lt;</span>Response<span class="token operator">></span> href<span class="token punctuation">:</span> <span class="token builtin">string</span> title<span class="token punctuation">:</span> <span class="token builtin">string</span> <span class="token operator">|</span> undefined <span class="token punctuation">}</span></code></pre></div> <p>I use <code class="language-text">href</code> from the <code class="language-text">ResolvedRelationship</code> to follow links to different pages by changing the URL. This means exposing the <code class="language-text">Method</code> isn't nessesary as they are always <code class="language-text">GET</code> requests.</p> <h2>Multiple Resources</h2> <p>The <code class="language-text">createHypermediaModel</code> function focuses on creating a hypermedia model for a single resource. In order to create a model for an entire API you can use a <code class="language-text">createApi</code> function to create a single object composing the sub-APIs for each individual resource.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">export</span> <span class="token keyword">function</span> <span class="token function">createApi</span><span class="token punctuation">(</span><span class="token parameter">fetch<span class="token punctuation">:</span> Fetch</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> resolve <span class="token operator">=</span> <span class="token function">createResolver</span><span class="token punctuation">(</span>fetch<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token function-variable function">getAccount</span><span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token parameter">url<span class="token punctuation">:</span> <span class="token builtin">string</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> resolve<span class="token operator">&lt;</span>none<span class="token punctuation">,</span> AccountResource<span class="token operator">></span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> accounts<span class="token punctuation">:</span> <span class="token function">accountHypermedia</span><span class="token punctuation">(</span>resolve<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// More models go here!</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>That covers all the main pieces of using <code class="language-text">createHypermediaModel</code> to build a type-safe hypermedia API. Please let me know if you liked this approach as I'm considering wrapping this up into an npm package. However, I've glossed over the detail of how <code class="language-text">createHypermediaModel</code> works. It's mostly the glue and pluming but there are a few interesting parts. Feel free to read the apendix below if you'd like to dig deeper under the covers.</p> <p>That's all I have for now and as always thanks for reading!</p> <h2>Apendix: Deeper into the Code</h2> <p> Here is the bulk of the code, feel free to skim over it and jump to the alaysis at the bottom.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">export</span> <span class="token keyword">type</span> JsonFetch <span class="token operator">=</span> <span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span><span class="token punctuation">(</span><span class="token parameter">method<span class="token punctuation">:</span> Method<span class="token punctuation">,</span> url<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">,</span> data<span class="token operator">?</span><span class="token punctuation">:</span> Request</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token builtin">Promise</span><span class="token operator">&lt;</span>Response<span class="token operator">></span> <span class="token keyword">export</span> <span class="token keyword">type</span> Resolver <span class="token operator">=</span> <span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span><span class="token punctuation">(</span><span class="token parameter">relationship<span class="token punctuation">:</span> Relationship</span><span class="token punctuation">)</span> <span class="token operator">=></span> ResolvedRelationship<span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span> <span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getHref</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">rel<span class="token punctuation">:</span> Relationship</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> rel <span class="token operator">===</span> <span class="token string">"string"</span> <span class="token operator">?</span> rel <span class="token punctuation">:</span> rel<span class="token punctuation">.</span>href<span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">getTitle</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">rel<span class="token punctuation">:</span> Relationship</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> rel <span class="token operator">===</span> <span class="token string">"string"</span> <span class="token operator">?</span> undefined <span class="token punctuation">:</span> rel<span class="token punctuation">.</span>title<span class="token punctuation">)</span> <span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">createResolver</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">fetch<span class="token punctuation">:</span> JsonFetch</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span><span class="token punctuation">(</span> relationship<span class="token punctuation">:</span> Relationship <span class="token punctuation">)</span><span class="token punctuation">:</span> ResolvedRelationship<span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> <span class="token function-variable function">apiCall</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter">request<span class="token punctuation">:</span> Request</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> rel<span class="token punctuation">:</span> <span class="token punctuation">{</span> href<span class="token punctuation">:</span> Href<span class="token punctuation">;</span> method<span class="token punctuation">:</span> Method<span class="token punctuation">;</span> name<span class="token operator">?</span><span class="token punctuation">:</span> <span class="token builtin">string</span> <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">typeof</span> relationship <span class="token operator">===</span> <span class="token string">"string"</span> <span class="token operator">?</span> <span class="token punctuation">{</span> href<span class="token punctuation">:</span> relationship<span class="token punctuation">,</span> method<span class="token punctuation">:</span> <span class="token string">"get"</span> <span class="token punctuation">}</span> <span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token operator">...</span>relationship<span class="token punctuation">,</span> method<span class="token punctuation">:</span> relationship<span class="token punctuation">.</span>method <span class="token operator">||</span> <span class="token string">"get"</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> response <span class="token operator">=</span> <span class="token keyword">await</span> fetch<span class="token operator">&lt;</span>Request<span class="token punctuation">,</span> Response<span class="token operator">></span><span class="token punctuation">(</span>rel<span class="token punctuation">.</span>method<span class="token punctuation">,</span> rel<span class="token punctuation">.</span>href<span class="token punctuation">,</span> request<span class="token punctuation">)</span> <span class="token keyword">return</span> response <span class="token keyword">as</span> Response <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token punctuation">{</span> call<span class="token punctuation">:</span> apiCall<span class="token punctuation">,</span> href<span class="token punctuation">:</span> <span class="token function">getHref</span><span class="token punctuation">(</span>relationship<span class="token punctuation">)</span><span class="token punctuation">,</span> title<span class="token punctuation">:</span> <span class="token function">getTitle</span><span class="token punctuation">(</span>relationship<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">export</span> <span class="token keyword">const</span> createHypermediaModel <span class="token operator">=</span> <span class="token operator">&lt;</span>Resource<span class="token punctuation">,</span> <span class="token constant">T</span><span class="token operator">></span><span class="token punctuation">(</span> <span class="token function-variable function">builder</span><span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token parameter">resource<span class="token punctuation">:</span> Resource<span class="token punctuation">,</span> resolver<span class="token punctuation">:</span> Resolver</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token constant">T</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token parameter">resolver<span class="token punctuation">:</span> Resolver</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token parameter">resource<span class="token punctuation">:</span> Resource</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">builder</span><span class="token punctuation">(</span>resource<span class="token punctuation">,</span> resolver<span class="token punctuation">)</span></code></pre></div> <p>The code is written in a functional programming style and functions declared before they are used. Therefore it is usually easier to look at functions starting from the bottom and going up.</p> <p>The first function is, therefore, <code class="language-text">ceateHypermediaModel</code>, which uses a bit of currying so the resolver and resource can be provided at different times. Dependencies such as Fetch and the Resolver are threaded through the call stack so no global references are needed.</p> <p>The other main function is <code class="language-text">createResolver</code> which constructs the <code class="language-text">ResolvedRelationship</code>. Its main job is to wrap up the call to fetch using the given relationship and the request/response types.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Practical Hypermedia Controls ]]>
</title>
<description>
<![CDATA[ A lot has been written about REST but less so when it comes to Hypermedia Controls. I haven't seen too many Hypermedia based APIs out in the… ]]>
</description>
<link>https://daniellittle.dev/practical-hypermedia-controls</link>
<guid isPermaLink="false">https://daniellittle.dev/practical-hypermedia-controls</guid>
<pubDate>Tue, 07 Jul 2020 08:00:00 GMT</pubDate>
<content:encoded><p>A lot has been written about REST but less so when it comes to Hypermedia Controls. I haven't seen too many Hypermedia based APIs out in the wild. I theorize that there are two main reasons for this. First, it is something many people haven't been exposed to, and second, it requires a little more up-front effort in order to get the ball rolling. However, I believe it's an incredibly useful pattern and it's easier to get started than you might think. This post aims to help out with that first problem, exposure. We'll take a look at what Hypermedia Controls are and why they're useful.</p> <p>Whatever the reason for the rarity of Hypermedia Controls, what you might commonly see in a REST API instead, is something like this.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token punctuation">{</span> <span class="token property">"id"</span><span class="token operator">:</span> <span class="token string">"0001"</span> <span class="token property">"username"</span><span class="token operator">:</span> <span class="token string">"daniellittledev"</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Daniel Little"</span> <span class="token property">"email"</span><span class="token operator">:</span> <span class="token string">"daniellittle@somewhere"</span> <span class="token property">"canUpdate"</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token property">"canDeactivate"</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span></code></pre></div> <p>This JSON object represents a user account. In this system, there are a few simple rules. Only the owner of the resource can update it and only admins can deactivate or activate accounts. This resource uses boolean flags to inform the client what state the object is in and what actions it can perform.</p> <p>However, there are some problems with this model.</p> <ul> <li>We can't tell if the current user should be able to activate or deactivate the account.</li> <li>We can't tell if the account can be activated, we have to assume it can be because we can't deactivate it.</li> <li>We don't know how to update or deactivate an account, we'd need more external information like the URL.</li> </ul> <p>Wouldn't it be nice if all these things were a bit easier to figure out? I think so too!</p> <h2>Enter Hypermedia Controls</h2> <p>Hypermedia Controls in REST APIs are all about adding links and actions to a resource instead of needing to interoperate what links and actions are available based on state. Examples of state are boolean flags like above or a status value like <code class="language-text">ready</code> or <code class="language-text">pending</code>. Here's what the same resource would look like if we added Hypermedia Controls instead.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token punctuation">{</span> <span class="token property">"id"</span><span class="token operator">:</span> <span class="token string">"0001"</span><span class="token punctuation">,</span> <span class="token property">"username"</span><span class="token operator">:</span> <span class="token string">"daniellittledev"</span><span class="token punctuation">,</span> <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Daniel Little"</span><span class="token punctuation">,</span> <span class="token property">"email"</span><span class="token operator">:</span> <span class="token string">"daniellittle@somewhere"</span><span class="token punctuation">,</span> <span class="token property">"links"</span><span class="token operator">:</span> <span class="token punctuation">{</span> ... <span class="token punctuation">}</span> <span class="token property">"actions"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"update"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"href"</span><span class="token operator">:</span> <span class="token string">"/account/0001"</span><span class="token punctuation">,</span> <span class="token property">"method"</span><span class="token operator">:</span> <span class="token string">"put"</span><span class="token punctuation">}</span> <span class="token property">"activate"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"href"</span><span class="token operator">:</span> <span class="token string">"/account/0001/activate"</span><span class="token punctuation">,</span> <span class="token property">"method"</span><span class="token operator">:</span> <span class="token string">"post"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Now we can clearly see which actions are available. There are two available actions, update and activate, along with the URL and verb needed to make the calls. Instead of the client needing to infer this from the data, the server directly dictates what actions are available. We don't need to assume the client can activate the account if <code class="language-text">canDeactivate</code> is <code class="language-text">false</code>. There's also no danger of adding conflicting flags. The client can directly show or enable buttons or links directly based on what Hypermedia Controls are present.</p> <p>Let's look at our previous problems again, now that we're using Hypermedia.</p> <ul> <li>There is no action for deactivating the account; so the user can't see or perform that action.</li> <li>There is an action to activate the account; so the user should see and perform that action.</li> <li>We know the URL and method, so the client doesn't need hardcode or build-up any URLs.</li> </ul> <p>Much better! This also helps out immensely when debugging or looking at the REST API directly. There's no need for all that extra context to be extracted from the client because it's all there in the resource.</p> <p>Also, note that to perform an update you would simply modify the resource as desired and send it right back. You can optionally remove the links and actions, but otherwise, they're typically ignored.</p> <p>All this makes the API much easier to reason about and use. But the key benefit is the client no longer needs to interpret any state to figure out what is going on. We're able to keep the knowledge, of who can do what and when, on the server without having to duplicate any logic into the client. And while this example is a fairly trivial one, a few more flags like the ones above or worse, enum states where the client has to decide what buttons are available based on states like <code class="language-text">Pending</code>, <code class="language-text">InProgress</code> or <code class="language-text">Completed</code>, can easily increase complexity and the burden of keeping everything in sync.</p> <h2>More Control</h2> <p>We can also do more than just make links and actions available or unavailable. We could also show that an action exists but isn't available. On the UI this could manifest as a visible but disabled button.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token property">"actions"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"update"</span><span class="token operator">:</span> <span class="token null keyword">null</span> <span class="token comment">// or { disabled: true }</span> <span class="token punctuation">}</span></code></pre></div> <p>If you'd like things to be a bit more dynamic or server controlled you can also include a title for an action which could be used as the label for a link or button.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token property">"actions"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"update"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"href"</span><span class="token operator">:</span> <span class="token string">"/account/0001"</span><span class="token punctuation">,</span> <span class="token property">"method"</span><span class="token operator">:</span> <span class="token string">"put"</span><span class="token punctuation">,</span> <span class="token property">"title"</span><span class="token operator">:</span> <span class="token string">"Update Account"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>It's really up to you to choose how much information is provided to the client. However, I'd be cautious of adding too much. You might be tempted to include other metadata like field types or validation rules. But the main goal here is to keep duplicate logic out of the client and keep the server in control of application state. Decoupling too much tends to lead to the <a href="https://en.wikipedia.org/wiki/Inner-platform_effect">Inner Platform Effect</a>.</p> <h2>Client-Side Routing</h2> <p>There's one unexpected question I came across while implementing a Hypermedia based API. Which is how they affect client-side routing. I've found keeping API URLs in sync with the browser URLs to be a good approach. Or to be more accurate, I believe they should be the same URL. If you're coming from a non-hypermedia based API your URLs will most likely have diverged so I'll demonstrate what this looks like in practice.</p> <p>The root hypermedia resource is the starting point for the API, it provides all the top level links you'd need to get started.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token comment">// Request:</span> GET <span class="token string">"/"</span> <span class="token comment">// Response:</span> <span class="token punctuation">{</span> <span class="token property">"links"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"my-account"</span><span class="token operator">:</span> <span class="token string">"/account/0001"</span><span class="token punctuation">,</span> <span class="token property">"accounts"</span><span class="token operator">:</span> <span class="token string">"/account"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Following a link such as <code class="language-text">my-account</code> (which the client knows by name) would update the browsers route to match, eg. <code class="language-text">/account/0001</code>. The client-side routing rules mirror the server-side rules to render the relevant components but simply forward the URL directly to the API to fetch a resource. Note that the value here is that the client doesn't have to hardcode, reconstruct or build any URLs.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token comment">// Request:</span> GET <span class="token string">"/account/0001"</span> <span class="token comment">// Response:</span> <span class="token punctuation">{</span> <span class="token property">"links"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"self"</span><span class="token operator">:</span> <span class="token string">"/account/0001"</span><span class="token punctuation">,</span> <span class="token property">"home"</span><span class="token operator">:</span> <span class="token string">"/"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>Actions are a little different and don't usually represent a route change. I recommend using a get-post-redirect style pattern so that a link (self) or a redirect is used to determine the next URL for the client.</p> <h2>Try it out</h2> <p>Next time you're building a form with a few actions especially if those actions change under different conditions or states consider using Hypermedia Controls. I hope you enjoyed this article, and if so make sure to keep an eye out for my next post on <a href="/type-safe-hypermedia-controls">Type Safe Hypermedia with Typescript</a>.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Power Query - The M Language ]]>
</title>
<description>
<![CDATA[ Recently I had the opportunity to write a Custom Connector for Power BI and come across something I didn't expect. To build a Connector you… ]]>
</description>
<link>https://daniellittle.dev/power-query-the-m-language</link>
<guid isPermaLink="false">https://daniellittle.dev/power-query-the-m-language</guid>
<pubDate>Mon, 22 Jun 2020 10:40:00 GMT</pubDate>
<content:encoded><p>Recently I had the opportunity to write a Custom Connector for Power BI and come across something I didn't expect. To build a Connector you use Power Query also known as the M formula language. Power Query was designed to build data transformation pipelines, focusing on repeatable importing and manipulations of tables.</p> <blockquote> <p>A core capability of Power Query is to filter and combine, that is, to mash-up data from one or more of a rich collection of supported data sources.</p> </blockquote> <p>But what I didn't expect is that Power Query is a lazy functional programming language. The documentation describes it as "a functional, case sensitive language similar to F#". So not only does Power BI include a programming language it's also a functional programming language! Although if I had to describe it, I'd say it's more of a simplified cross between JavaScript and Haskell. Curious? Well then, let's take a quick look at what Power Query looks like, and some of its features.</p> <p>The first thing you might notice about Power Query is that it's almost entirely expression-based. Every function is comprised of a single expression. </p> <div class="gatsby-highlight" data-language="fsharp"><pre class="language-fsharp"><code class="language-fsharp">Function <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">"Hello"</span> <span class="token function">Function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// returns "Hello"</span></code></pre></div> <p>Here we have a global variable called <code class="language-text">Function</code> which contains a function which returns "hello". All functions are lambdas.</p> <p>One of the most common building blocks is the <code class="language-text">let</code> expression, which lets you build up more complex functions using variables.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token keyword">let</span> <span class="token hvariable">hello</span> <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token hvariable">world</span> <span class="token operator">=</span> <span class="token string">"World"</span> <span class="token keyword">in</span> <span class="token hvariable">hello</span> <span class="token operator">&amp;</span> <span class="token string">" "</span> <span class="token operator">&amp;</span> <span class="token hvariable">world</span> <span class="token operator">&amp;</span> <span class="token string">"!"</span></code></pre></div> <p>If you're not familiar with the <code class="language-text">let</code> syntax it's quite common in expression-based functional languages. A <code class="language-text">let</code> expression allows you to define and bind other expressions for use in the <code class="language-text">in</code> clause. You can read it like, let these "names" be bound to these "values" in this "expression".</p> <p>Let's look at a more complex function. The function below makes a web request to a given URL and returns the result as JSON.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token constant">Fetch</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token hvariable">url</span> <span class="token hvariable">as</span> <span class="token hvariable">text</span><span class="token punctuation">)</span> <span class="token hvariable">as</span> <span class="token hvariable">record</span> <span class="token operator">=></span> <span class="token keyword">let</span> <span class="token hvariable">accessToken</span> <span class="token operator">=</span> <span class="token constant">Extension.CurrentCredential</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token hvariable">access_token</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token hvariable">authHeader</span> <span class="token operator">=</span> <span class="token string">"Bearer "</span> <span class="token operator">&amp;</span> <span class="token hvariable">accessToken</span><span class="token punctuation">,</span> <span class="token hvariable">response</span> <span class="token operator">=</span> <span class="token constant">Web.Contents</span><span class="token punctuation">(</span><span class="token hvariable">url</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token constant">ManualCredentials</span> <span class="token operator">=</span> <span class="token hvariable">true</span><span class="token punctuation">,</span> <span class="token constant">Headers</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token constant">Authorization</span> <span class="token operator">=</span> <span class="token hvariable">authHeader</span><span class="token punctuation">]</span> <span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">in</span> <span class="token constant">Json.Document</span><span class="token punctuation">(</span><span class="token hvariable">response</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>There are a few things going on in this function but one of the interesting things to point out are the two main types you see in Power Query, apart from tables of course. These are lists and records, and the interesting bit is that the symbols are opposite to what you might expect if coming from most other languages. </p> <p>Lists are defined using braces <code class="language-text">{}</code> and records are defined using square brackets <code class="language-text">[]</code>, the exact opposite of JavaScript or FSharp.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token hvariable">list</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">}</span> <span class="token hvariable">record</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token constant">Property</span> <span class="token operator">=</span> <span class="token hvariable">true</span><span class="token punctuation">,</span> <span class="token constant">AnotherProperty</span> <span class="token operator">=</span> <span class="token string">"Hello"</span> <span class="token punctuation">]</span></code></pre></div> <p>Accessing a property is also a little different and also uses <code class="language-text">[]</code>.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token hvariable">value</span> <span class="token operator">=</span> <span class="token hvariable">record</span><span class="token punctuation">[</span><span class="token constant">Property</span><span class="token punctuation">]</span></code></pre></div> <p>In the Fetch function above you can see the <code class="language-text">access_token</code> property being used via the credentials record.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token constant">Extension.CurrentCredential</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token hvariable">access_token</span><span class="token punctuation">]</span></code></pre></div> <p>Briefly, on types, the language is dynamic with optional types and can also be extended with custom metadata. Below the function starts without any types and you can see how the code changes as I add more type information.</p> <div class="gatsby-highlight" data-language="fsharp"><pre class="language-fsharp"><code class="language-fsharp"><span class="token punctuation">(</span>url<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token operator">..</span><span class="token punctuation">.</span>expression <span class="token punctuation">(</span>url <span class="token keyword">as</span> text<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token operator">..</span><span class="token punctuation">.</span>expression <span class="token punctuation">(</span>url <span class="token keyword">as</span> text<span class="token punctuation">)</span> <span class="token keyword">as</span> record <span class="token operator">=</span><span class="token operator">></span> <span class="token operator">..</span><span class="token punctuation">.</span>expression <span class="token punctuation">(</span>url <span class="token keyword">as</span> text<span class="token punctuation">)</span> <span class="token keyword">as</span> record meta <span class="token punctuation">[</span> Documentation<span class="token punctuation">.</span>Name <span class="token operator">=</span> <span class="token string">"My Record Type"</span> <span class="token punctuation">]</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token operator">..</span><span class="token punctuation">.</span>expression</code></pre></div> <p>Now, I've saved the best until last. One of the most powerful features of Power Query is that it's lazy. Take for example the following code.</p> <div class="gatsby-highlight" data-language="haskell"><pre class="language-haskell"><code class="language-haskell"><span class="token keyword">let</span> <span class="token hvariable">pets</span> <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token constant">Fetch</span><span class="token punctuation">(</span><span class="token string">"https://api.service.com/dogs"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token constant">Fetch</span><span class="token punctuation">(</span><span class="token string">"https://api.service.com/cats"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">in</span> <span class="token hvariable">pets</span><span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">}</span></code></pre></div> <p>In this expression, we have a list of pets which contains the result of some API calls to a web service. However, only the first element of the array is ever accessed and because Power Query is lazy the second fetch will never actually be evaluated. In a custom connector, this could be used to access a paged rest API in order to import a table. And because evaluation is lazy using the standard <code class="language-text">take</code> function will only fetch the pages that are needed are fetched.</p> <p>It's exciting to see functional programming, especially a language as interesting as Power Query, popping up in the mainstream. I had a blast learning about Power Query and I learnt so much along the way. If you're interested in trying out a functional first language, whatever it may be, I encourage you, now is the time to check one out!</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Environment Settings for Build Once Packages in React ]]>
</title>
<description>
<![CDATA[ Let's look at some questions: How do you specify which API to use for an environment? How do you configure the environment settings of… ]]>
</description>
<link>https://daniellittle.dev/environment-settings-for-build-once-packages-in-react</link>
<guid isPermaLink="false">https://daniellittle.dev/environment-settings-for-build-once-packages-in-react</guid>
<pubDate>Tue, 14 Jan 2020 17:00:00 GMT</pubDate>
<content:encoded><p>Let's look at some questions:</p> <ol> <li>How do you specify which API to use for an environment?</li> <li>How do you configure the environment settings of frontend apps for each environment?</li> <li>How to you achieve: build once, deploy everywhere packages for a frontend app?</li> </ol> <p>Most frontend applications currently take the approach of <a href="https://twitter.com/housecor/status/973881714710908928">building a package for each environment</a>. This approach is reasonably well supported by Webpack and it is a common approach. There's also a lot of workarounds such as sniffing the URL, injecting extra scripts or using a find and replace script on the bundle. These approaches can provide a single package but are often custom solutions for individual applications.</p> <p>I think there are two main reasons for this, the first, is that when you <code class="language-text">create-react-app</code> out of the box there is no built-in support for build once, deploy everywhere. You have to fend for yourself. But second, and possibly, more importantly, it is more difficult to set up runtime style environment settings needed for build once, deploy everywhere packages.</p> <h2>Build Once, Deploy Everywhere</h2> <p>As this approach is less common, let's look at what exactly this is, why it's important and some of the benefits of this approach. The build once, deploy everywhere pattern refers to the building a single deployment artefact which can be deployed to one or many different environments.</p> <h3>Shorter build times</h3> <p>Building packages is expensive, building a package once saves quite a bit of time and compute. If your build takes 40 seconds, and you have two environments, the total build time is effectively doubled to over a minute. Fast builds and deployment times are also important for low deployment lead times and short development cycles. Today it's also common to have you build/ci agent in the cloud where we'll typically pay per minute or per agent for parallel builds. Here short build times have an even greater impact on development and costs.</p> <h3>Exact same code</h3> <p>By building the package once and using that same package in every environment, you can guarantee they'll all be running the exact same code. There are multiple reasons why you might end up with slight unexpected variations such as non-deterministic compilers, resulting in different optimisations. Dependencies could change, for example, if the build step runs an auto package restore or the build script relies on an external service. There may also be bugs in the tooling which can be unforeseen. By building the package once, there are fewer opportunities for things to go wrong, which means less risk.</p> <h3>Simplified deployment pipeline</h3> <p>Modern deployment pipelines such as those in products such as Octopus Deploy or Azure DevOps support environment based deployments, deployment promotion and variable substitution. These tools assume a single artifact or package which can then be deployed to an environment. Variable substitution is applied at deployment time after the package has been created, typically as a final configuration step during deployment. Taking advantage of these features results in a simplified deployment pipeline. The tooling can often assist with promoting to the next environment or marking the package as containing defects, managing the lifecycle of the package for us.</p> <h2>Loading Environment Settings in React</h2> <p>In order to load the settings, I've gone with the approach of using a single file to keep loading times as low as possible.</p> <p>There is a single <code class="language-text">settings.json</code> file which contains the environment you want to load settings for, as well as blocks containing the default and environment settings. In the example below the environment is <code class="language-text">development</code> which is what I'd also check into version control.</p> <div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token comment">// settings.json</span> <span class="token punctuation">{</span> <span class="token property">"environment"</span><span class="token operator">:</span> <span class="token string">"development"</span><span class="token punctuation">,</span> <span class="token property">"default"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"api"</span><span class="token operator">:</span> <span class="token string">"defaultapi.com"</span><span class="token punctuation">,</span> <span class="token property">"siteName"</span><span class="token operator">:</span> <span class="token string">"Example Site"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token property">"development"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"api"</span><span class="token operator">:</span> <span class="token string">"developmentapi.com"</span><span class="token punctuation">,</span> <span class="token property">"banner"</span><span class="token operator">:</span> <span class="token string">"You are in the Development Environment"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>On deployment, environment property is replaced with the appropriate environment name. Settings can also be added or modified. Then, when the application is run the application, I'll get the combination of (using spread internally) the default and matching environment blocks.</p> <p>To tie it all together, I'm using a component called <code class="language-text">AppSettingsLoader</code> which loads the settings given the URL of a settings file. It also takes three other props to determine what to show while the settings are being loaded or unavailable, what to render once the settings are available, and optionally an error prop.</p> <div class="gatsby-highlight" data-language="tsx"><pre class="language-tsx"><code class="language-tsx"><span class="token keyword">import</span> AppSettingsLoader <span class="token keyword">from</span> <span class="token string">"react-environment-settings"</span><span class="token punctuation">;</span> <span class="token keyword">import</span> settingsAssetUrl <span class="token keyword">from</span> <span class="token string">"./settings.json.txt"</span><span class="token punctuation">;</span> <span class="token keyword">interface</span> <span class="token class-name">Settings</span> <span class="token punctuation">{</span> api<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> banner<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token operator">&lt;</span>AppSettingsLoader<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Settings</span></span><span class="token punctuation">></span></span><span class="token plain-text"> settingsUrl=</span><span class="token punctuation">{</span>settingsAssetUrl<span class="token punctuation">}</span><span class="token plain-text"> loading=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Loading settings...</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">}</span><span class="token plain-text"> ready=</span><span class="token punctuation">{</span><span class="token parameter">s</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>pre</span><span class="token punctuation">></span></span><span class="token punctuation">{</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>s<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>pre</span><span class="token punctuation">></span></span><span class="token punctuation">}</span><span class="token plain-text"> /></span></code></pre></div> <p>The AppSettingsLoader is also a generic component; in this example, you can also see the <code class="language-text">Settings</code> interface used to specify the type of the combined settings. Therefore, the final product of the Settings for all environments need to match a common interface.</p> <div class="gatsby-highlight" data-language="tsx"><pre class="language-tsx"><code class="language-tsx"><span class="token operator">&lt;</span>AppSettingsLoader<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Settings</span></span><span class="token punctuation">></span></span><span class="token plain-text"> ... /></span></code></pre></div> <p>In order to load the settings themselves, there were a number of issues I had to work through. I wanted to keep the settings file separate to the application bundle, but <code class="language-text">json</code> files are bundled if you import them. I also wanted to avoid caching issues so I couldn't just move the file into the public folder and fetch it from there.</p> <p>In order to load the settings file with Typescript and Webpack I was able to use the <a href="https://webpack.js.org/guides/typescript/#importing-other-assets">Importing Other Assets</a> functionality which lets you import a file, in this case, a <code class="language-text">txt</code> file. Importing the file will cause it to be processed giving it a unique filename, but unlike a <code class="language-text">json</code> import the file contents are unmodified and the file is stored in the <code class="language-text">media</code> folder.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&gt; build &gt; static &gt; css &gt; js &gt; media &gt; settings.json.4355cbd.txt</code></pre></div> <p>Above is an example of where you can locate the file after a build. As you can see the settings file is easy to locate, having a similar but also cache busting filename. This means it's easy to locate the settings file and perform environment name and variable substitution.</p> <p>Importing the file in Typescript also requires a module declaration.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token comment">// global.d.ts</span> <span class="token keyword">declare</span> <span class="token keyword">module</span> <span class="token string">'*.txt'</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> content<span class="token punctuation">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span> <span class="token keyword">export</span> <span class="token keyword">default</span> content<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>And when the file is imported, you'd receive the path to the file which can be passed to the <code class="language-text">AppSettingsLoader</code> and loaded via a fetch.</p> <div class="gatsby-highlight" data-language="typescript"><pre class="language-typescript"><code class="language-typescript"><span class="token keyword">import</span> settingsAssetUrl <span class="token keyword">from</span> <span class="token string">"./settings.json.txt"</span><span class="token punctuation">;</span></code></pre></div> <p>You could also provide a Url from another source if needed.</p> <p>Finally, by using <code class="language-text">AppSettingsLoader</code> at the root of an application, you're then able to breifly delay running the application until the settings have been loaded and are available.</p> <div class="gatsby-highlight" data-language="tsx"><pre class="language-tsx"><code class="language-tsx"><span class="token operator">&lt;</span>AppSettingsLoader<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Settings</span></span><span class="token punctuation">></span></span><span class="token plain-text"> settingsUrl=</span><span class="token punctuation">{</span>settingsAssetUrl<span class="token punctuation">}</span><span class="token plain-text"> loading=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Loading...</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token punctuation">}</span><span class="token plain-text"> ready=</span><span class="token punctuation">{</span><span class="token parameter">s</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">App</span></span> <span class="token attr-name">appSettings</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>s<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">}</span><span class="token plain-text"> /></span></code></pre></div> <h2>Installation and Code</h2> <p>If you'd like to try it out, you can install this package.</p> <div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> i react-environment-settings</code></pre></div> <p>I won't go into all the code, but you can find the full project on GitHub <a href="https://github.com/daniellittledev/react-environment-settings">daniellittledev/react-environment-settings</a>. Originally I was only planning on sharing my approach with a blog post, but it just wouldn't be complete without a package on npm.</p> <p>I've tried to keep the code relatively simple, so I'll just share a few key parts.</p> <p>The bulk of the logic is inside two main files, <code class="language-text">loadSettings.ts</code> which loads the merges the settings, and <code class="language-text">index.ts</code> which contains the component itself.</p> <p>Below is the main load settings function. Here I'd like to highlight in terms of error handling, fetch and loading issues are both caught at the top level of this function.</p> <div class="gatsby-highlight" data-language="tsx"><pre class="language-tsx"><code class="language-tsx"><span class="token keyword">export</span> <span class="token keyword">async</span> <span class="token keyword">function</span> loadSettings<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">T</span></span><span class="token punctuation">></span></span><span class="token plain-text">( settingsUrl: string ) </span><span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> settings <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getSettings</span><span class="token punctuation">(</span>settingsUrl<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> allSettings <span class="token operator">=</span> <span class="token function">getSelectedSettings</span><span class="token punctuation">(</span>settings<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> mergedSettings <span class="token operator">=</span> <span class="token function">mergeSettings</span><span class="token punctuation">(</span>allSettings<span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token builtin">unknown</span><span class="token punctuation">;</span> <span class="token keyword">return</span> success<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">T</span></span><span class="token punctuation">></span></span><span class="token plain-text">(mergedSettings as T); } catch (ex) </span><span class="token punctuation">{</span> <span class="token keyword">return</span> error<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">T</span></span><span class="token punctuation">></span></span><span class="token plain-text">(ex); } };</span></code></pre></div> <p>This error is then directly accessible using the <code class="language-text">error</code> prop on the <code class="language-text">AppSettingsLoader</code> component.</p> <div class="gatsby-highlight" data-language="tsx"><pre class="language-tsx"><code class="language-tsx"><span class="token keyword">switch</span> <span class="token punctuation">(</span>settings<span class="token punctuation">.</span><span class="token keyword">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token keyword">case</span> <span class="token string">"Error"</span><span class="token punctuation">:</span> <span class="token keyword">return</span> props<span class="token punctuation">.</span>error <span class="token operator">?</span> <span class="token punctuation">(</span> props<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span>settings<span class="token punctuation">.</span>error<span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token punctuation">(</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">Error loading settings</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>So you have full control if something goes wrong.</p> <h2>Wrapping up</h2> <p>Good luck out there with your settings loading journey. If you're trying to get a new project up and running or updating an existing project, I hope this post has helped you.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Practising Continuous Deployment ]]>
</title>
<description>
<![CDATA[ I've long been an advocate of Continuous Deployment, but it's always felt somewhat out of reach. I've come close with projects that have had… ]]>
</description>
<link>https://daniellittle.dev/practising-continuous-deployment</link>
<guid isPermaLink="false">https://daniellittle.dev/practising-continuous-deployment</guid>
<pubDate>Mon, 21 Oct 2019 17:00:00 GMT</pubDate>
<content:encoded><p>I've long been an advocate of Continuous Deployment, but it's always felt somewhat out of reach. I've come close with projects that have had decent test coverage and automated deployments, but there was always something missing. There was always still a button you needed to click to promote from test into production. Often unreleased code could build-up, resulting in a bigger riskier release or more manual testing.</p> <p>Continuous Deployment can be difficult to adopt <em>because</em> you need to build reliability and confidence into your build and deployment pipelines. But more difficult is the culture shift, it's a different way of working and you can't just slap some tests on it and declare Continuous Deployment. Buy-in is important and so is process, because while Continuous Deployment is positively self-reinforcing, not practising it is negatively reinforcing. You need critical mass, and you need to jump the gap quickly. So while I've come close, it remained difficult to bridge the gap into the magical world of Continuous Deployment.</p> <p>However, during my time with the wonderful folks at Stacktrace, we practised Continuous Delivery amongst a team of eight developers. To date, it's that only team I've joined that was already practising Continuous Delivery. It was everything I hoped it would be. And since then I've brought a lot of what I learnt with me, continuing to put Continuous Delivery into practice.</p> <p>So I'd like to tell you about the strategies we used.</p> <h3>Shared code ownership</h3> <p>Everyone was equally across most areas of the codebase, and everyone felt comfortable working on any feature or change. We all paid attention to quality and avoided cutting corners. This made everything easier; you can take for granted cohesion, consistency and tests to cover your back. We also made sure to keep it that way.</p> <h3>Always production-ready</h3> <p>All commits are production-ready, you know that each push could potentially make it to production. If code isn't ready to go live, then it's either not wired up to the UI, silently running beside an existing version or behind a feature toggle. This ensures each release is small and all code is continuously integrated, so everyone sees the latest code even if it's not finished.</p> <p>Features also need to be backwards compatibility typically through parallel implementations or on-the-fly database migrations.</p> <h3>Short-lived branches</h3> <p>Branches are kept small and short-lived typically only lasting for 1-2 days. They're also only used for Pull Requests and usually don't represent a full or complete feature. As long as they're production-ready they're good to go.</p> <h3>Rebasing onto master</h3> <p>Master is always moving forward and in order to get value out of continuous integration, you need the latest code on your machine. We frequently rebased development branches onto master. To make this even easier, I'll use a function like fmar, which stands for fetch master and rebase.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">function fmar { git fetch git rebase origin/master }</code></pre></div> <h3>Quick Code Reviews</h3> <p>All code is merged into master from a PR, and each PR must be reviewed by someone else. Sometimes we'd pick someone familiar with the change and sometimes we'd pick someone different to share things around.</p> <p>We also treated code reviews as a priority. Initially it's the responsibility of the author to find someone to review the PR. Once you agreed to review a PR, it was then up to you to review it promptly or hand the PR back if something unexpected came up.</p> <p>We also tried to as much as possible give feedback as advice. PRs were almost always approved, instead of blocked, but most feedback was actioned regardless. Sometimes in a follow-up PR instead of delaying an existing PR.</p> <h3>Clean history</h3> <p>The key to quick PRs is code and commits that are easy to read and easy to follow. We would regularly rebase the commits in a PR so commits would tell a story or make a change easier to follow. And because branches were short-lived force pushing isn't a problem. We'd also use git pushfl or git push --force-with-lease for added safety, which aborts if anyone else has pushed to that branch.</p> <h3>Automated Code Formatters</h3> <p>Another tool we used to keep PRs quick was automated code formatting. This ensures that all code is consistent and that no one needs to waste time on style discussions in a PR.</p> <h3>Robust Test Suite</h3> <p>A good test suite is invaluable for continuous integration and deployment. Many changes can be verified via the tests without needing to run the application and perform lots of slower manual testing. Every change is backed by tests, and the tests are first-class code which is also actively maintained and improved.</p> <h3>Fully Automated deployments</h3> <p>Setting up fully Automated deployments is a key aspect because it reinforces many of the concepts above. Completing a PR doesn't just sit in test until it's ready. Keeping commits production-ready is more than just an ideal. The PR will go all the way to production, and it needs to be production-ready.</p> <p>This is also where a robust test suite really becomes indispensable. Automated builds always run before PRs can be integrated, and deployments are exercised by deploying to a test environment before they're deployed to production.</p> <h3>Testing in Prod</h3> <p>The last point I want to mention is testing in production. Having a test tenancy in the production environment allows for the testing and review of new functionality and changes that have not yet been enabled for all users. This was invaluable to exercise the system from end to end with real data and with all the real dependencies.</p> <h2>A Reflection</h2> <p>I found it an incredibly valuable experience to practice continuous deployment, but even more importantly, the practises that support it, make it possible and sustain it. </p> <p>Joining a team and learning through immersing myself in a culture that was already practising helped to bring these strategies into focus for me. </p> <p>I find that sometimes, it is hard to do things one step at a time because they can all seem to depend on each other. In the case of Continuous Deployment I still think that's true to some extent. There is a gap you have to jump to truly adopt Continuous Deployment. But I feel I have a much better idea of what makes Continuous Deployment successful.</p> <p>I'd also love to hear about what makes Continuous Deployment work for you. If you think I've missed something or one thing really stands out for you tag me on twitter <a href="https://twitter.com/daniellittledev">@daniellittledev</a>.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ How to run Expecto with dotnet test ]]>
</title>
<description>
<![CDATA[ Expecto is a fantastic test framework and test runner for FSharp. But contrary to the name, the thing I like most about Expecto is that it… ]]>
</description>
<link>https://daniellittle.dev/how-to-run-expecto-with-dotnet-test</link>
<guid isPermaLink="false">https://daniellittle.dev/how-to-run-expecto-with-dotnet-test</guid>
<pubDate>Mon, 07 Oct 2019 19:00:00 GMT</pubDate>
<content:encoded><p>Expecto is a fantastic test framework and test runner for FSharp. But contrary to the name, the thing I like most about Expecto is that it contains so little magic. Your test project is a simple Console applications and to run you tests you just run the app. No Visual Studio plugins required.</p> <div class="gatsby-highlight" data-language="powershell"><pre class="language-powershell"><code class="language-powershell">dotnet run</code></pre></div> <p>However, recently I wanted to also run my tests using <code class="language-text">dotnet test</code> to fit into a existing test suit and build script. By default Expecto tests won't be discovered by <code class="language-text">dotnet test</code> but the good news is it's only two packages and an attribute away from working with both <code class="language-text">run</code> and <code class="language-text">test</code>.</p> <p>I started with an application that used no auto test discovery opting for explicit test registration like the following. </p> <div class="gatsby-highlight" data-language="f#"><pre class="language-f#"><code class="language-f#">let allTests = testList &quot;all-tests&quot; [ BuilderTests.tests Convention.test Domain.tests ] [&lt;EntryPoint&gt;] let main argv = printfn &quot;Running tests!&quot; runTestsWithArgs config argv allTests</code></pre></div> <p>We'll come back to this later, first we need to install some packages.</p> <p>In order to set up tests with dotnet core we need to add the <code class="language-text">Test SDK</code> to the project file.</p> <div class="gatsby-highlight" data-language="xml"><pre class="language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>PackageReference</span> <span class="token attr-name">Include</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Microsoft.NET.Test.Sdk<span class="token punctuation">"</span></span> <span class="token attr-name">Version</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>16.3.0<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <p>However this will generate an entry point for your application and because we already have one we'll need to disable that by setting <code class="language-text">GenerateProgramFile</code> to <code class="language-text">false</code> in the project file.</p> <div class="gatsby-highlight" data-language="xml"><pre class="language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>PropertyGroup</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>GenerateProgramFile</span><span class="token punctuation">></span></span>false<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>GenerateProgramFile</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>PropertyGroup</span><span class="token punctuation">></span></span></code></pre></div> <p>After that we'll need to add the package <code class="language-text">YoloDev.Expecto.TestSdk</code> in order <code class="language-text">dotnet test</code> to discover Expecto tests.</p> <div class="gatsby-highlight" data-language="xml"><pre class="language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>PackageReference</span> <span class="token attr-name">Include</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>YoloDev.Expecto.TestSdk<span class="token punctuation">"</span></span> <span class="token attr-name">Version</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0.8.0<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div> <p>This package exposes Expecto Test Attributes for discovery via the Microsoft Test SDK.</p> <p>Finally, we need to make one change to the <code class="language-text">Program.fs</code> file, adding the <code class="language-text">Tests</code> attribute to the tests so they can be discovered.</p> <div class="gatsby-highlight" data-language="f#"><pre class="language-f#"><code class="language-f#">[&lt;Tests&gt;] let allTests = testList &quot;all-tests&quot; [ BuilderTests.tests Convention.test Domain.tests ] [&lt;EntryPoint&gt;] let main argv = printfn &quot;Running tests!&quot; runTestsWithArgs config argv allTests</code></pre></div> <p>Now when we run <code class="language-text">dotnet test</code> we see the following:</p> <div class="gatsby-highlight" data-language="powershell"><pre class="language-powershell"><code class="language-powershell">> dotnet test Test run <span class="token keyword">for</span> App<span class="token punctuation">.</span>Tests<span class="token punctuation">.</span>dll<span class="token punctuation">(</span><span class="token punctuation">.</span>NETCoreApp<span class="token punctuation">,</span>Version=v2<span class="token punctuation">.</span>2<span class="token punctuation">)</span> Microsoft <span class="token punctuation">(</span>R<span class="token punctuation">)</span> Test Execution Command Line Tool Version 16<span class="token punctuation">.</span>3<span class="token punctuation">.</span>0 Copyright <span class="token punctuation">(</span>c<span class="token punctuation">)</span> Microsoft Corporation<span class="token punctuation">.</span> All rights reserved<span class="token punctuation">.</span> Starting test execution<span class="token punctuation">,</span> please wait<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> A total of 1 test files matched the specified pattern<span class="token punctuation">.</span> Test Run Successful<span class="token punctuation">.</span> Total tests: 31 Passed: 31 Total time: 1<span class="token punctuation">.</span>3619 Seconds</code></pre></div> <p>Success!</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Reliable Messaging over a Service Bus ]]>
</title>
<description>
<![CDATA[ When working with a traditional database inside of a monolith application, we don't usually need to think too much about how transactions… ]]>
</description>
<link>https://daniellittle.dev/reliable-messaging-over-service-bus</link>
<guid isPermaLink="false">https://daniellittle.dev/reliable-messaging-over-service-bus</guid>
<pubDate>Thu, 16 May 2019 18:00:00 GMT</pubDate>
<content:encoded><p>When working with a traditional database inside of a monolith application, we don't usually need to think too much about how transactions work. We can rely on a transaction to either roll back all the changes or commit them. Either way, our model is always consistent.</p> <p>More recently, many applications have become distributed in one way or another. Many use a Service Bus or a REST API to communicate with other external systems. Communication between these systems is not transactional, so they won't be able to share a transaction and rollback if there are failures. So we'll need a method of reliably sending messages from one system to another. In this post, we'll be looking at how to implement reliable messaging between two applications using a Service Bus.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/2e091859671a8874dbfdbf7eeb89f2b7/9435c/services-communicating-over-service-bus.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.61855670103093%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAo0lEQVQY012Q2QoCMQxF+/+/4pP/Ifqo+DQOiAvFKczSznS53pQWqoHThiS9Sar0suA8DFi9hycppR94wIWQQROPJfecJlyNQWBeUBeK7boO47ZBrCYyMSKyyVFrHIgI1LiXBuTE+L7vYVknpsQRMW0tPs5lAd+Iiv/gFrdxxMq6SLGai0TeT+Q1z/lWvihL4E1Q1mlXzhOR/++o4mJ3rm440BczOzhKFmMUIAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Services communicating over a Service Bus" title="Services communicating over a Service Bus" src="/static/2e091859671a8874dbfdbf7eeb89f2b7/fea0e/services-communicating-over-service-bus.png" srcset="/static/2e091859671a8874dbfdbf7eeb89f2b7/064a4/services-communicating-over-service-bus.png 225w, /static/2e091859671a8874dbfdbf7eeb89f2b7/44727/services-communicating-over-service-bus.png 450w, /static/2e091859671a8874dbfdbf7eeb89f2b7/fea0e/services-communicating-over-service-bus.png 900w, /static/2e091859671a8874dbfdbf7eeb89f2b7/9435c/services-communicating-over-service-bus.png 970w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <h2>What's the problem?</h2> <p>When sending messages over a Service Bus there are a number of failure points to consider. If there is a failure at any of these points then information could be lost, state could be corrupted or the process may stall.</p> <blockquote> <p>We need to do three things when processing a message</p> <ol> <li>Execute domain logic</li> <li>Send new messages</li> <li>Save updates to the database</li> </ol> </blockquote> <p>The core of the problem lies with the fact that there are two data-stores, the primary database and a (durable) queue or topic. However, it's only possible to write to one or the other first.</p> <h3>Send then Save</h3> <p>Let's look at what happens when we send messages first, then save to the database.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 478px;" > <a class="gatsby-resp-image-link" href="/static/19ea4df6bd8aa4109b9a107960494007/16786/send-first-with-failure-to-save.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 87.23849372384937%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB0klEQVQ4y6VU20oDMRDt/3+Fr76oT6IgguCLCiqoVWll7WVba+/tXpvdHc9JkxK3a0UcOCSZ2TlzyWRrYRSJZJmESSKr1UoKpSTFyj1X2jrzuVx/fEicppIZuwJ49mYzeZtOJYA/dTXJc/GCQA5bLTnudmVGEkgha5nCad/zZK/ZlMvBQOvyYm29GY3kvN/X+gsEpNRSOBy123I/Hsup78vVcKgNGQJRemEoj8hgEMdyCwJl9JRXZBejggwBXrCnrcbSzno9OUF2B8iSBk1osvBBSFJKHbaVQ/iMc2rOdQTVhDl6EgJ3yJDKwhDZNUDAh8lEnmBroJduyb7Jnn7ecmlKNj1zpUxKcTNzbSRXzve6ZO2ALBVgDRa6fPYJKEo2nvOSbUOoHMKyqF+CubYNoc0iwTwt0I8lEGCcNCH0uSm53A7q6bdFGGMsPtHkLm7Ow+gQ7xiTIQI00PQIaxWhTaSSMKm4IObFi4sdwqr+bhEu8ASHAOcqQk8sOLghhl+Vgtn7/5GQvYuwT9jHEkgYMkvsIwLfFtDtJIxQ8hgZTvDhBA4WfMvMfARMeYZzFy8r73R2E+o/jTFsNzJf4y8l2+uvGl5VMdhSMTb66VnCbyT/wBd2TDIPzoq5pQAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="After sending message there is a failure to save" title="After sending message there is a failure to save" src="/static/19ea4df6bd8aa4109b9a107960494007/16786/send-first-with-failure-to-save.png" srcset="/static/19ea4df6bd8aa4109b9a107960494007/064a4/send-first-with-failure-to-save.png 225w, /static/19ea4df6bd8aa4109b9a107960494007/44727/send-first-with-failure-to-save.png 450w, /static/19ea4df6bd8aa4109b9a107960494007/16786/send-first-with-failure-to-save.png 478w" sizes="(max-width: 478px) 100vw, 478px" loading="lazy" /> </a> </span></p> <p>In this situation, we've sent out messages, but there was an error while writing the updated application state to the database. In this case, no updates are made to the database so as far as our application is concerned nothing happened, but we ended up leaking messages.</p> <p>Now downstream systems may be working with inconsistent messages. The Service Bus may also redeliver the message, so the application can retry, but if the message is retried a different result might be reached because state and time will continue to change between attempts.</p> <h3>Save then Send</h3> <p>So sending messages first isn't too good, what if we save first instead? Then we wouldn't process invalid messages, and we'll avoid putting bad state into the database. Let's see what that looks like.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 478px;" > <a class="gatsby-resp-image-link" href="/static/0fc82c63fe5c176d740233df6edd8d89/16786/save-first-with-failure-to-send.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 87.23849372384937%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB5ElEQVQ4y62USU/jQBCF8/9/BVcuM5wQSKORkLgAEiDNDIsIMknINlkhXmO3i6+attVyDOJASaVenuv1q+pqd6I4FikKidJUttutlHkuGaPOdVRs8PIi55OJJFkmhcNzXNfBei2Pq5WExOteR4yRIAzlZ68nh8/PslYSrJR3WxG0HwSy1+3K6XRq90z5jl7M5/J7PLb7Jxyo1skIOOj35XqxkOPhUM5mMwsUHKQ2iiL5i4JpksglBLnbV7tHXUIGBQfcMVeso6n9Go3kCHU/UKmAJXQqhhAqqdoN2NYjvGWdufUNh1pCQ00i/AqFulk6omoMOfDPcin/wB6opZ/y0KnXuGCzcSm7mvnWJFXzlfmYkufe9zZlG4DKHK+A2jV9rRNetmCmgdWEuUfYNIsR1KZeyXwhNaEFXJDuhdRnQzsZUq0UfqZ+hzChMf9DMmMcU+AnLimgTaY0/oT9icNmtE/trLtciDb4LiEfpMy1yMa7DFPVFxUVVjtYClnWRviKkjme6jOEQMeEMWbU1glde+k8rub4xj3ZHcIUIGauRJbMjSk1DDmoBG+z0tV4hzAm5QWBS+QvCa58wce9wUAM3mwb+exS7J/GAa0qXGN/mbBqj/KD1jCNl1JfmpeyfXp+Qb/D3wAOvjGhC8Bw2AAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="After saving state there is a failure to send" title="After saving state there is a failure to send" src="/static/0fc82c63fe5c176d740233df6edd8d89/16786/save-first-with-failure-to-send.png" srcset="/static/0fc82c63fe5c176d740233df6edd8d89/064a4/save-first-with-failure-to-send.png 225w, /static/0fc82c63fe5c176d740233df6edd8d89/44727/save-first-with-failure-to-send.png 450w, /static/0fc82c63fe5c176d740233df6edd8d89/16786/save-first-with-failure-to-send.png 478w" sizes="(max-width: 478px) 100vw, 478px" loading="lazy" /> </a> </span></p> <p>However, now we've got a new problem. We successfully save the state but if we failed to send the messages. If we retry now, we'd risk doing the work again, creating duplicates or sending different (invalid) messages. This is a risk because the database could again be in a different state to the first attempt. In fact, the database will always be in a different state because we just wrote to it!</p> <p>We could also check to make sure we haven't already handled this message and abort processing, but then no messages would be sent at all. The process would stall, and data would fail to propagate.</p> <h3>Sending and Saving Atomically</h3> <p>What we really need is a way to do both at once. We need to store the updated state and any messages we intend to send inside a single transaction. We need this step to be atomic. If we look towards the database, we can achieve this by writing those messages to the database along with the state. In doing so, we won't leak messages before we save, and we won't lose them after either.</p> <h2>Using an Outbox</h2> <p>Saving our state and messages inside the same transaction is the core principle of the Outbox pattern. However, there's a bit more to do before we're finished. We still need to send the messages via the Outbox.</p> <p>Once the state and the messages have been persisted the next step is to <em>attempt</em> to send the messages in the Outbox. After the messages have been sent to the Service Bus we need to make a second update to the database, marking the messages as sent (dispatched).</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 478px;" > <a class="gatsby-resp-image-link" href="/static/83b69f9837a64e7b51c975153e54d998/16786/outbox-with-mark-as-sent.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 112.55230125523012%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAXCAYAAAALHW+jAAAACXBIWXMAAAsTAAALEwEAmpwYAAACiElEQVQ4y6WVy3ITMRBF/f+fwQdQQLECdiygiueSVDJx7BA/MrbL9ryf4lxFMnI8wwZVqVqalm53X11pJlmeG9O2Ji9LU9e16RlXWI1l+6Yx2ywzn5ZLa0N/Q18libna7cwGX8Paiek6M2fyaj43b+/vzQZgtd48tabvzcvZzLyIIrsm9C1I5g17fmy35jW+PQEmiqTJt83GfFgszMfVyi7u+qdth6oyX+LYPBaFtXvmvs3T1CxIRu2OTFcEsIDvAHr/8GCBvxMtBBTAzfFoxxF2FwDOAFQgD24BO+o+Avr58dF8JcsaCmxZDrCCs58EudrvrfV+mz37VK4CylewdiKCnzcP5q1axuLQ732qJCMp32zJlnw+Nmzqgw2+d2TVOcAwyMmvfW58BlgPZOuz8JWcBZOPYCW8+kAnQDl6ZSJgFjSua1xCfBuUdRHQZXgGqCgxErgTyUjnmh5xUNcI+hcK+H04WI3qVGO67Jb5lAOJkYzP/i8gzpKxzrBz4vXn2apkMpRtqMJ3zQu+p7ptbs8JMCHimgwLFuaUUGIlg5QNCdknBNRJJ6zP+aYuX6q5AB2nFxkW2ASRpoDrnutAWoAax+GFApQ1vksOAdoAMOOii7tovbZWvEXwt3dXLJSNn48Cjolc/KUBYCjsUUBxuKRUcSiuzro4c3d2qORadAxlKD21zEtKrwCQlRYLvYPBHX7e2iEdVgBuAZjzCEx5JKY8VTfwOEOXt4xXZB8P6PD2XzrMySbUoe/SmxQwpEO9RoM6lFwWRJK+MtelMWntSKCjAupX4X2uZ9Kh5/cMkI/1yAMgjkR8P3Yo+vf418YL1j5RI8T7J2z0cQh8k4wTtH84vSzO/k//A8EnBRqnpw1sAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Outbox sending messages then marking them as sent" title="Outbox sending messages then marking them as sent" src="/static/83b69f9837a64e7b51c975153e54d998/16786/outbox-with-mark-as-sent.png" srcset="/static/83b69f9837a64e7b51c975153e54d998/064a4/outbox-with-mark-as-sent.png 225w, /static/83b69f9837a64e7b51c975153e54d998/44727/outbox-with-mark-as-sent.png 450w, /static/83b69f9837a64e7b51c975153e54d998/16786/outbox-with-mark-as-sent.png 478w" sizes="(max-width: 478px) 100vw, 478px" loading="lazy" /> </a> </span></p> <p>However, there are still three separate actions being performed here, and any one of them may fail. We're safe if the first step fails because our system will still be in a consistent state. No messages are lost or leaked. However, if the second step fails, we'll still need to send those messages.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 478px;" > <a class="gatsby-resp-image-link" href="/static/200a47de33dbb09ae377ed06f306a274/16786/save-state-and-messages-with-failure-to-send.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 87.23849372384937%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB8klEQVQ4y62UW08bMRCF8/9/RV/7An2qqISQKvWFIkGlFlpE0DYJuSy5Z+/X6TeON3KWBfWBkUb2+njOjMfH24viWKQsJUpTyfNc6qKQjFHnOio22m7l+2wmSZZJafEC129vs5HH9VpC4nWtJ1UlXhjK6WAgn5+eZKMkWC17WxP00fPkQ78v33zfrFX1Hr1aLORiOjXrX0mo1ssI+DQcyo/lUr6Mx3I5nxugJJHaJIrkFxX4SSLXEBR2Xe2e6hJOUJLgD3PFenq088lEzqjuhCoVMIS2ijGESqp2B5Y7hL/5zuz3HUkNYUVPIvyGCnWxtkTNGJLw52olt2AP9NI98thWr3FeENgj25651iZVcytzMSUvnP3myCaAKgu8AVwvtE943caUsIUdCAuHsG0V1WmQzXZUoa67hRwIS5sp5jYDZBRaD+jNlt41hO0Km7gXhAlEzzR5SIP/Ig/jXJSHjB7R2QzyOeKds+/gfPfZrwLvJExbom5MNal91As4crAUsqyLcMcTXOAZiwkEOWPKGNOfkACVj8pLx9hKLcQD+2RfEKYAMfMl/fI5qrrOUzaFJKrBu6x2LuyIUC9jSaBPr6a7nUx4BTMIV2wejEZS4W3ZyFuXYv40jTS6qrDC/m/CRmv1K9KoWi+lU6P69NyGvof/A9m9L/6ur6HtAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Save messages and state to database then fail to send" title="Save messages and state to database then fail to send" src="/static/200a47de33dbb09ae377ed06f306a274/16786/save-state-and-messages-with-failure-to-send.png" srcset="/static/200a47de33dbb09ae377ed06f306a274/064a4/save-state-and-messages-with-failure-to-send.png 225w, /static/200a47de33dbb09ae377ed06f306a274/44727/save-state-and-messages-with-failure-to-send.png 450w, /static/200a47de33dbb09ae377ed06f306a274/16786/save-state-and-messages-with-failure-to-send.png 478w" sizes="(max-width: 478px) 100vw, 478px" loading="lazy" /> </a> </span></p> <h3>Retry based dispatch</h3> <p>Unlike our earlier attempt of saving first then sending to the service bus, this time we can take advantage of our new Outbox! Now if we encounter an error, we can retry processing the message except we'll only want to send the messages we already have.</p> <h3>Asynchronous dispatch</h3> <p>Messages that aren't redelivered after a failure, require us to also use some method of asynchronous dispatch. Either because the maximum number of tried was reached or because the message isn't configured to retry at all. Asynchronous dispatch allows us to check for unsent messages that fall through the cracks.</p> <h3>At least once delivery</h3> <p>After all that, we should now be in a position where a message will always be delivered to the Service Bus, <em>at least once</em>. At least once delivery is an unavoidable property of distributed messaging. Furthermore, we've been relying on it a bit already. When messages aren't successfully processed, aka there's a failure before the message is acknowledged, we depend on the message being redelivered so we can retry.</p> <p>So, on the delivery side, there could be a failure to deliver a message:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/85311166dcb1f8e13789de45c31d89e3/9435c/app-delivery-failure.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.61855670103093%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAArklEQVQY012Q3Q7CIAyFef9X8cr3MHqp8WouMf6EuMVtsFngeFpnoiP5oPTn0OJ8CNg3DSYRCCml/MENY0oGZl/OGblku1/7Hse2RWJccQeKraoK3esFXd+AoYV8ZOs9NkQFsiTEZ4MwBSZn7Ohf1zUi83Q5NVTMx4jHOJqA/IiqfeEUp67DxDztLiWxmNpa35PbMNjpZFZWx51YF4uRtVMhy+/4iCerP3P0lg29AQ/fOBxJmC0kAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Application failure and redelivery" title="Application failure and redelivery" src="/static/85311166dcb1f8e13789de45c31d89e3/fea0e/app-delivery-failure.png" srcset="/static/85311166dcb1f8e13789de45c31d89e3/064a4/app-delivery-failure.png 225w, /static/85311166dcb1f8e13789de45c31d89e3/44727/app-delivery-failure.png 450w, /static/85311166dcb1f8e13789de45c31d89e3/fea0e/app-delivery-failure.png 900w, /static/85311166dcb1f8e13789de45c31d89e3/9435c/app-delivery-failure.png 970w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>A failure while processing a message:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/92af90ab64b5f27b2d89ad8445cfc278/9435c/app-processing-failure.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.61855670103093%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAq0lEQVQY011Qyw7CIBDk/3/Fm9/ReNV4qlpjNMQ2FgrlNe6QNqluMrDsDMMuSk8Tjn2POUZEQSnlB7LAp1SBTT1XDnhai/MwIAlPqJOY7doWYwhgrERFzsjyyEFrNAIarlwkN1k03RX7WwcnOoZiQjPtHN7eV4O4MWX+kCku44hZdFmMWOcegsfHGVg5s1Mjd1VcnFl4CbCMsx2ZnbKj/++gLqdcNXdjMEhDXxnWOB3peRadAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Application failure and redelivery" title="Application failure and redelivery" src="/static/92af90ab64b5f27b2d89ad8445cfc278/fea0e/app-processing-failure.png" srcset="/static/92af90ab64b5f27b2d89ad8445cfc278/064a4/app-processing-failure.png 225w, /static/92af90ab64b5f27b2d89ad8445cfc278/44727/app-processing-failure.png 450w, /static/92af90ab64b5f27b2d89ad8445cfc278/fea0e/app-processing-failure.png 900w, /static/92af90ab64b5f27b2d89ad8445cfc278/9435c/app-processing-failure.png 970w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>Or a failure when sending messages a message acknowledgment, which may be lost even though the message was processed.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/7859d585c167b5eaffd63a3fa8792d83/9435c/app-ack-failure.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.61855670103093%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAqklEQVQY01WPzQ6CMBCE+/6v4sn3MHrUeEIS408aaaRQoC3jTAMJbvLRzU6Z7Rjb9zg3DcYYEck8z3/wgyGlAjbzvGhP73F1Dom6MBea7aoK7TRBtQqFnJG55GgtDkQGqxa1IEWcON/XNQLvqYwamdkQ8BmGYhA3puofTHFr25IiBI/x65C1jJr+9+TVdeU0cXHW4E2wxNlG1ksjKVF10mjttVR1Z3THB/0AHrY4F/ycApoAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Application failure and redelivery" title="Application failure and redelivery" src="/static/7859d585c167b5eaffd63a3fa8792d83/fea0e/app-ack-failure.png" srcset="/static/7859d585c167b5eaffd63a3fa8792d83/064a4/app-ack-failure.png 225w, /static/7859d585c167b5eaffd63a3fa8792d83/44727/app-ack-failure.png 450w, /static/7859d585c167b5eaffd63a3fa8792d83/fea0e/app-ack-failure.png 900w, /static/7859d585c167b5eaffd63a3fa8792d83/9435c/app-ack-failure.png 970w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>This means downstream services may receive messages more than once.</p> <p>Next up, On the dispatch side, if multiple messages are sent, some may get through, but a failure can make it impossible to know which messages are successfully delivered. Even if the messages are dispatched one at a time, messages may still be sent multiple times due to failures.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/9b0a0738f2f72825917f05d2afae9001/9435c/app-dispatch-failure.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.61855670103093%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAq0lEQVQY012P2wrCMBBE8/+/4pP/Ifqo+FQLopVgS9N7LuNMbEFcOCS7m8zOGjsMONc1Zu/hSUrpS4yIhAmmEDLYeiQS5c+uw7VpENgX5kKxXVHALQsUKuqxdy36oUVifrQWByKB/JGDvAaQE+v7ssRIMwqji8TsOOI9TYhyuk4Tuj+4xc05zHwn11svEv3vSNX3+TR+VVbhRbCuk37Ijkj6q2/iijtXb2joAw5VOB/7iCNXAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Dispatch failure and redelivery" title="Dispatch failure and redelivery" src="/static/9b0a0738f2f72825917f05d2afae9001/fea0e/app-dispatch-failure.png" srcset="/static/9b0a0738f2f72825917f05d2afae9001/064a4/app-dispatch-failure.png 225w, /static/9b0a0738f2f72825917f05d2afae9001/44727/app-dispatch-failure.png 450w, /static/9b0a0738f2f72825917f05d2afae9001/fea0e/app-dispatch-failure.png 900w, /static/9b0a0738f2f72825917f05d2afae9001/9435c/app-dispatch-failure.png 970w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>For these reasons (and few more I don't have time for right now) it's a good idea to make message processing idempotent. Or in other words, making them safe to process multiple times. As an added optimisation, we can also store the Id's of the messages we have successfully processed and use them to drop any duplicate messages. This can help us to avoid further unnecessary processing. Then we can jump straight to sending any unsent messages.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 299px;" > <a class="gatsby-resp-image-link" href="/static/6c10e78f3bc3fab8a03c66da4ddb6b01/b9a2f/transaction-inbox-outbox.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 41.47157190635451%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB6ElEQVQoz52SX0hTYRjGDxoEUhFWBBVElDd1EWiBhlAQBRLUdXcRBEGBRSO1lSaFShHdBLLE7Wxzfy4as2QgGuSSUdBFF+XsYnNnW3gmO3PbOfuXkL8+T2MXXfbBj+d7H14eeHlfqVAoYJRK6IaBvqWCgq6TF36+WGxosVhgq9dE/E3fJG9S1EVvPo9UrlQw1tcp53KUNM2EjQ3+5+mGjlQtl/mcTuNbWsJfJxiPM5NMMqMoBBMJPq6qpFIKyz+iRKPfSaQTRJQvhGOf+BCLEFp+z9f0NyqlMtJmtcqtSIS26WkOBwI0uVw0C5qcTrYJpMlJOkMhvG4HT8eGGX5sxeazccF5lTPjlzn1qoeWoWPcDPTBr99IiMDr4TCSLNPq9bLL42mwW9TNIvT83BwueQJL/x0eWu8jB2RO2y5xaLSDthfd7B85Se/bR2zW6oHXFhaQ7HZ2ipCWqakGOwSS7ODs7CxOx2vu9fXyYMCC/Y2djvEeDoy0c/R5F3uenOB20FoPrNW4sbhojrrP76fV52uwV9Tb3W4uzs/jcdvpt1oYHBzAFXTRNXGFI886Of7yHAfH2rn7buhvYEmcyapYdyybZUVs+F/iwk+LK9C0LKqqksmoaDmNVPYnibUkylqKFaFqLoOhG/wBInz2KWfArqoAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Transaction containing state, inbox and outbox" title="Transaction containing state, inbox and outbox" src="/static/6c10e78f3bc3fab8a03c66da4ddb6b01/b9a2f/transaction-inbox-outbox.png" srcset="/static/6c10e78f3bc3fab8a03c66da4ddb6b01/064a4/transaction-inbox-outbox.png 225w, /static/6c10e78f3bc3fab8a03c66da4ddb6b01/b9a2f/transaction-inbox-outbox.png 299w" sizes="(max-width: 299px) 100vw, 299px" loading="lazy" /> </a> </span></p> <p>We can refer to this as the Inbox. We also don't need to keep things in the Inbox forever. I usually opt to keep a certain window, such as Id's no longer than 30 minutes old, or the first few thousand.</p> <h3>Using a relational database</h3> <p>We've talked a lot about a database but not what kind of database because all that matters is that the Inbox, State and the Outbox are all inside the same transaction. In a relational database, I'll usually use a separate table for the Inbox and Outbox. The Outbox will usually have the following columns:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">- SequenceNo (Clustered Primary Key) - MessageId - AddedAt - Metadata (json) - MessageType - Payload (json) - Dispatched (bool) - DeliveredAt (datetime)</code></pre></div> <p>You can also remove messages from the Outbox after they're delivered and processed if they're of no further use.</p> <h3>Using a document database</h3> <p>You can also use the Outbox pattern with a Document database. However, it's typical for document databases not to have cross-document transactions. In this case, we can still achieve our requirement of keeping the Inbox and Outbox inside the transaction by storing them inside each document instead.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">{ id: &quot;product-1&quot;, name: &quot;phone (model x)&quot;, stockLevel: 9, backorderAvalible: false, inbox: [ &quot;m-1&quot;, &quot;m-2&quot;, &quot;m4&quot; ], outbox: [ { id: &quot;m-5&quot;, type: &quot;QuantityReserved&quot; ... } ] }</code></pre></div> <p>Many Document Databases will let you run queries so you can find unsent messages. If you're using Azure CosmosDB the change feed is a fantastic method of subscribing to changes through the database.</p> <h2>Final Notes</h2> <p>The real world often forces us to think about all the ways our software can fail. The Outbox presents a robust method of reliable message delivery in the face of failure. It's incredibly important to build this reliability into our systems. Otherwise, when things inevitably fail, data inconsistency and data loss will happen.</p> <p>As an industry, I worry that it's all too common to see companies delay or avoid implementing reliable messaging. Instead, hoping that these failures won't happen (yet). And while some of these failures can be rare, the alternative is often much worse. When message silently go missing or messages are leaked it can quickly become a big issue. One that's often difficult to resolve.</p> <p>Finally, I'd like to point out this certainly isn't the only way to tackle the problem of reliable messaging. But when it comes to messaging and a ServiceBus it's certainly an invaluable tool to have at your disposal.</p> <p>Happy Outboxing.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Why you need Reliable Messaging ]]>
</title>
<description>
<![CDATA[ You might have heard the phrase "there's no such thing as reliable messaging". It's an interesting statement, but aside from being… ]]>
</description>
<link>https://daniellittle.dev/why-you-need-reliable-messaging</link>
<guid isPermaLink="false">https://daniellittle.dev/why-you-need-reliable-messaging</guid>
<pubDate>Wed, 16 Jan 2019 00:00:00 GMT</pubDate>
<content:encoded><p>You might have heard the phrase "there's no such thing as reliable messaging". It's an interesting statement, but aside from being completely untrue, the statement is also entirely unhelpful. What you can't have is "completely reliable messaging", but the real question is how close can you get? How close do you need to get?</p> <p>The concept of Reliable Messaging is broad and can be somewhat complex at times. I won't get into all the details just yet. Instead, in this post, I'm going to establish what exactly Reliable Messaging is and why it's so important.</p> <h2>What is Reliable Messaging</h2> <p>Reliable messaging is the concept of commutating with certain guarantees about the successful transmission of messages. For example, if the message is delivered, that it is delivered at least once. In contrast, this can be compared best-effort delivery, where there is no guarantee that messages will be delivered at all. I'm going to focus on message delivery and reliability, but reliable messaging may also refer to message ordering. </p> <p>These guarantees don't need to be baked into the protocol or framework you're using either. An interesting property of reliable messaging is that you can add more reliability at higher levels. You can build reliable protocols on top of unreliable protocols. The best example of this is TCP which is built on top of the IP protocol.</p> <p>The most important aspect of Reliable Messaging is, at the end of the day, the only way to know if something is done is by receiving a message saying it was done. But before I explore exactly why Reliable Messaging is so important, I'll go on a brief tangent to have a look at why you can't have Completely Reliable Messaging.</p> <h2>Why you can't have Completely Reliable Messaging</h2> <p>Reliable Messaging can't provide complete reliability for a number of reasons, but you only need one negative example to disprove something is not absolute. In a distributed system the receiver could be faulty, offline, or explosively dismantled and spread around all corners of the globe. Even if the receiver works perfectly, the communication medium may be unreliable in many different ways. The sender may also be unreliable, it may crash, or simply contain a bug or other logic error. You can't guarantee anything in a world where anything can fail, but you can plan for failures.</p> <h2>What makes Reliable Messaging important?</h2> <blockquote> <p>It is necessary to understand how a system can fail and how to deal with failures when they inevitability occur. </p> </blockquote> <p>When building any kind of distributed system it is important to know what guarantees are needed. Otherwise, the default is always best-effort delivery. Which means the system will loose data, without anyone knowing when, why or how. Even if there are no errors, exceptions or obvious signs. If messages fail to be propagated you might not realise anything went wrong for days, or months, or at all. </p> <p>Issues like this also tend to be expensive to track down and fix. Because they're found so late they may also end up being impossible to track down and fix. The core problem is, it is necessary to understand how a system can fail and how to deal with failures when they inevitability occur. In this sense, Reliable Messaging is a means to an end. </p> <p>Given that the core problem is dealing with failures, there are situations where you just don't need reliable messaging. In some systems manual monitoring and alerts could be enough; however, this is usually more indirect and coarse. Some actions may not be important at all, in which case best effort would suffice. If an action is user-driven then the user could manually retry instead. Otherwise, if you don't want to be manually adding reliability, because that get's expensive really quickly, then having a good strategy for Reliable Messaging is very important.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Automatic ModelState Validation for ASP.NET Core ]]>
</title>
<description>
<![CDATA[ Model State Validation for a JSON API isn't too hard because you only need to send back validation errors, especially with the attribute… ]]>
</description>
<link>https://daniellittle.dev/automatic-modelstate-validation</link>
<guid isPermaLink="false">https://daniellittle.dev/automatic-modelstate-validation</guid>
<pubDate>Mon, 02 Jul 2018 10:35:58 GMT</pubDate>
<content:encoded><p>Model State Validation for a JSON API isn't too hard because you only need to send back validation errors, especially with the <code class="language-text">ApiController</code> attribute. However, for all those that are still using server-side rendering and Razor, it's still a bit challenging.</p> <p>It's challenging because you need to return the correct <code class="language-text">View</code> after posting a form. And the easiest method of getting the job done is writing this type of code in each <code class="language-text">Action</code>.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">if</span> <span class="token punctuation">(</span>ModelState<span class="token punctuation">.</span>IsValid<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">RenderTheGetForm</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>It does the job, but it's usually a lot of extra, tedious, code.</p> <p>Instead we can keep the <code class="language-text">Controller</code>s lean by shifting this code into an <code class="language-text">Action Filter</code> attribute which can be used similarly to the <code class="language-text">ApiController</code> attribute. So I decided to write one and publish it.</p> <p>Here's how it works. You install the <code class="language-text">AutomaticModelStateValidation</code> package and drop the <code class="language-text">AutoValidateModel</code> attribute on the <code class="language-text">action</code> that uses a View Model and validation.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token punctuation">[</span><span class="token class-name">Route</span><span class="token punctuation">(</span><span class="token string">"/[controller]"</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SubmissionController</span> <span class="token punctuation">:</span> <span class="token class-name">Controller</span> <span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token class-name">HttpGet</span><span class="token punctuation">]</span> <span class="token keyword">public</span> <span class="token class-name">ActionResult</span> <span class="token function">NewSubmission</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Load data for the blank form</span> <span class="token keyword">return</span> <span class="token function">View</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">NewSubmissionViewModel</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">[</span><span class="token class-name">HttpPost</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token punctuation">[</span><span class="token class-name">AutoValidateModel</span><span class="token punctuation">(</span><span class="token function">nameof</span><span class="token punctuation">(</span>NewSubmission<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token keyword">public</span> <span class="token class-name">RedirectToActionResult</span> <span class="token function">SaveSubmission</span><span class="token punctuation">(</span><span class="token class-name">SaveSubmissionViewModel</span> model<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Save submission to database</span> <span class="token keyword">return</span> <span class="token function">RedirectToAction</span><span class="token punctuation">(</span><span class="token function">nameof</span><span class="token punctuation">(</span>ViewSubmission<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token punctuation">{</span> Id <span class="token operator">=</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">[</span><span class="token class-name">HttpGet</span><span class="token punctuation">]</span> <span class="token keyword">public</span> <span class="token class-name">ActionResult</span> <span class="token function">ViewSubmission</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Load submission from database</span> <span class="token keyword">return</span> <span class="token function">View</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">ViewSubmissionViewModel</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span></code></pre></div> <p>The <code class="language-text">AutoValidateModel</code> attribute on the <code class="language-text">SaveSubmission</code> <code class="language-text">Action</code> performs the <code class="language-text">ModelState.IsValid</code> check. If the model is valid everything continues as normal, however, if the model is invalid then the specified fallback <code class="language-text">Action</code> in is invoked and the <code class="language-text">ModelState</code> from the previous <code class="language-text">Action</code> is merged in.</p> <p>This means you're able to render the invalid <code class="language-text">Form</code> with validation messages and the appropriate HTTP status code with a single line of code!</p> <p>If you want to get started, grab the <a href="https://www.nuget.org/packages/AutomaticModelStateValidation/">Automatic ModelState Validation</a> NuGet package. And keep reading if you're interested in some more of the details.</p> <h2>The deep dive</h2> <p>One of the highlights of this attribute is to invoke the fallback action programmatically without another round trip to the client. In the past, I've achieved similar functionality by temporarily storing the ModelState and redirecting to the previous action. However, this time around I have made use of the advancements in <code class="language-text">AspNetCore</code> to bypass that step entirely.</p> <p>The bulk of the code resides in the <code class="language-text">AutoValidateModelAttribute</code> which implements the <code class="language-text">ActionFilterAttribute</code> class. After first checking that the <code class="language-text">ModelState</code> is invalid the next step is to determine check controller action to invoke.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> controllerName <span class="token operator">=</span> <span class="token function">SansController</span><span class="token punctuation">(</span>controller <span class="token operator">??</span> context<span class="token punctuation">.</span>Controller<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>If the controller isn't explicitly specified then the fallback is the <code class="language-text">Type</code> name of the controller. Here I also remove the <code class="language-text">Controller</code> suffix.</p> <p>Next, I have to locate the relevant <code class="language-text">ActionDescriptor</code> by getting the <code class="language-text">IActionDescriptorCollectionProvider</code> and finding the matching descriptor.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> controllerActionDescriptor <span class="token operator">=</span> actionDescriptorCollectionProvider <span class="token punctuation">.</span>ActionDescriptors<span class="token punctuation">.</span>Items <span class="token punctuation">.</span><span class="token generic-method"><span class="token function">OfType</span><span class="token punctuation">&lt;</span><span class="token class-name">ControllerActionDescriptor</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">FirstOrDefault</span><span class="token punctuation">(</span>x <span class="token operator">=></span> x<span class="token punctuation">.</span>ControllerName <span class="token operator">==</span> controllerName <span class="token operator">&amp;&amp;</span> x<span class="token punctuation">.</span>ActionName <span class="token operator">==</span> action<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>To invoke the <code class="language-text">ActionDescriptor</code> the next thing I'll need is an <code class="language-text">ActionContext</code>. Here is also where I pass along the previous <code class="language-text">ModelState</code> so the validation errors are carried through to the new <code class="language-text">Action</code>.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> actionContext <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ActionContext</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span>HttpContext<span class="token punctuation">,</span> context<span class="token punctuation">.</span>RouteData<span class="token punctuation">,</span> controllerActionDescriptor<span class="token punctuation">,</span> context<span class="token punctuation">.</span>ModelState<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>The last major piece is getting an <code class="language-text">IActionInvokerFactory</code> to create a <code class="language-text">ControllerActionInvoker</code> and then invoking it.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">var</span> actionInvokerFactory <span class="token operator">=</span> <span class="token generic-method"><span class="token function">GetService</span><span class="token punctuation">&lt;</span><span class="token class-name">IActionInvokerFactory</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> invoker <span class="token operator">=</span> actionInvokerFactory<span class="token punctuation">.</span><span class="token function">CreateInvoker</span><span class="token punctuation">(</span>actionContext<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">await</span> invoker<span class="token punctuation">.</span><span class="token function">InvokeAsync</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div> <p>After that, there was just one more problem to fix. When no <code class="language-text">View</code> is explicitly specified when returning a ViewResult, AspNet Mvc will fall back to using the action name from <code class="language-text">RouteData</code>. Because I'm invoking a second Action inside a single Request the wrong view will be used unless I update the <code class="language-text">RouteData</code> to match. So, I also set the action name to the name of the fallback action before calling the <code class="language-text">ControllerActionInvoker</code>.</p> <div class="gatsby-highlight" data-language="csharp"><pre class="language-csharp"><code class="language-csharp"><span class="token keyword">if</span> <span class="token punctuation">(</span>context<span class="token punctuation">.</span>RouteData<span class="token punctuation">.</span>Values<span class="token punctuation">.</span><span class="token function">ContainsKey</span><span class="token punctuation">(</span>ActionNameKey<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> context<span class="token punctuation">.</span>RouteData<span class="token punctuation">.</span>Values<span class="token punctuation">[</span><span class="token class-name">ActionNameKey</span><span class="token punctuation">]</span> <span class="token operator">=</span> controllerActionDescriptor<span class="token punctuation">.</span>ActionName<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre></div> <p>If you're interested in the full source code you can check it on <a href="https://github.com/Lavinski/AutomaticModelStateValidation">GitHub under Automatic ModelState Validation</a>.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Running .NET on the Raspberry Pi ]]>
</title>
<description>
<![CDATA[ I recently got my hands on an older Raspberry Pi, which was a great excuse to see if I could get .NET running on it! If you're interested in… ]]>
</description>
<link>https://daniellittle.dev/running-mono-on-the-raspberry-pi</link>
<guid isPermaLink="false">https://daniellittle.dev/running-mono-on-the-raspberry-pi</guid>
<pubDate>Mon, 27 Nov 2017 04:59:57 GMT</pubDate>
<content:encoded><p>I recently got my hands on an older <a href="https://www.raspberrypi.org">Raspberry Pi</a>, which was a great excuse to see if I could get .NET running on it! If you're interested in playing around with a Pi or just want to see what it's like to get one running, then you're in the right place. I'll take you through setting it up, installing some programs and compiling some C# on the device with a few failures along the way.</p> <p>I knew this Raspberry Pi was an older model, but I wasn't entirely sure what model it was. Figuring that out seemed like a good first step because that might impact what OS I can run. Plus I wanted to make sure the model I had was able to run <code class="language-text">.NET</code>. So my first challenge was to figure out what model I had.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 737px;" > <a class="gatsby-resp-image-link" href="/static/040c9c3b9e8c28d20dfa158974f24f2a/7dae4/PiModelB1Cleaned-1.jpg" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 68.24966078697422%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAEDAgX/xAAVAQEBAAAAAAAAAAAAAAAAAAACAf/aAAwDAQACEAMQAAABpqDJ64yr/8QAGhABAQACAwAAAAAAAAAAAAAAAQMCEQAEFP/aAAgBAQABBQJ7FB9TvCo4s1SPJY6n/8QAFREBAQAAAAAAAAAAAAAAAAAAECH/2gAIAQMBAT8Bp//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABsQAAIBBQAAAAAAAAAAAAAAAAABIRAyQWGR/9oACAEBAAY/ArlyikwaFCP/xAAbEAACAwADAAAAAAAAAAAAAAAAAREhQTFhcf/aAAgBAQABPyGGdgfGpDOdtofs+jJxyFoOg//aAAwDAQACAAMAAAAQCx//xAAXEQEAAwAAAAAAAAAAAAAAAAAAAREh/9oACAEDAQE/EIsx/8QAFhEBAQEAAAAAAAAAAAAAAAAAEQAB/9oACAECAQE/EE1sS//EABwQAQACAwEBAQAAAAAAAAAAAAEAESExQVFhcf/aAAgBAQABPxByqDx1dT3gUNCX1+kKG106iWU0ysZxyNJfIVHT8/ImwisF45P/2Q=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="A Raspberry Pi, Model B, Gen 1" title="A Raspberry Pi, Model B, Gen 1" src="/static/040c9c3b9e8c28d20dfa158974f24f2a/7dae4/PiModelB1Cleaned-1.jpg" srcset="/static/040c9c3b9e8c28d20dfa158974f24f2a/40f63/PiModelB1Cleaned-1.jpg 225w, /static/040c9c3b9e8c28d20dfa158974f24f2a/df2c7/PiModelB1Cleaned-1.jpg 450w, /static/040c9c3b9e8c28d20dfa158974f24f2a/7dae4/PiModelB1Cleaned-1.jpg 737w" sizes="(max-width: 737px) 100vw, 737px" loading="lazy" /> </a> </span></p> <p>At first glance, it looked like it would be a bit more difficult than I was expecting because there's no clear version number printed on the board and quite a few variations which are very similar. I found <a href="https://en.wikipedia.org/wiki/Raspberry_Pi">Wikipedia</a> to be the best way to identify a Raspberry Pi. It lays out each model nicely and shows the mounting holes, components, ports and logo which you can use to determine your exact model.</p> <p>From there I was able to determine that the model I had was the Model B (Gen 1). Now that I knew what I was dealing with, it was time to see if I could get it to boot. For that, I needed an <a href="https://elinux.org/RPi_SD_cards">SD card that would work</a>, a USB Micro cable and a <a href="https://www.raspberrypi.org/blog/power-supply-confirmed-as-5v-micro-usb/">USB adapter</a>. Luckily, I had more than enough phone chargers and a few old SD cards lying around.</p> <p>My first few attempts at getting the Pi to boot were completely unsuccessful. To this day I don't know if it was because of the SD cards I tried or the <a href="https://developer.ubuntu.com/core/get-started/raspberry-pi-2-3">Raspberry Ubuntu image</a> I tried. But I may have run into almost every issue you can have (probably not, but it sure felt like it) and the quite extensive <a href="https://www.raspberrypi.org/forums/viewtopic.php?t=58151">guide to troubleshooting boot issues</a> didn't help either. However, somewhere along the way, I got my first image on screen!</p> <p><img src="/../../images/running-mono-on-the-raspberry-pi/IMG_20170820_135411.jpg" alt="Rainbow Square on Monitor"></p> <p>Is that the Raspberry Pi rendering a nice rainbow square on screen? No, it's actually just rendering four pixels that have been scaled up to fit the screen. This happens when the <a href="https://raspberrypi.stackexchange.com/questions/19354/raspberry-pi-with-boots-up-with-rainbow-screen">GPU firmware successfully loads</a> but then something later in the boot process goes wrong, such as an invalid image on the SD card. Although you'd be forgiven for mistaking it with the <a href="https://www.raspberrypi.org/forums/viewtopic.php?f=91&#x26;t=95430">small rainbow square</a> in the top right that indicates a low voltage from the power supply.</p> <p>After trying a few different SD cards, I decided to ditch Ubuntu and try one of the <a href="https://www.raspberrypi.org/downloads/">officially supported images</a>. I decided to try NOOBS first, which is an operating system installer that lets you pick from a few different operating systems including Raspbian (the official Raspberry Pi OS). This time I had a bit more luck, not much more, but more nonetheless. The Pi successfully booted! I pick Raspbian and wait for it to install.</p> <p><img src="/../../images/running-mono-on-the-raspberry-pi/IMG_20170820_143942.jpg" alt="NOOBS installing Raspbian"></p> <p>And wait. And wait. I think it got to about 20% before refusing to progress any further. It may have just been really really slow, but I was starting to consider that maybe there's something wrong with the device. At this point, I'd been at it for a while, so I decided to leave it for another weekend.</p> <p><em>One Month Later</em></p> <p>I find myself looking at a <a href="https://raspberry.piaustralia.com.au/">Raspberry Pi Zero W</a>, they're cheap and relatively easy to get. But not "already on my desk waiting for me" cheap. It's time to give this thing one last shot.</p> <p>This time it's straight to Raspbian, in particular, Raspbian Lite (which doesn't contain a GUI). I skipped over the process of getting the OS onto the SD card earlier, but I wanted to point out how nice it is. Once you've <a href="https://www.raspberrypi.org/downloads/raspbian/">downloaded the image file</a>, which is just a zip, in this case, you use <a href="https://etcher.io/">Etcher</a> to write the image to the card. It's a three-step process of selecting the image, choosing the drive and clicking start, it's fast and flawless. I plug in the mouse, keyboard and monitor, insert the SD card, and plug in the power. And it Boots!</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/c513adc162c672efaf35c051205da375/53a76/PiBootSequence.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 76.90742624618515%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAA7DAAAOwwHHb6hkAAADM0lEQVQozxXRV2/iCBQFYL+uAjHNxhXcsDEdTE0IA4GYHno1ppgaSCBVq1VmVpmMNKv51+tIR/ft07lXF4BBIymQ1IVQlhvFSvNGrtdv+0W5kc2VKrVuPJHmXW6bxQoajCaD4dxwBp6dWQxntnOj3QwCdhBESQR1k7Vqt9+fD8faYLzs9ubV20FvuLxtja7zlatMAUUw0AiaQNB0fm4FQchswmxWADGZERxBXY5CvtpqK52Omr9plKr9Sn1Yb07kSk+KpgOBBAITVrPNZrXqW0BWyG6DCBgGELPN4eXYq2A+WyvVerUvo1QbSrmutPpava3GErloPIOhtB3CYQizw4geFEFxFAXsFsjp513ZSLc1741W6uJ+qOwGyt1Q3c/Xz+P5QywlO2gvijEQTKCIE0McGErgKE7iBGC3wlRQZHNSqzEbTQ+94Wak7merl+nqefvwrmgnRXvsjnepTDkc/4biHE4wOM44cMZJ0ABiQ6igj87F5Jt+q78u1ia3HW24OBUbark1C8TzfiknBq5w0kOQHgTjUIzVPYZRDoLVMUq63VRS6nTX7eFuoJ7602NHPZTac2/0GmVCBBdx8pJLTPJi0u1J8G5JECV/MMFxXgC2oTCs/4rVa5f79+nqb+3uXbv/sTp97B5/lttapaNVuloy1wgni1JCjiVlKZ67SJfcHgmAIAyyOzFMaPa3i7vvivY22/wzWrx8qyiXcv9KHiSyzdBFOZQqSqlSIJJjuDDNBijG52S8OsbtTpdDDDc6u8HstTt5Wuz/VZZvo8VbZ/rUVo+N0T6ebQaScjRdCcUKrBB1CRFOCDGcT8ckLviYeGoweZ7vfiwPH9rhQ5+b48f64Wd7csrX1FimcVnoilKOdEUYd5zhwxwfolk/YLEgCCU4fdHh9PXu6ff+8b/t8fP+9c/29Gtz+kxet72xvC9W0MOHMrSYoIUoJYRpl44DgMUIO8JBvpgbjF8nm/f1w+f9y5/l4VPdfv+6QjkW6irnS1FfRnLyYQcXJDm/g/URrAcw/GWyIgRCcTQbYVxx3nfJ+9O8Ly0EM3wwHYzlOU+MdkdYUaL4kM5I1kPQIkEJhNP1Py/CzqlD3Qr7AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Pi Boot Sequence" title="Pi Boot Sequence" src="/static/c513adc162c672efaf35c051205da375/fea0e/PiBootSequence.png" srcset="/static/c513adc162c672efaf35c051205da375/064a4/PiBootSequence.png 225w, /static/c513adc162c672efaf35c051205da375/44727/PiBootSequence.png 450w, /static/c513adc162c672efaf35c051205da375/fea0e/PiBootSequence.png 900w, /static/c513adc162c672efaf35c051205da375/53a76/PiBootSequence.png 983w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>If you're wondering why that picture is so much clearer than the others, it's because I've switched from using a TV to a computer monitor. I didn't time how long it took, but I'd take a guess the Pi took around a minute or so to boot. After which I was prompted to log in.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Raspbian GNU/Linux 9 raspberrypi tty1 raspberrypi login:</code></pre></div> <p>There's already a default user. A quick search for the <a href="https://www.raspberrypi.org/documentation/linux/usage/users.md">default credentials</a> reveals Pi's secrets (u: <code class="language-text">pi</code> p: <code class="language-text">raspberry</code>). And I'm in!</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 719px;" > <a class="gatsby-resp-image-link" href="/static/fc6dd56a35f6799d43addfe78c160d75/04c1a/PiFirstBoot--2-.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 31.710709318497916%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsSAAALEgHS3X78AAABU0lEQVQY0w3C606CUAAAYJ5BWTXn3LwDogKpiOA5eIDDDoJ4yfsdKxVctFm/6uHr20dJ5fTMw54FfWL2MdLVNlAUBIAqtxuSVMjn6UTikaafksknOvE//ZDMpmixlAFCnpIr2Z97/B3ffGIRy1DlpsBXKwwrClKpxDAMly+UWJbnuArP86Ig1rmKLIl8LtWpZimJzQwwHNjIJzZGCGia3GqrKoS6qQGjh4jS0RtNVdfNHjKh3sOm5WDbhhruNqhmtXh7D+5xHBwOl/M1DD82u9Mlitfb0z64Hl6j+9fvbLkfvSzWm+N0vnLdwXQ08R3HQRpVY3Jjtz/yXK/vEuLCnmWRgeNPZ6vjZL4bztbL7Wmzf1O6SHhuKSoAEHbaClvINWtlqs4Vw/ByjcJLFO2D8+n8OV8H3nhhO0NMfIgI0HHfHRvYbSldCA3DsDStW+N5War+AUOUXZMzeiltAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Loging into the Pi" title="Loging into the Pi" src="/static/fc6dd56a35f6799d43addfe78c160d75/04c1a/PiFirstBoot--2-.png" srcset="/static/fc6dd56a35f6799d43addfe78c160d75/064a4/PiFirstBoot--2-.png 225w, /static/fc6dd56a35f6799d43addfe78c160d75/44727/PiFirstBoot--2-.png 450w, /static/fc6dd56a35f6799d43addfe78c160d75/04c1a/PiFirstBoot--2-.png 719w" sizes="(max-width: 719px) 100vw, 719px" loading="lazy" /> </a> </span></p> <p>The first thing I noticed was that the keyboard layout was different. Typing the pipe symbol <code class="language-text">|</code> instead inserted a hash <code class="language-text">#</code> which indicated a <code class="language-text">UK</code> keyboard layout. Most settings for the Raspberry Pi can be updated by entering the command <code class="language-text">sudo raspi-config</code>. You can also change your password and <a href="https://www.raspberrypi.org/documentation/remote-access/ssh/">enable SSH</a> from there.</p> <p>The steps to change the keyboard layout are fairly straightforward. Well, except for selecting a non-UK keyboard because those are all grouped under <code class="language-text">Other</code>. Here's the complete set of steps in case you were wondering.</p> <ol> <li>Select Internationalization menu</li> <li>Select keyboard setup menu.</li> <li>Select your keyboard (or pick one of the generic models)</li> <li>Select [Other]</li> <li>Select [English (US)]</li> </ol> <p>Now I had a fully functioning Pi. So it was time to see if I could install some variant of .NET on it, either <code class="language-text">.NET Core</code> or <code class="language-text">mono</code>. What you can run depends on the CPU of the Pi you have. But there are two main versions, <code class="language-text">arm v6</code> and <code class="language-text">arm v7</code>. All the specifications are on the same <a href="https://en.wikipedia.org/wiki/Raspberry_Pi">Wikipedia page</a> I mentioned earlier but if your Pi is running you can also use the following command.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&gt; uname -m armv61</code></pre></div> <p>You might have noticed that the same moniker is printed in the welcome message after you log in. The Raspberry Pi I have contains an <code class="language-text">armv61</code> chip the same as the Pi Zero. This is a different model from the new chip in the Raspberry Pi 3 which contains an <code class="language-text">arm v7</code> chip. Unfortunately .NET Core (and a few other languages such as node) currently only support the newer <code class="language-text">arm v7</code> architecture. This limited my options a bit, but, it turns out that Mono does support <code class="language-text">arm v6</code>. At this point, I can see the light at the end of the tunnel. I now have a method for running .NET on the Raspberry Pi.</p> <p>I still wasn't sure if I'd be able to compile .NET on the device or just run applications, so it was time to get empirical. There are two Mono packages you can install via <code class="language-text">apt-get</code>. The runtime <code class="language-text">mono-runtime</code> and everything, <code class="language-text">mono-complete</code>, which includes the compiler. I thought I'd take a stab at installing <code class="language-text">mono-complete</code>.</p> <p>The <code class="language-text">apt-get update</code> command is for updating the local package cache, so I'll get the latest version of the Mono package.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">sudo apt-get update sudo apt-get install mono-complete</code></pre></div> <p>My luck's really coming about now. Mono installs successfully, first time!</p> <p>Time to compile some code. I already had some C# I wanted to try out on the device, and I need my monitor back to get it. So it was time to switch to <code class="language-text">ssh</code> so I can access the Pi remotely. I used chocolatey to install openssh.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">choco install openssh</code></pre></div> <p>Plugged the Pi into the network, and realised I had no idea what the IP address was. A friend of mine had pointed me towards <code class="language-text">arp</code> earlier that day. A great little tool that lists all the IP addresses of devices on your local network. And while I quickly realised it is much nicer on unix-like systems, because it displays hostnames whereas I had to revert to manually looking them up (via <code class="language-text">nslookup</code>), it was still very useful.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&gt; arp -a Interface: 10.1.1.227 --- 0x13 Internet Address Physical Address Type 10.1.1.1 aa-bb-cc-dd-ee-1f dynamic 10.1.1.29 aa-bb-cc-dd-ee-2f dynamic</code></pre></div> <p>There weren't too many devices on my local network. I even chanced upon the correct Pi address on my first try.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&gt; nslookup 10.1.1.29 Name: raspberrypi.lan Address: 10.1.1.29</code></pre></div> <p>Now that I knew the IP address, I could ssh into the Pi and do the rest remotely.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">ssh [email protected]</code></pre></div> <p>The file I had to copy was fairly small, and I could have copied the file over with <code class="language-text">scp</code> but echoing out the contents into a file worked for me. Here's how to write hello world to a file.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">echo &#39;using System; namespace RaspberryPi { public class Program { public static void Main(string[] args) { Console.WriteLine(&quot;Hello World&quot;); } } }&#39; &gt; app.cs</code></pre></div> <p>Then it was just a case of compiling the program and running it.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&gt; mcs app.cs &gt; mono app.exe Hello World</code></pre></div> <p>So there we have it! Starting with an unidentified Raspberry Pi, some old SD cards and a phone charger. I managed to (eventually) successfully compile and run a .NET application.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ cURL to Postman ]]>
</title>
<description>
<![CDATA[ Postman is a fantastic tool for testing any HTTP endpoint. But if you're using your browser to look around and you find something of… ]]>
</description>
<link>https://daniellittle.dev/curl-to-postman</link>
<guid isPermaLink="false">https://daniellittle.dev/curl-to-postman</guid>
<pubDate>Tue, 14 Nov 2017 00:18:32 GMT</pubDate>
<content:encoded><p>Postman is a fantastic tool for testing any HTTP endpoint. But if you're using your browser to look around and you find something of interest it can be a pain to recreate the request in Postman and copy across all the headers. There must be a better way!</p> <p>Turns out there is! Chrome and Postman both have support for cURL which makes it easy to copy any request from Chromes dev tools and into Postman. You can also export any Postman request as a cURL command which makes sharing much easier as well.</p> <p>In the Chrome Network tab, you can copy a request via a selection of formats. <span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 649px;" > <a class="gatsby-resp-image-link" href="/static/38474732d8a48ecdc75febc3b781c3fe/9a22e/Curl.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 45.76271186440678%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABM0lEQVQoz22QWVLDMBBEff97cQb4gRRJiG1to32zZNFOfkKRLpWW1rzRaKaVSxdzyrXUVmonbRUZbZwPkQuVy2Z9wNDWczKXhYWQe+s+FjJ+ui7i87zcFn75mbkkAFwQE8qFJMhgKLKlbtcbe7/OlLYPld7WkMpOrk5KScbWkrM1kHbOGk0ppa0WKSUXLMY4xmCMkZSjNe7jxYYd1ylNvffWGibApEkphei+70h6gr5O3+czTK11qRV+72Ps0Ohbm8Z9jxTOOXO8br33MEspHGJ8WdZ417Zt8AEjxUG1BzxQTlNSCinYynLOMGutQgjQcLQxz/D+DI87jMIUkRAqhgDHWbfMy22e5fGRYK19DT/KjgExwTtU7RCH5WjGXTg+WvP6ZVyjK3T0S2GPD6Ph46/+w7+ApQX2lKcCIAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Chrome Copy as cURL" title="Chrome Copy as cURL" src="/static/38474732d8a48ecdc75febc3b781c3fe/9a22e/Curl.png" srcset="/static/38474732d8a48ecdc75febc3b781c3fe/064a4/Curl.png 225w, /static/38474732d8a48ecdc75febc3b781c3fe/44727/Curl.png 450w, /static/38474732d8a48ecdc75febc3b781c3fe/9a22e/Curl.png 649w" sizes="(max-width: 649px) 100vw, 649px" loading="lazy" /> </a> </span></p> <p>Once you have your cURL request you can then use the import command and paste in the cURL command. <span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/91d9ae8a226bcf932ddc277160b65b39/3d4e0/PostmanFromCurl.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 68.39126919967664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAB6klEQVQoz4WRy4+aUBTG+Rd9dGIVpm3S2U+btE0qicoFLsg0XfjcK7rvvovu+hhHoVE7ca2C4aG2gIOgPTi1nVoz/fJBDveeH+fjQnz88L7z5dPnyw74qqdEVpSuqu78dV/srCg9Jdq9UtROr3fZ7RLPzzLnj04yZCSKItMP0w+SyXgslkwkUifJRDwOBsXicSqdfkKSqVTqMZU5JTPUKUUglmMREgWMhUgcFz3mcrlsNkvT2d+iaZrjeIz5AmKfvuCe0VFNRAzm4dqxAlPIq6rquq5l24vFwnEcqF3Pu/H9RqNRyOcRj89e4vPXLOYQwQuisJcoiiyTv77+tt1ufd8PgiAMw00Yrt1luHLa7TaEupCKby/ENxL0ioRQlIp3BNH6/T4MtG17Pp/DcCgs0/Acp9VqsYiRRJiGgYTmf2COg9iWZWmaNplMZrOZpulgeJ0sywyDABL2YQ9hWILJpmmOx2PgAdZ1HYYDHMVmWUn6038EHgwGEBjI6XRqGAbU9vK75weyDLHRfTDGeDQawYH9Oq3NJgzWwVxfL4xGs/WfyQAPh0OAV6vVDXgdeKa2lF/9eCc1m010/2Q4xlKpVK/Xa7VatVqtVCrlchluUMEuz/N3mw/h28/Gx3T7e/6CeeHIqnRMBwFBPwFBSBM+HLysugAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Postman From Curl" title="Postman From Curl" src="/static/91d9ae8a226bcf932ddc277160b65b39/fea0e/PostmanFromCurl.png" srcset="/static/91d9ae8a226bcf932ddc277160b65b39/064a4/PostmanFromCurl.png 225w, /static/91d9ae8a226bcf932ddc277160b65b39/44727/PostmanFromCurl.png 450w, /static/91d9ae8a226bcf932ddc277160b65b39/fea0e/PostmanFromCurl.png 900w, /static/91d9ae8a226bcf932ddc277160b65b39/3d4e0/PostmanFromCurl.png 1237w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>It took me a while to find out how to export the request, it's hidden under the <code class="language-text">code</code> link. <span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/9e66e97eee027dccf3293f5bb332e76a/3d4e0/PostmanMain.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 68.39126919967664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7CAAAOwgEVKEqAAAAB3UlEQVQ4y31TTY/TMBDNb+YOWqltui0tEtJy48B/4ILECe2BTdOyEj+AA4hGSmk+2sR2EjtvZ5y4hBKI9DSeeTPPM+PWe/z0AV+De3wOAsIG4e4Lgu0WQdiDzhuOOT8M8UDYbnd47HPDnt/Q2bt/O8XHu+dYvFxhvVphRZhNp5hOJhbLWx93r5aY+z7mcx/+bIYJ8a+XS7xZLPDi5ga3zBHW6zW8JMuRZylMXaGqazRNg7IUOJ9OUKLE/76acqWUkFWNWinU4gxPUlElCihFBAUVIU0SJEmKwzHBr+MRSZoiz/MrnFCec/w8nPDs/RnvHjKI9ACvlKRMnVUVo7IdFkUBWRYoKEGQVRQv2aou18JOUqKgaeKcmkhzqOgHvMa0f4xhjEEcx1A0SqsboO14vogFmWe0FO+s4SoL9knQ2IK2L9RaY7/fI8syux/T89yVEMKKMvgCrrHC1nYa/xTkcQydh4K8Co47uE4vwmMdcjCKItvNMM77ZUHdX3It5nL/EmTLhSzAxTwaW/cYzncx9ocYFXRiQ7iueA3NFTfEqKA7D7/fe2Kuw0gaCfbBdlBoRi7hF+e91vQH2H2X+BbzjvXldS+CSpZ2hOvXGvoMN1JrNKJcIxO6++0NeN7hE0niJVtAAIMaAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Postman Main" title="Postman Main" src="/static/9e66e97eee027dccf3293f5bb332e76a/fea0e/PostmanMain.png" srcset="/static/9e66e97eee027dccf3293f5bb332e76a/064a4/PostmanMain.png 225w, /static/9e66e97eee027dccf3293f5bb332e76a/44727/PostmanMain.png 450w, /static/9e66e97eee027dccf3293f5bb332e76a/fea0e/PostmanMain.png 900w, /static/9e66e97eee027dccf3293f5bb332e76a/3d4e0/PostmanMain.png 1237w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>From there you can export the request into a wide variety of formats. <span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/9fe97ebc489345c509cff81eb866ad4d/3d4e0/PostmanExport.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 68.39126919967664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAB7ElEQVQoz4WS72vTQBjH8wf6xjSkk8b6ar4W0RdrM6fN5Wf9C8QKpv03FIW+cNqatWuhUGm7DmGwTdauSe6SS87nkgXZrPjhy8PdcV++zx2P8OXzh/63w6+9/mGv7w2G3nB4U7mOiwXXYHgM+j4YwIX+0VHP84Snu5Unj+SKojxUlJ1yWRTFksiRSqUdWSoV2/uiWJakB5Iky7JSqYCq1aqgIR1pmm2ZQKPR0DP291+odVWtA2qher22V6vtaRoyTbhtmDoSTMuyTAOKYRie512v1xGH0CRKkpiLRpSx6OwH/viWjD+9eefee/xy9zmYNcGwbMu2LcuGwNFohDEmBG+usb9JcMBwyAhmEWHEj8nVhobBe9dVDzSEdAvMltN0MiB8PB6HIQ5C/+qSnp2yzSrl/oClScoykiRpt9uGrr/mJvuuOYpijIOL8+jnkl2cp78u2XrN/CD1AxaEDBNuhh6bTe66Zc7b9n0f44gmLI4ZVC6aCU7ov82QDM7VakVpzLaRt/2fZPjudBuUUtd1EUL8xfbtN08mkziOCSGQsDUZ/J1OZ7u52+3OZrPpdDqfz5cZJwWnyxPYLRaLVqsFE3G37dwPc5bXHJSh6+iZimoHCMbJdv4AE2ZCA85fNDNu1o7zynB00ykOeM/Ab9uYTGjE7wRyAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Postman Export" title="Postman Export" src="/static/9fe97ebc489345c509cff81eb866ad4d/fea0e/PostmanExport.png" srcset="/static/9fe97ebc489345c509cff81eb866ad4d/064a4/PostmanExport.png 225w, /static/9fe97ebc489345c509cff81eb866ad4d/44727/PostmanExport.png 450w, /static/9fe97ebc489345c509cff81eb866ad4d/fea0e/PostmanExport.png 900w, /static/9fe97ebc489345c509cff81eb866ad4d/3d4e0/PostmanExport.png 1237w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>And there we have it, Chrome to cURL to Postman and back again.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Dynamically calling a Function in FSharp ]]>
</title>
<description>
<![CDATA[ Sometimes you just want to make a dynamic call. There is no equivalent for in so I guess we'll have to roll our own. In this post I'll go… ]]>
</description>
<link>https://daniellittle.dev/dynamically-calling-a-function-in-fsharp</link>
<guid isPermaLink="false">https://daniellittle.dev/dynamically-calling-a-function-in-fsharp</guid>
<pubDate>Sat, 11 Feb 2017 06:16:03 GMT</pubDate>
<content:encoded><p>Sometimes you just want to make a dynamic call.</p> <p>There is no equivalent for <code class="language-text">Func&lt;&gt;.DynamicInvoke</code> in <code class="language-text">FSharpFunc</code> so I guess we'll have to roll our own. </p> <p>In this post I'll go though how to build a function called <code class="language-text">dynamicInvoke</code> which you use like this:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let sayHello name = printfn &quot;Hello %s!&quot; name let objectResult = dynamicInvoke sayHello [&quot;Daniel&quot;] let typedResult = objectResult :&gt; string // typedResult = &quot;Hello Daniel!&quot;</code></pre></div> <p>The example above starts off with a normal FSharp function that takes a typed argument, in this case, a <code class="language-text">string</code> and returns a <code class="language-text">string</code>. Then <code class="language-text">dynamicInvoke</code> is used to call the function with a list of arguments which returns the result as an object.</p> <p>You could also use <code class="language-text">dynamicInvoke</code> on its own to build a function with the signature <code class="language-text">obj seq -&gt; obj</code>. Which I'd say is the functional equivalent of <code class="language-text">DynamicInvoke</code>, just what we're looking for!</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let dynamicFunction = dynamicInvoke sayHello</code></pre></div> <p>The actual signature of <code class="language-text">dynamicInvoke</code> therefore is as follows <code class="language-text">obj -&gt; obj seq -&gt; obj</code>. In other words, it takes the original function (as an object), an <code class="language-text">obj seq</code> for the arguments and returns an object, which is the result of the original function.</p> <h2>How it works</h2> <p>At its core, the solution is to use standard .NET reflection to dynamically invoke <a href="https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/core.fsharpfunc%5B%27t,%27u%5D-class-%5Bfsharp%5D?f=255&#x26;MSPPError=-2147217396"><code class="language-text">FSharpFunc&lt;&#39;T,&#39;U&gt;.Invoke : &#39;T -&gt; &#39;U</code></a>. The other tricky bit involves how functions work in FSharp.</p> <p>In FSharp, functions that take multiple parameters return a function that takes the rest of the parameters. Which itself is a function that takes a single parameter and does the same. All of these functions take a single parameter. So we could also say, there is no such thing as a function that takes multiple parameters! </p> <p>Let's have a look at a function with multiple parameters:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let sayHello name age = printfn &quot;Hello %s, you are %i years old!&quot; name</code></pre></div> <p>The type hierarchy of this <code class="language-text">sayHello</code> function will contain the following type:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">FSharpFunc&lt;string, FSharpFunc&lt;int, string&gt;&gt;</code></pre></div> <p>In order to dynamically invoke the function, each <code class="language-text">FSharpFunc</code> that makes up the function can be invoked recursively until a result is reached. And because <code class="language-text">FSharpFunc</code> is a standard .NET type we can get the <code class="language-text">MethodInfo</code> for <code class="language-text">Invoke</code> and dynamically invoke it!</p> <p>For each argument, the function is partially applied. The code below does exactly this, using reflection to get the <code class="language-text">MethodInfo</code> for the <code class="language-text">Invoke</code> method and calling <code class="language-text">Invoke</code> on it. Such invoke.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">let partiallyApply anyFSharpFunc argument let funcType = anyFSharpFunc.GetType() // Guard: FSharpType.IsFunction funcType let invokeMethodInfo = funcType.GetMethods() |&gt; Seq.filter (fun x -&gt; x.Name = &quot;Invoke&quot;) |&gt; Seq.head methodInfo.Invoke(anyFSharpFunc, [| argument |])</code></pre></div> <p>Now, all it takes to call a function is to recursively partially apply it until we run out of arguments to apply. Add some error handling and we're done! The complete code is below and I'll also publish a NuGet package shortly.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">open System open FSharp.Reflection type InvokeResult = | Success of obj | ObjectWasNotAFunction of Type let dynamicFunction (fn:obj) (args:obj seq) = let rec dynamicFunctionInternal (next:obj) (args:obj list) : InvokeResult = match args.IsEmpty with | false -&gt; let fType = next.GetType() if FSharpType.IsFunction fType then let (head, tail) = (args.Head, args.Tail) let methodInfo = fType.GetMethods() |&gt; Seq.filter (fun x -&gt; x.Name = &quot;Invoke&quot; &amp;&amp; x.GetParameters().Length = 1) |&gt; Seq.head let partalResult = methodInfo.Invoke(next, [| head |]) dynamicFunctionInternal partalResult tail else ObjectWasNotAFunction fType | true -&gt; Success(next) dynamicFunctionInternal fn (args |&gt; List.ofSeq )</code></pre></div> <p>Now it's possible to dynamically call any FSharp function!</p> <p>A quick word on error handling. This function can fail if something other than a function is invoked. Sadly there's no <code class="language-text">IAmAFunction</code> marker interface. So the only option is to use a runtime check and return a <code class="language-text">ObjectWasNotAFunction</code> <code class="language-text">InvokeResult</code>.</p> <p>This is an explicit failure of this function and therefore an explicit result is returned. Exceptions caused by invoking the function, however, are exceptional, and never caught (except at the application boundary), so they pass right through.</p> <p>If you found this post useful, I'd love to hear about it. So leave a comment if you found this post interesting or if it helped you out! </p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Comparing MicroBus and MediatR ]]>
</title>
<description>
<![CDATA[ Mediators are an excellent addition to the developer toolbox. Allowing you to define a pipeline that is decoupled from any particular… ]]>
</description>
<link>https://daniellittle.dev/comparing-microbus-and-mediatr</link>
<guid isPermaLink="false">https://daniellittle.dev/comparing-microbus-and-mediatr</guid>
<pubDate>Sat, 07 Jan 2017 02:09:43 GMT</pubDate>
<content:encoded><p>Mediators are an excellent addition to the developer toolbox. Allowing you to define a pipeline that is decoupled from any particular framework. Having a pipeline makes it easy to deal with cross cutting concerns like security, transaction, validation and others. For these reasons and more using a Mediator has become quite a popular choice. They are also used to improve other aspects of an application in regards to structure and architecture. </p> <p>Recently there have been a few such Mediator libraries pop-up for .NET including MediatR, GreenPipes and MicroBus. I started MicroBus back in 2015 and have used it in a number of projects since. So I thought now would be great to talk a bit about MicroBus and what it does. In this post, I will be comparing MicroBus and MediatR, so that you can see the similarities and differences. </p> <p>But before I begin, I'd like to say; I think both MediatR and MicroBus are great solutions to these problems. I've made some different choices along the way, however, both these projects had similar origins (aka doing it numerous times before making a package), have similar goals and tackle similar problems.</p> <h2>Wire Up</h2> <p>I'll start with how to wire-up the Mediators, which involves firstly registering them to a dependency injection container.</p> <p>With MicroBus I wanted to ensure the experience was the same regardless of which container you prefer. It's syntax, is, therefore, a little more succinct than out of the box MediatR.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus autofacContainerBuilder.RegisterMicroBus(busBuilder);</code></pre></div> <p>MediatR takes the approach of zero dependencies and provides the following sample for setting up MediatR with Autofac.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MediatR var builder = new ContainerBuilder(); builder.RegisterSource(new ContravariantRegistrationSource()); builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly).AsImplementedInterfaces(); builder.RegisterAssemblyTypes(typeof(Ping).GetTypeInfo().Assembly).AsImplementedInterfaces(); builder.RegisterInstance(Console.Out).As&lt;TextWriter&gt;(); builder.Register&lt;SingleInstanceFactory&gt;(ctx =&gt; { var c = ctx.Resolve&lt;IComponentContext&gt;(); return t =&gt; c.Resolve(t); }); builder.Register&lt;MultiInstanceFactory&gt;(ctx =&gt; { var c = ctx.Resolve&lt;IComponentContext&gt;(); return t =&gt; (IEnumerable&lt;object&gt;)c.Resolve(typeof(IEnumerable&lt;&gt;).MakeGenericType(t)); });</code></pre></div> <p>However that's not entirely fair, the actual implementation for MicroBus is relatively similar under the covers. MicroBus also currently only provides an Autofac extension. Although you can set-up any other container manually. The Autofac implementation itself consists mainly of this file <a href="https://github.com/Lavinski/Enexure.MicroBus/blob/master/src/Enexure.MicroBus.Autofac/ContainerExtensions.cs">ContainerExtensions.cs</a> and uses a resolver and scope class similar to ASP.NET MVC instead of factories for resolving dependencies. If you'd like to request a particular container, then feel free to open a GitHub issue.</p> <p>MicroBus wire-up is slightly more complex in two places, validation, which ensured command and requests only have a single handler and Registrations which support singleton and transient registrations, which is useful for transparently doing complex registrations that can completely change how handlers work. MicroBus uses this to provide Saga support something I'll write more on in a later post.</p> <h2>Pipeline and Handler Registration</h2> <p>Next, we'll take a look at how to register handlers and how to create a pipeline.</p> <p>Again I wanted to ensure that registration for MicroBus was consistent across containers and that the concept of a pipeline was a first class citizen. There are two main types of handlers in MicroBus, Global/Delegating Handlers which execute for every message and Message handlers which sit at the end of the pipeline.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus var busBuilder = new BusBuilder() // Global Handlers run in order so these are explicitly registered .RegisterGlobalHandler&lt;LoggingHandler&gt;() .RegisterGlobalHandler&lt;SecurityHandler&gt;() .RegisterGlobalHandler&lt;ValidationHandler&gt;() .RegisterGlobalHandler&lt;TransactionHandler&gt;() // Scan an assembly to find all the handlers .RegisterHandlers(assembly);</code></pre></div> <p>Global handlers run in the order they are registered then Message Handlers are executed. The Delegating Handlers are also Task-based which uses <code class="language-text">async</code> in contrast to before and after methods. Again this is very similar to ASP.NET WebApi and ASP.NET Core, which use a similar approach.</p> <p>Another one of the goals I had in mind when building MicroBus was Safety. To help prevent you from doing the things you probably don't want to be doing anyway. MicroBus supports three message types, commands, events and queries. Each of these types have different semantics which are enforced through validation. Only a single command handler can be registered for a command. The same goes for queries. Events, however, can have multiple handlers (polymorphic handlers are also supported) but no return types.</p> <p>Registration via MediatR up until very recently (about two days ago) didn't provide any abstractions, so registrations were made directly via the container with decorators. Leaving the pipeline to the container removed a fair amount of complexity from MediatR and delegates it to the container. The trade-off here though is that the user may have to deal with the complexity instead.</p> <p>MediatR 3.0 now also provides support for pipelines which makes registration much easier for all containers.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MediatR builder.RegisterGeneric(typeof(IPipelineBehavior&lt;,&gt;)).As(typeof(LoggingBehaviour&lt;,&gt;)); builder.RegisterGeneric(typeof(IPipelineBehavior&lt;,&gt;)).As(typeof(SecurityBehaviour&lt;,&gt;)); builder.RegisterGeneric(typeof(IPipelineBehavior&lt;,&gt;)).As(typeof(ValidationBehaviour&lt;,&gt;)); builder.RegisterGeneric(typeof(IPipelineBehavior&lt;,&gt;)).As(typeof(TransactionBehaviour&lt;,&gt;));</code></pre></div> <h2>The API</h2> <p>The primary interface you use to send commands to MicroBus is the <code class="language-text">IMicroBus</code> interface.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus public interface IMicroBus { Task SendAsync(ICommand busCommand); Task PublishAsync(IEvent busEvent); Task&lt;TResult&gt; QueryAsync&lt;TQuery, TResult&gt;(IQuery&lt;TQuery, TResult&gt; query) where TQuery : IQuery&lt;TQuery, TResult&gt;; }</code></pre></div> <p>This interface is strongly typed and enforces that a given message type is used with the matching method. MicroBus also provides a secondary generic <code class="language-text">IMicroMediator</code> interface which can be used with untyped MessageHandlers, we'll look at these a bit later. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus public interface IMicroMediator { Task SendAsync(object message); Task PublishAsync(object message); Task&lt;TResult&gt; QueryAsync&lt;TResult&gt;(object message); }</code></pre></div> <p>With most choices in MicroBus, I've gone for the opinionated option to get better compile-time safety or better validation. This interface, however, offers much fewer guarantees. In some brownfield projects especially those which already followed a similar pattern but had messages that didn't use the MicroBus marker interfaces, this is extremely useful. </p> <p>The MediatR interface is very similar to the IMicroBus interface. It has the three primary methods for Commands, Request/Queries and Events but using different names. One nice feature here is the support for CancellationTokens. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MediatR public interface IMediator { Task&lt;TResponse&gt; Send&lt;TResponse&gt;(IRequest&lt;TResponse&gt; request, CancellationToken cancellationToken = default(CancellationToken)); Task Send(IRequest request, CancellationToken cancellationToken = default(CancellationToken)); Task Publish&lt;TNotification&gt;(TNotification notification, CancellationToken cancellationToken = default(CancellationToken)) where TNotification : INotification; }</code></pre></div> <p>These interfaces are probably the most similar part of the two libraries. It's also interesting to see that MediatR also took the type-safe route here. One thing I did find slightly confusing was that MediatR uses IRequest with no Response for its commands.</p> <h2>Message Handlers</h2> <p>So far we've covered how to register handlers, and how to send messages to them. Next up is how they are defined. In MicroBus there are three typed handler interfaces and one generic handler interface for the IMicroBus and IMicroMediator interfaces.</p> <p>The three typed interfaces are for each of the message types, commands, queries and events.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus ICommandHandler&lt;Command&gt; IQueryHandler&lt;Query, Result&gt; IEventHandler&lt;Event&gt;</code></pre></div> <p>Here is what a command handler would look like in MicroBus. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus class CommandHandler : ICommandHandler&lt;Command&gt; { public async Task Handle(Command command) { Console.WriteLine(&quot;Command handled!&quot;); } }</code></pre></div> <p>It's worth mentioning that EventHandlers support polymorphic dispatch so a <code class="language-text">IEventHandler&lt;AnimalEscaped&gt;</code> and <code class="language-text">IEventHandler&lt;LionEscaped&gt;</code> would fire if <code class="language-text">LionEscaped</code> inherits from <code class="language-text">AnimalEscaped</code> (MediatR also supports this). </p> <p>The generic handlers are also quite similar. However, in this case, there's only one interface because it's impossible to know what the message will be based on its type. If you're implementing a command or event, you would typically return Unit.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MicroBus class Handler : IMessageHandler&lt;Message, Unit&gt; { public async Task&lt;Unit&gt; Handle(Message message) { return Unit.Unit; } }</code></pre></div> <p>MicroBus is also split up into four main parts.</p> <ul> <li>The core package</li> <li>Infrastructure contracts, which include <code class="language-text">IMicroBus</code> and the <code class="language-text">IHandler</code> interfaces</li> <li>Message contracts, which includes <code class="language-text">ICommand</code>, <code class="language-text">IQuery</code>, <code class="language-text">IEvent</code> and <code class="language-text">IMessage</code></li> <li>Dependency Injection Extensions</li> </ul> <p>Splitting up MicroBus into multiple packages is a nice feature that lets you selectively include the parts of MicroBus you depend on. Most commonly you see Message Contracts defined in a library that depends only on <code class="language-text">MicroBus.MessageContracts</code>.</p> <p>MediatR's Handler are quite similar the main distinction being that MediatR provides both async and synchronous versions of each interface. The example below shows an async command handler.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MediatR class CommandHandler : IAsyncRequestHandler&lt;Command&gt; { public async Task Handle(Command message) { Console.WriteLine(&quot;Command handled!&quot;); } }</code></pre></div> <p>Overall you can see a lot of similarities with a few defining features.</p> <h2>Delegating Handlers</h2> <p>We've already talked a bit about Pipeline and Handler registration and this one of the most useful features of a Mediator. MicroBus has first class support for pipelines and makes writing cross-cutting code effortless.</p> <p>To start, you implement IDelegatingHandler which has a similarly looking handle method. One of the nice things about IDelegatingHandler is that don't need a constructor, and if you need dependencies, you don't need to worry about where the "inner" handler goes. Instead, the next handler is passed along through <code class="language-text">Handle</code> keeping the scope of the variable as small as possible. Delegating Handlers are also registered globally which means that you'll only need to register them once and they'll run for every type of message.</p> <p>The example below shows how you could create a global handler which wraps every message handler in a database transaction. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MiroBus public class DatabaseTransactionHandler : IDelegatingHandler { public async Task&lt;IReadOnlyCollection&lt;object&gt;&gt; Handle(INextHandler next, object message) { using (var transaction = database.NewTransaction()) { return await next.Handle(message); transaction.Commit(); } } }</code></pre></div> <p>Delegating Handlers also make use of async and await which means you can make using of <code class="language-text">using</code> and <code class="language-text">try</code> as opposed to having a before and after method.</p> <p>MediatR didn't have a global pipeline until recently. Before which made registering cross-cutting code for every handlers somewhat tedious. The latest version 3.0 puts it on par in this respect and the handlers which are called Behaviours are again quite similar. The snippet below shows an example of a behaviour in MediatR.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// MediatR public class MyBehavior&lt;TRequest, TResponse&gt; : IPipelineBehavior&lt;TRequest, TResponse&gt; { public async Task&lt;TResponse&gt; Handle(TRequest request, RequestHandlerDelegate&lt;TResponse&gt; next) { //Before var response = await next(); // After return response; } }</code></pre></div> <h2>What's next</h2> <p>Mediators are a great addition to the developer toolbox letting you deal with cross cutting concerns without tying your application to a UI, web or service framework. We've looked at wire-up, declaring and registering handlers, usage, and pipelines while comparing MicroBus and MediatR. </p> <p>I hope I've been able to show you a bit about MicroBus and what makes it different. So if you're used a mediator before (or if you haven't) I'd recommend trying MicroBus out for yourself, I'm always looking for feedback and suggestions. You can get the get the bits on github here <a href="https://github.com/Lavinski/Enexure.MicroBus">Enexure.MicroBus</a>.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Event Sourcing: What properties should Domain Events have? ]]>
</title>
<description>
<![CDATA[ What I learned since last time A while ago I wrote about Generating Read Models with Event Sourcing where I suggest adding derived… ]]>
</description>
<link>https://daniellittle.dev/event-sourcing-what-properties-should-domain-events-have</link>
<guid isPermaLink="false">https://daniellittle.dev/event-sourcing-what-properties-should-domain-events-have</guid>
<pubDate>Mon, 31 Oct 2016 08:46:13 GMT</pubDate>
<content:encoded><h2>What I learned since last time</h2> <p>A while ago I wrote about <a href="/generating-read-models-with-event-sourcing/">Generating Read Models with Event Sourcing</a> where I suggest adding derived properties to the persisted domain events also known as Enriched Events. Since writing that post, I have been using this approach. However, over time I found that this was not the solution I was hoping for. In short enriching events also has some problems and recently I have switched over to using only delta style events for persisted events. In this article, I will cover the problems that come from enriching events and suggest a (better) alternative solution to the question "What properties should Events have?".</p> <h2>What problem is Event Enriching meant to solve?</h2> <p>When a Domain Event is raised, it is published to several interested handlers. The first of these is the Apply Method whose job it is to update the state of the Aggregate. Because the Aggregate is the primary source of an event, it has access to all the updated state. The problem stems from needing to pass some of this data to the other interested handlers.</p> <p>If we look at a bank account, the event would be a transaction resulting in a changed account balance. The other interested handlers could be Read Model Generators, other event handlers or even other services. Some of these are almost certainly interested in the current balance of an account. In this case, Enriching the <code class="language-text">Transaction Added</code> event would involve adding the Current Balance to the events. Enriching solved the issue of easily providing information to all the interested handlers. More importantly, though, it ensured that there is only one place where derived state is calculated.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 468px;" > <a class="gatsby-resp-image-link" href="/static/bbccbcce497d6b6be0967e8039604999/bb106/Before.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 56.41025641025641%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABoElEQVQoz2VSQU/bMBTOnx0XEBIgBFKvTBrjgDjvMu3Aph1hSJvGhdNU1BYqioRQYSVQ0sSxn+0kdpo4Ni+tKAWsJ/k9P32f3/fZnrVuFlVlnXN5PqaUJUkqZcK5EELyepPGVNjFJI4pA14UpfcejKdRRBgDKSQwAOCEEADxDBZBEIyCkVLaQwDGK4qaoV7GOl6656o+t5NCVU4jj3WenTUna74sKnubFPPdmte6WBuWGyw9VIgy0jTFMTD0uDwZir++OL4XR3f8cMB/+/yPz38NoBMm0zFYXvFxLcFD2MNwGDwGhNAYtSXqc49uX8LHC9Y4j1fbZLlFVlpk4ZR8uaLO1hg6A8/mnO5ZXuz24u0e+9SjO5escUbWO2SzgxTR12s6VfUCfmOYqeyDUHdc+VzdguqS1J/kA8hImk9venWztS8+zRtWIlFWvrcT3oyNtnEhE5nqvDj4z7/34ecN/OjDfp9hjsm3a3YylIWpjLWhNjAP1lr7vo+vD0m21SUb7ajRidZa4WIzXGqGy83ww79w7yIayHGgzH1WavwD1j0Bj+ZnoLDmuAEAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Diagram, Derived properties are calculated in the behaviour" title="Diagram, Derived properties are calculated in the behaviour" src="/static/bbccbcce497d6b6be0967e8039604999/bb106/Before.png" srcset="/static/bbccbcce497d6b6be0967e8039604999/064a4/Before.png 225w, /static/bbccbcce497d6b6be0967e8039604999/44727/Before.png 450w, /static/bbccbcce497d6b6be0967e8039604999/bb106/Before.png 468w" sizes="(max-width: 468px) 100vw, 468px" loading="lazy" /> </a> </span></p> <p>Sending derived properties to other handlers and services is an important problem that Enriching Events was able to resolve. So it is equally important to ensure that the new solution solves this problem as well. But first, we'll look into what the problems with Enriching Events are.</p> <p>As a side note, there are still cases where other handlers for an event keep track of their own running totals or tallies (derived state). However, this is usually because it is data that the Aggregate does not care about and does not already calculate or store. In which case, no logic is being duplicated anyway.</p> <h2>Ok so what’s wrong with Enriching Events</h2> <p>There are a few problems that come from enriching Events which you can avoid by using delta only Events.</p> <h3>Redundant Data</h3> <p>One of the core ideas in event sourcing is storing a list of all the changes that have happened to an Aggregate. By playing back these events you can determine the state of the Aggregate at a point in time. Because the system is deterministic, you will arrive at exactly the same state every time.</p> <p>For a bank account given all the deposits and withdrawals ever made can determine what the current balance is. If you were to store the current balance along with every transaction, you would have to store much more data for little benefit. In fact, it stops us from using other nice features of Event Sourcing.</p> <h3>You can’t do Replay Testing</h3> <p>Replay testing allows you to use all your current production data as test data for your application. The derived state will be re-calculated using the events as they are replayed. Comparing the results of different versions can then be used to spot any divergences and fix them before they make it to production.</p> <p>The one downside to this is that we must do slightly more work when replaying events. However, processing events in memory is extremely quick and loading the data is usually the bottleneck anyway. Lots of events can still slow things down, but you can use Snapshotting to win back even more performance.</p> <h3>No Concurrency for Aggregates</h3> <p>Concurrency is probably the biggest issue with Enriched Events. Looking at the <code class="language-text">Transaction Added</code> event for a bank account. If the balance total is part of the event, then it forces you to process all behaviours in serial. This is what it looks like if we add the current balance to the event.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Event Amount Total TransactionAdded 50 50 TransactionAdded -20 30 TransactionAdded 10 40 Total 40</code></pre></div> <p>But what happens when both the second and third event occurs at the same time.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Event Amount Total TransactionAdded 50 50 TransactionAdded! -20 30 TransactionAdded! 10 60 Total 60 // Should be 40</code></pre></div> <p>If we do not handle concurrency at all, the total from the first event will get overridden by the total from the second event. This would be terrible! Optimistic Concurrency is the next level and a good default, in this scenario, a concurrency exception is thrown instead. This works well for cases where you cannot do work in parallel.</p> <p>However, if the model does not need the totals to process transactions (at least not in a completely consistent manner), then the order does not matter anymore. You will still end up with 40 regardless of the order you process the behaviours in. So, we can be a bit clever and for transactions that do not conflict, try to insert it again automatically. Speeding up the time it takes to process events.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Event Amount TransactionAdded 50 TransactionAdded -20 TransactionAdded 10 Total 40</code></pre></div> <p>Even if behaviours cannot be processed in parallel such if we needed the balance to be completely consistent inside the aggregate, we can derive the totals so we can still avoid persisting them.</p> <h3>Unfocused Events</h3> <p>Enriched Events contain all the derived properties as well as the deltas which can leave you with quite large events. I have found that in most cases individual handlers will only care about one or the other, deltas or totals. For our bank account example if we want to publish the current balance we could have two events instead of one giant event. The first event would still be <code class="language-text">Transaction Added</code> and the second would be <code class="language-text">Balance Changed</code>. If you were updating a SQL Read Model you would probably have two tables (transaction and balances) and an event handler for each table, so two events align perfectly.</p> <h2>Multiple events to prevent duplicating logic</h2> <p>Using multiple events is also how we will deal with sending derivable state to other handlers. The second event, which includes the derived state, won't be persisted at all. I'll call this a transient event. The Persisted Domain Events that the behaviour creates are created as normal. However, Transient events need to be handled a little differently because they need the internal state from after the <code class="language-text">Apply</code> method is called. Adding a Handle method for behaviours that executes after the Apply method gives us a chance to let the world know about derived or calculated data.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 468px;" > <a class="gatsby-resp-image-link" href="/static/1d3fc22890389a84327493ec52eb08e0/bb106/DomainEvents-1.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 78.41880341880342%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACUklEQVQ4y4VU2W7TQBT1h/LAKwioyhPQFiJU+owqvgUBRSpla9SSNG1KhYQUmsTOxHbG8b7bhzuTpaljxJVOrudOfHLuFqUsgQWKopQ+TTPwCYfreXBdD9OpDdt2CDY9TxHHKYRFUQzDMMH5FEEQyneVOsIsy+mLBkxzAsdxYHELljWlsyljcTIjjOMYmqqBMUakXMYUQbIOLI344WZAfhNCMf/xxb0/vxQxBRUrS6xZz03XLuSRPsK0gOrP7oUQJQgCRGFE8hMJkW7b8PBZc/B95Ep/MLSl/0I4IjSZiySbyYqyEizMpFSpsN/vYzgYQtcNjNgYvudj/4pjt2thr8vx9GyCxy0Tj04NbBAenJrYahtwo2ROWIAFK4TVVIXCN1cTvLyw8IoI9y4tIufY7kzwjMj/S1jXlF/cR0v3cE6pdwjHlKLw4tymeNf0kBKRIJEpVwlX613XFBbm68ESN4SrNZzNXTZrCs1XnhdS3aFKDaGmHGkuPg4dfNJEg1zpj281pYBWrWEYhuj1/uD6ug+PNmO3Y+Bec4yNEx33yd/9xpa485XhYXNEJfCl8gGNjCEyqKa83BZSKBS8H9hS2QHhbd+W5w8DB+/IH6oO/CRDSu+meXlr05TFwxI1NRxHBeqsbm2VoljfgGmUQg8olTl+2zHGfgIzTCU4IZ8TLIQsFXo0yOpQhUpLLmootmb/0sCTH2M8b+vYITTOyLfG2CJsnjA0WgzefA6rJVNEV8XfUEhEIfmMOv36J21Ix8KLC46dc07ekn6bsNmaoEFD/i/Cv6P8uuNWxlyGAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Diagram" title="Diagram" src="/static/1d3fc22890389a84327493ec52eb08e0/bb106/DomainEvents-1.png" srcset="/static/1d3fc22890389a84327493ec52eb08e0/064a4/DomainEvents-1.png 225w, /static/1d3fc22890389a84327493ec52eb08e0/44727/DomainEvents-1.png 450w, /static/1d3fc22890389a84327493ec52eb08e0/bb106/DomainEvents-1.png 468w" sizes="(max-width: 468px) 100vw, 468px" loading="lazy" /> </a> </span></p> <p>Now, when a behaviour is run the persisted event is raised, Apply updates the state, and the Handle method will run. Giving you a place to raise transient events as well. After the behaviour is finished all these events are then published.</p> <p>Rebuilding the Read Model will also require the transient events to be regenerated. However, we can completely skip the Handle method when Hydrating an Aggregate from an event stream.</p> <h2>Persisted Domain Events</h2> <p>Now we have small delta only events in our event store, the door is open to leveraging the real power of Event Sourcing. It is much easier to keep other handlers informed and avoid duplicate code. Events are more focused, smaller and easier to work with. There are more options for dealing with concurrency. And you can make use of Replay Testing to eliminate a broad range of regressions.</p> <p>So, what properties should Events have? Persisted events should only store what they need, typically only the change or the delta. The rest can be derived from there.</p> <hr> <p>I am currently building a more Functional Event Sourcing library for C# called <a href="https://github.com/Lavinski/Eventual">Eventual</a>. It's my playground for Event Sourcing ideas and a good place to dig into some real code. It is, however, an early alpha and still a work in progress, so it doesn't cover everything in this post. Nevertheless, I still recommend you take a look if you want a peek under the covers.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Links to Get Started with React and Redux ]]>
</title>
<description>
<![CDATA[ Getting started to React and want to get right to it? These are the links you're looking for. What you need! First up you’ll need Node… ]]>
</description>
<link>https://daniellittle.dev/links-to-get-started-with-react-and-redux</link>
<guid isPermaLink="false">https://daniellittle.dev/links-to-get-started-with-react-and-redux</guid>
<pubDate>Wed, 12 Oct 2016 22:38:46 GMT</pubDate>
<content:encoded><p>Getting started to React and want to get right to it? These are the links you're looking for.</p> <h3>What you need!</h3> <p>First up you’ll need Node: <a href="https://nodejs.org.au/">https://nodejs.org.au/</a></p> <p>You can get the React tooling here: <a href="https://github.com/facebookincubator/create-react-app">https://github.com/facebookincubator/create-react-app</a></p> <p>Once you have React you’ll want Redux: <a href="https://github.com/reactjs/react-redux">https://github.com/reactjs/react-redux</a></p> <p>That’s all you need to get started!</p> <h3>Browser Extensions</h3> <p>React Developer Tools, great for debugging state: <a href="https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en">https://chrome.google.com/webstore/detail/react-developer-tools</a></p> <p>Redux Developer Tools, amazing for debugging state and time travel debugging: <a href="https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en">https://chrome.google.com/webstore/detail/redux-devtools</a></p> <h3>Extra Resources</h3> <p>The how and why of React apps: <a href="https://css-tricks.com/learning-react-redux/">https://css-tricks.com/learning-react-redux/</a></p> <p>A random super simple example Redux app: <a href="https://github.com/tstringer/create-react-app-with-redux">https://github.com/tstringer/create-react-app-with-redux</a></p> <h3>Extra packages for better redux apps</h3> <p>If you need to make ajax calls this is the best was to do it: <a href="https://github.com/yelouafi/redux-saga">https://github.com/yelouafi/redux-saga</a></p> <p>For caching updates to speed things up: <a href="https://github.com/reactjs/reselect">https://github.com/reactjs/reselect</a></p> <p>Remove magic strings in actions and reducers: <a href="https://github.com/pauldijou/redux-act">https://github.com/pauldijou/redux-act</a></p> <p>Happy coding! :)</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ There is always time to write clean code ]]>
</title>
<description>
<![CDATA[ The number one most important thing you can do in software development. Always leave the code base cleaner than when you found it. Always… ]]>
</description>
<link>https://daniellittle.dev/there-is-always-time-to-write-clean-code</link>
<guid isPermaLink="false">https://daniellittle.dev/there-is-always-time-to-write-clean-code</guid>
<pubDate>Sun, 22 May 2016 00:40:02 GMT</pubDate>
<content:encoded><p>The number one most important thing you can do in software development. Always leave the code base cleaner than when you found it. Always aim to improve things.</p> <p>I recently stumbled on a <a href="https://www.thebesttechpodcastintheworld.com/2016/05/21/episode-001/">fantastic podcast</a> by <a href="https://twitter.com/sitapati">Joshua Wulf</a> featuring <a href="https://twitter.com/DamianM">Damian Maclennan</a> who brilliantly described why this is so important.</p> <blockquote> <p>If you see a professional chef vs. a home cook, they enjoy cooking, but they end up with a mess all over the kitchen bench, but if you watch a professional work they'll chop something and then they'll wipe the board down, do something else and clean up a little bit. All along the way they're cleaning up. So they never get this massive build up of crap. Because once you've got that build up of crap you can't move. You end up with this tiny five by five centimeter square of space and you need to chop an onion and all of a sudden onion is going everywhere. That's what software development can be like, that's what code bases get like. You need to clean as you go.</p> </blockquote> <blockquote> <p>You need to always take that professional mindset. A lot of companies think there's no time to do that. You just need to smash out features, and then you get to the point where people go to their manager and say we've got all this technical debt we need to stop what we're doing and fix our technical debt. And the managers kind of hit the roof over that. We're under all this pressure. I've heard people give these excuses; there's never any time to do it right. But if you go into a hospital they're generally fairly slammed for time as well but you would never see a surgeon say "you know I really should wash my hands but I'm kind of busy, there's no time". They just do it. It's part of their professional ethics to do it. To use hygiene and do things right. And again you'll get fired as a chef if you're not fast enough because you don't clean as you go. But in software it's kind of this top down beat people with a stick approach telling them to go faster and then you wondering why you end up with a mess.</p> </blockquote> <p>Good software development teams clean as they go and the developers understand their professional responsibilities. You have to keep on eye on the future, on the impacts your decisions today will have. And it doesn't have to be at the expense of the short term. In fact, the future is often closer that it appears. Cleaning up as you go and doing things right can help you as soon as tomorrow. Now don't get me wrong, these aren't rules that apply to all code, we still have throwaways and prototypes. There are still trade-offs to make. But the baseline is set. If you're not cleaning as you go, it's slowing you down.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Announcing MicroBus 3 ]]>
</title>
<description>
<![CDATA[ Awesome! MicroBus 3, what does that mean? Well, I've been using Semver (mostly, sometimes a little Ferver creeps in) for my package versions… ]]>
</description>
<link>https://daniellittle.dev/announcing-microbus-3</link>
<guid isPermaLink="false">https://daniellittle.dev/announcing-microbus-3</guid>
<pubDate>Wed, 09 Mar 2016 20:47:00 GMT</pubDate>
<content:encoded><p>Awesome! MicroBus 3, what does that mean? Well, I've been using Semver (mostly, sometimes a little Ferver creeps in) for my package versions so it means in this release there's a few breaking changes. Now, first off, this is a much bigger update than 2.0 was and redefines a few of the MicroBus concepts.</p> <p>There are three main changes, firstly the Registration API has been reworked, global handlers have been smoothed out and there's a new <code class="language-text">IMicroMediator</code> interface (useful for sending any type as a message). But before I get into the details first here's a little bit of background.</p> <h2>The Story So Far</h2> <p>MicroBus has been a fantastic project to work on. I've been lucky enough to be able to use it quite substantially in my workplace. However, some things didn't turn out quite the way I expected them to. So it was time for a few changes.</p> <p>Since the beginning, MicroBus has always had the concept of a pipeline which contains two types of handlers. The first was Message Handlers that resided at the end of the pipeline which do the real work for a given message. The second type of handlers were Pipeline Handlers which could be used to intercept a message as it travelled down the pipeline.</p> <p>In the first version of MicroBus, the Pipeline Handlers are were explicitly added to the message handlers when registering them. However, even though you assigned the Pipeline Handlers individually, they behaved as if they were global. You could only ever have one set of Pipeline handlers for any one message, even if there were multiple different Message Handlers. It had to be the same instance of the Pipeline. </p> <p>In version 2 support for having a global pipeline was added. However, these handlers were restricted to only running once, so they wouldn't run a second time if you sent messages from inside message handlers. Which was super useful, but slightly confusing with regards so naming.</p> <h2>What's Changed</h2> <p>So it was time to clean up a few things. Version 3 started with wanting a bit more flexibility out of MicroBus. If your message contracts implemented <code class="language-text">ICommand</code>, <code class="language-text">IEvent</code> or <code class="language-text">IQuery</code> then everything was fine. However, there were a few cases, such as handling existing messages that didn't use these interfaces, where handlers needed to support any type of object.</p> <h3>IMicroMediator interface</h3> <p>This new interface has the same three methods (send, publish, query) as <code class="language-text">IMicroBus</code> except that messages can be any .NET <code class="language-text">object</code>. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public interface IMicroMediator { Task SendAsync(object message); Task PublishAsync(object message); Task&lt;TResult&gt; QueryAsync&lt;TResult&gt;(object message); }</code></pre></div> <p>To handle messages that don't implement our interfaces, a new handler <code class="language-text">IMessageHandler</code> interface has been added. The <code class="language-text">Handle</code> method of this interface takes a message of any type and returns an <code class="language-text">object</code>.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">class Handler : IMessageHandler&lt;Message, Unit&gt; { public async Task&lt;Unit&gt; Handle(Message message) { return Unit.Unit; } }</code></pre></div> <p>Traditional MicroBus message types can also be sent using the <code class="language-text">IMicroMediator</code> interface and can be handled by either the type safe or generic message handler interfaces.</p> <h3>Registration API</h3> <p>The next big change was the Registration API, there are two main changes here. Firstly when registering MicroBus to the Container Builder, instead of having to register everything inside a lambda, you can now pass in a <code class="language-text">BusBuilder</code> like so.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var busBuilder = new BusBuilder(); containerBuilder.RegisterMicroBus(busBuilder);</code></pre></div> <p>The second change to the Registration API is to the handler registration methods themselves. Previously the registration code looked like this.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">busBuilder .RegisterCommand&lt;TestCommand&gt;().To&lt;TestCommandHandler&gt;() .RegisterCommand&lt;TestEvent&gt;().To&lt;TestEventHandler&gt;();</code></pre></div> <p>The main reason the API was originally designed this way was to make it easier to register events.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">busBuilder .RegisterEvent&lt;Event&gt;().To(x =&gt; { x.Handler&lt;EventHandler&gt;(); x.Handler&lt;EventHandler2&gt;(); });</code></pre></div> <p>In this version of the API you only have to specify the message type once when registering multiple handlers. However, this required quite a lot of code for not much benefit, especially when most of the time you could just use assembly scanning registration methods instead.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">.RegisterHandlers(x =&gt; x.FullName.Contains(&quot;BusMessageTests&quot;), assembly);</code></pre></div> <p>The explicit handler registration API is now much more flat, and combines the <code class="language-text">Register</code> and <code class="language-text">To</code> methods into a single method in <code class="language-text">BusBuilder</code>.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">busBuilder .RegisterQueryHandler&lt;IsItTimeToGetOutOfBedQuery, Result, IsItTimeToGetOutOfBedQueryHandler&gt;() .RegisterQueryHandler&lt;BreakfastEvent, MakeBaconHandler&gt;() .RegisterQueryHandler&lt;BreakfastEvent, EventHandler&gt;()</code></pre></div> <h3>Global Handlers</h3> <p>The last big change is Global handlers. I talked about the problems with the way handlers previously worked. Mainly that pipeline Handlers were Global handlers in disguise except individually registered. In v3 these handlers have been pulled out of the individual registrations and replaced with real global handlers, that are globally registered. These handlers will run for every message sent over MicroBus. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">busBuilder .RegisterGlobalHandler&lt;InnerHandler&gt;()</code></pre></div> <p>Global handlers use the new <code class="language-text">IDelegatingHandler</code> interface which has one main difference to the old <code class="language-text">IPipelineHandler</code> interface mainly the use of <code class="language-text">INextHandler</code> instead of a <code class="language-text">Func</code> to invoke the next handler in the pipeline.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">class DoNothingHandler : IDelegatingHandler { public async Task&lt;object&gt; Handle(INextHandler next, object message) { return await next.Handle(message); } }</code></pre></div> <p>Overall global handlers are now much more consistent and much easier to use.</p> <p>However, this means the global handlers now run all the time, for every message. Needing handlers that know if they're at the Top Level of the call stack is still something I really wanted. So I've brought it back as dependency you can use to tell if it's an outer Handler or not.</p> <p>Adding <code class="language-text">IOuterPipelineDetector</code> to the constructor of a handler will provide an instance via Dependency Injection. The <code class="language-text">IOuterPipelineDetector</code> interface has a single property called <code class="language-text">IsOuterPipeline</code> which you can use to prevent a handler running a second time if the MicroBus pipeline runs inside an earlier instance of the pipeline.</p> <h2>Conclusion</h2> <p>It's been quite a bit release, with a few new features that will make MicroBus more powerful and easier to use. The new <code class="language-text">IMicroMediator</code> makes it easier to work with any message types, registration is simplified and global handlers are easier to build. </p> <p>So there you have it, all the changes in MicroBus 3! Make sure you try it out the new version. Of if you're installing for the first time use the command below. I'm also always on the lookout for feedback so leave a suggestions or issues on the GitHub page. Happy messaging!</p> <blockquote> <p>PM> Install-Package <a href="https://www.nuget.org/packages/Enexure.MicroBus.Autofac/">Enexure.MicroBus.Autofac</a></p> </blockquote></content:encoded>
</item>
<item>
<title>
<![CDATA[ Porting MicroBus to DotNetCore ]]>
</title>
<description>
<![CDATA[ When the new .net core reached RC it looked like the perfect time to start to port some of the Nuget packages I've made starting with… ]]>
</description>
<link>https://daniellittle.dev/porting-microbus-to-dotnetcore</link>
<guid isPermaLink="false">https://daniellittle.dev/porting-microbus-to-dotnetcore</guid>
<pubDate>Sat, 30 Jan 2016 13:28:04 GMT</pubDate>
<content:encoded><p>When the new .net core reached RC it looked like the perfect time to start to port some of the <a href="https://www.nuget.org/profiles/lavinski">Nuget packages</a> I've made starting with <a href="https://github.com/Lavinski/Enexure.MicroBus">MicroBus</a>. I've been watching most of the <a href="https://live.asp.net/">aspnet standups</a> so I've always been relatively familiar with what was going on, but there were still a few challenges along the way. I usually like to have everything figured out before I write about it, but for this post, I want to give a good picture of the experience as I found it.</p> <p>I started out using <a href="https://blog.marcgravell.com/2015/11/the-road-to-dnx-part-1.html">The Road to DNX</a> by Marc Gravell as a guide, which was great for figuring out exactly where to start.</p> <h2>Porting the project</h2> <p>He starts off moving all the old framework specific csproj files so he can build the project the old way as well as with dnx. I ended by just deleting these as I probably won't be using them again even though it's still an RC. So my first step was creating the project.json files, after that you can add them to the solution and Visual Studio will create some xproj files for you.</p> <p>I almost missed the super important part where the blog explains how to include them.</p> <blockquote> <p>IMPORTANT: as soon as you add a project.json to a sln you get a second file per project.json for free: {YourProject}.xproj; these should be included in source control.</p> </blockquote> <p>It breaks the flow a little bit to point it out as an important note but in doing so I guess I missed it on my first read through.</p> <p>The next part was getting the project building. One of the first things I discovered was that dnx was not just a runtime it's also a build system. And it supports targeting multiple frameworks in the one project file. I wanted to compile my project for both <code class="language-text">.net 4.5.1</code> and the new portable <code class="language-text">dotnet</code> targets. This turned out alright, but there was a lot of digging to figure out exactly which monikers I needed, <a href="https://stackoverflow.com/questions/31834593/target-framework-dnx451-or-net451-in-class-library-projects">and the name changes didn't help</a>.</p> <p>One of the biggest changes I had to make was moving to the new reflection API. I'd used the new API before, but I'm sure I ran into every issue again. The two main things to be aware of here is most of the stuff has moved to <code class="language-text">TypeInfo</code> and methods like <code class="language-text">GetInterfaces()</code> are now properties like <code class="language-text">ImplementedInterfaces</code>. Google didn't help as much here as I expected which probably means it's still a part of .net that is still rarely used.</p> <h2>Getting the Tests working</h2> <p>For the tests, the first thing I tried to do was leave them exactly as they were (as .net 4.5.1 tests) and use a test runner executable just like before. However, it quickly became apparent that this wouldn't work well. When I build each project with dnx I would get the .net451 dlls I needed however the output directories only contain the artifacts for that project. Unlike the previous build system which would also copy all the dependencies. I'm still not sure how it discovers project dependencies, but I'm guessing it's related to the projects being siblings on disk.</p> <p>I then ported my tests to XUnit so I could use the commands. The IDE lets you then select which commands you want to run. However, you have to have that project selected as the startup project to see it's options. Running the tests this way will still run the tests via the console.</p> <h2>Setting up the Build Server (AppVeyor)</h2> <p>I've been committing my packages to source control recently. The idea of super-deterministic builds is a nice idea. Plus on a build server like AppVeyor restoring packages for each build makes the whole process take much longer than just a git pull.</p> <p>I tried a few things to get this working first committing the packages folder which doesn't seem to contain all the dependencies. Then I looked into committing the lock files as well. I was having issues just getting the project to build on the server. So after a few attempts, I abandoned the approach in favor of just getting it working first.</p> <p>I had a few issues getting package restore working. Some project dependencies and package dependencies would just fail with "Unable to resolve dependency". At this point, I was trying to figure out if dnx had the equivalent of the solution file. It does have the concept of <code class="language-text">global.json</code> but not 100% clear on all the cases it gets used for. I did find that calling dnu restore with the solution path resoved my dependency resolving issue <code class="language-text">dnu restore $solutionDir</code>. I remember reading somewhere it would search child directories for projects, possibly using the <code class="language-text">global.json</code> to guide the search.</p> <p>All this was using the rc1 clr version of the runtime. Initially, it was hard to know what version of the clr I should be using. I actually started out trying to use coreclr for everything, but that can't build .net451. I then switched over to using the clr version and was able to get the project building. However, once I got to the tests, they would then fail. The tests are using <code class="language-text">dnxcore50</code>, and you can only run them using the new coreclr. So what you have to do is build the project with the <code class="language-text">clr</code> then use <code class="language-text">dnvm</code> and switch over to <code class="language-text">coreclr</code> to run the tests.</p> <p>The last things to note is that restore and build are <a href="https://ci.appveyor.com/project/Daniel45729/enexure-microbus/build/93">incredibly verbose</a>.</p> <h2>Conclusion</h2> <p>Eventually, I got everything working, packages build with <code class="language-text">dnx pack</code> are pushed to NuGet with the extra support for dotnetcore!</p> <p>Looking back, I'm not sure if I would have waited until the new dot net cli is ready. There's still a lot of changes happening, and some things could definitely be smoother. It was great to finally get hands on with the new tools, though. Visual studio hid a few things that quickly become apparent when trying to get a project building on a build server. Overall though it feels like a good start although it still feels beta-ish in a few places.</p> <p>Now that MicroBus is building again it's time to start work on the next release.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Querying AD Groups with PowerShell ]]>
</title>
<description>
<![CDATA[ Getting the list of the AD groups if nice and easy in PowerShell. All the CmdLets are located in the module which you might not have… ]]>
</description>
<link>https://daniellittle.dev/querying-ad-groups-with-powershell</link>
<guid isPermaLink="false">https://daniellittle.dev/querying-ad-groups-with-powershell</guid>
<pubDate>Thu, 22 Oct 2015 02:33:15 GMT</pubDate>
<content:encoded><p>Getting the list of the AD groups if nice and easy in PowerShell. All the CmdLets are located in the <code class="language-text">ActiveDirectory</code> module which you might not have installed on your system.</p> <p>To install the module you'll need these Windows features</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Add-WindowsFeature RSAT-AD-PowerShell, RSAT-AD-AdminCenter</code></pre></div> <p>Then you can import the module</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Import-Module ActiveDirectory</code></pre></div> <p>Then query the user you want to see the groups for. This command can also list the groups for other groups in case of inheritance.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Get-ADPrincipalGroupMembership &quot;username&quot; | select name</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ Building a MicroBus application ]]>
</title>
<description>
<![CDATA[ I often like to think of software architecture as the art of structuring software. It's goal being to meet requirements while at the same… ]]>
</description>
<link>https://daniellittle.dev/building-a-microbus-application</link>
<guid isPermaLink="false">https://daniellittle.dev/building-a-microbus-application</guid>
<pubDate>Sat, 19 Sep 2015 05:31:08 GMT</pubDate>
<content:encoded><p>I often like to think of software architecture as the art of structuring software. It's goal being to meet requirements while at the same time being resistant to falling into the state most commonly referred to as a Big Ball of Mud. To fight back against this, applications can use a well-defined architecture along with consistency and readability to ensure they don't become a sprawling, duct-tape-and-baling-wire, spaghetti code jungle. Instead, applications can be structured in such a way as to reduce unnecessary coupling between components. And have a strong foundation that provides consistency, structure and an ideology of the application.</p> <h2>What is MicroBus</h2> <p>MicroBus is a small library designed to help structure applications using the concepts of the Message Bus and Mediator patterns. The mediator pattern focuses on reducing coupling by communicating through a mediator, and the bus depicts the style of communication. These two aspects enable the application to be constructed as a series of pipelines each responsible for its own vertical of functionality.</p> <h2>Sending Messages</h2> <p>MicroBus is centered around sending messages. As an example of what this looks like, here is an example of sending and processing a command.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">await bus.Send(new AddItemToCartCommand(cartId, itemId));</code></pre></div> <p>The command, in this case, is adding an item to some shopping cart. The message itself is a data only object that implements <code class="language-text">ICommand</code>. MicroBus also supports events and queries as first class citizens and enforces their semantics though type safety where possible. For instance, events are the only message types that can have multiple handlers registered to them, and queries are the only message types that can return data. The methods to send events and queries are also slightly different to enforce the notion that each has an explicit purpose.</p> <p>To publish an event to all it's handlers the <code class="language-text">Publish</code> method is used, the event must implement the <code class="language-text">IEvent</code> interface.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">await bus.Publish(new Event(...));</code></pre></div> <p>Queries also have their own method that returns the result for the given query. Queries must implement <code class="language-text">IQuery&lt;TQuery, TResult&gt;</code> where TQuery is itself, and TResult is the result. The Result must also implement <code class="language-text">IResult</code>. This enforces the notion that queries must have a result and also enables type inference to work seamlessly for calls to <code class="language-text">bus.Query()</code>.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var result = await bus.Query(new Query(...));</code></pre></div> <p>In this case, the type of <code class="language-text">result</code> would be inferred from the query type.</p> <h2>Handling messages</h2> <p>Once the message has been put on the bus, then the handlers take over. More generally, handlers contain core logic of the application. Above we sent a <code class="language-text">AddItemToCartCommand</code> command onto the bus so now to handle the command we need a command handler. This is a class that implements the interface <code class="language-text">ICommandHandler&lt;T&gt;</code>. So our command handler would look something like this.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">class AddItemToCartCommandHandler : ICommandHandler&lt;TestCommand&gt; { ctor ⇥ ⇥ public async Task Handle(AddItemToCartCommand command) { var cart = repository.Load(command.CartId); cart.AddItem(command.ItemId); repository.Save(cart); } }</code></pre></div> <p>Similarly, events will use <code class="language-text">IEventHandler&lt;T&gt;</code> and queries will use <code class="language-text">IQueryHandler&lt;TQuery, TResult&gt;</code>.</p> <p>After creating the message and handler you then need to register them to the bus. Here is what a registration would look like when using Autofac. In this case handlers will be registered to Autofac with the <code class="language-text">InstancePerLifetimeScope</code> scope.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">container.RegisterMicroBus(busBuilder =&gt; busBuilder .RegisterCommand&lt;Command&gt;().To&lt;CommandHandler&gt;(...) .RegisterEvent&lt;Event&gt;().To&lt;EventHandler&gt;(...) );</code></pre></div> <p>It's also fairly easy to support any other container, and you can even use it without one at all.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var bus = new BusBuilder() .RegisterQuery&lt;Query, Result&gt;().To&lt;QueryHandler&gt;(...) .BuildBus();</code></pre></div> <p>In this case, the built-in BusBuilder is used to create a bus without any IOC container.</p> <h2>The Pipeline</h2> <p>Messages and Handlers are the bread and butter of MicroBus, but the real power comes from the Pipeline. The pipeline consists not only of just the end handler but lets you place any number of intermediary pipeline handlers between receiving the message and handling it.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 609px;" > <a class="gatsby-resp-image-link" href="/static/8cb3b8cd18f859a34ea93022a96e48ee/672f7/MicroBus_PipelineHandlers.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 10.83743842364532%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAIAAADXZGvcAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAhUlEQVQI1wF6AIX/AF+c02Ge1VWW0ajJ5s/g8ajJ52Of1Wyk13ir2sTZ7cre73+w3Gyk12Sf1aHE5Mjc7rTQ6lmZ02Sg12Gb0ABamdNoo9lWmNOhxOTA1+2fw+VlodhxqNt2q9u40um81et9sN1vp9poo9mawOK40emsy+dendZvqNtcmM/sNlO1jiJJHAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Pipeline Handlers" title="Pipeline Handlers" src="/static/8cb3b8cd18f859a34ea93022a96e48ee/672f7/MicroBus_PipelineHandlers.png" srcset="/static/8cb3b8cd18f859a34ea93022a96e48ee/064a4/MicroBus_PipelineHandlers.png 225w, /static/8cb3b8cd18f859a34ea93022a96e48ee/44727/MicroBus_PipelineHandlers.png 450w, /static/8cb3b8cd18f859a34ea93022a96e48ee/672f7/MicroBus_PipelineHandlers.png 609w" sizes="(max-width: 609px) 100vw, 609px" loading="lazy" /> </a> </span></p> <p>Pipeline handlers let you intercept messages as they are passed through to the message handlers, and then the responses as they bubble back up through the pipeline. This makes pipeline handlers the ideal place to handle all the cross-cutting concerns in an application. Such as logging, security, unit-of-work/transactions to name a few.</p> <p>Here is an example of a pipeline handler responsible for starting and committing a Unit of Work.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">class TransactionHandler : IPipelineHandler { private readonly UnitOfWork unitOfWork; public PipelineHandler(UnitOfWork unitOfWork) { this.unitOfWork = unitOfWork } public async Task&lt;object&gt; Handle(Func&lt;IMessage, Task&lt;object&gt;&gt; next, IMessage message) { try { var response = await next(message); unitOfWork.Commit(); } catch { unitOfWork.Rollback(); } } }</code></pre></div> <p>The same <code class="language-text">IPipelineHandler</code> interface is used for all messages. This enables the use of the same pipeline can be used across all types of messages. This interface is fairly typical, but there's one thing worth point out here which is the first parameter of the Handle method. This method takes a <code class="language-text">Func&lt;IMessage, Task&lt;object&gt;&gt;</code> which instantiates or resolved the next handler in the pipeline and calls its handle method. This is a kind of Russian doll model in that each handler contains the next handler.</p> <p>Creating a pipeline just consists of creating a new <code class="language-text">Pipeline</code> object and adding a series of pipeline handlers to it.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var pipeline = new Pipeline() .AddHandler&lt;PipelineHandler&gt;();</code></pre></div> <p>Once the pipeline has been created you can use it for as many different messages as you want. For example here the same pipeline is used to register a command and a query.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">container.RegisterMicroBus(busBuilder =&gt; busBuilder .RegisterCommand&lt;Command&gt;().To&lt;CommandHandler&gt;(pipeline) .RegisterQuery&lt;Query&gt;().To&lt;QueryHandler&gt;(pipeline) );</code></pre></div> <h2>Compared to MVC/WebApi</h2> <p>So far we've seen MicroBus handling messages and handling cross-cutting concerns using the pipeline. While most frameworks, such as <em>ASP.NET Web API</em>, <em>ASP.NET MVC</em>, and <em>Nancy</em> will let you do something similar with handlers and action filters. One of the advantages behind the MicroBus is that it allows the application code to define the pipeline itself as opposed to embedding it in the frameworks themselves. These frameworks many also have other concerns going on besides the very simple “message in, message out” pattern.</p> <p>Decoupling the application from these frameworks also has the added benefit of being able to use the same code for multiple different entry points. For example, you have a web app that can also consume messages from a service bus. Because all the cross cutting concerns are handling by MicroBus, it becomes trivial to support.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 631px;" > <a class="gatsby-resp-image-link" href="/static/babc28e0d496643752db42db23a4a8c3/eef7a/MicroBus_Invokers.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 34.389857369255154%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABVklEQVQY032QzUvCcBzGf39fB6FDRIF4iOjipaBDpy6BUFCHQjdfsFGGLl8w37aVLt9yTiJzlbrU+UIHEbroEtz2+zXTgxH05XN5nud7eHiAySmYL6tGx8tRQkIIQYggmjM7iH45ixLseOsHEWkv0MDve9NMU5E6ROpoymQMdRQZKUOkjJAiT+Xka56qMrClOie0dJhoUZX+WEFNsY75M1iw4AzlG9nYgAvfxFlnuIiFuDRz+8mFyyxlCzzYgoWrSBbohc0eceO8Zom2XJmeO1pcOn1dxt8NZwLmS3qD9C7BGy/aq25pn8i5ScZBJg2YuOJqmuzPAGe71mTnmJYYYaDX/mi3yHj+muYDDNd/ZOQyxbI5P1Mi6dJTLj2pxEUu5aN4kuJjdwVg9lS3veIWUbWmuj+D6UOoM1SIdCDUZlKDmgKRtvAA1nBhk6itO94sMenvtv87374xXt6ohi5nAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Multiple invokers" title="Multiple invokers" src="/static/babc28e0d496643752db42db23a4a8c3/eef7a/MicroBus_Invokers.png" srcset="/static/babc28e0d496643752db42db23a4a8c3/064a4/MicroBus_Invokers.png 225w, /static/babc28e0d496643752db42db23a4a8c3/44727/MicroBus_Invokers.png 450w, /static/babc28e0d496643752db42db23a4a8c3/eef7a/MicroBus_Invokers.png 631w" sizes="(max-width: 631px) 100vw, 631px" loading="lazy" /> </a> </span></p> <p>Entry points can also include Tests making Integration and Unit testing much easier. Part of the reason for this is each feature already maps to one command and handler pair. Integration tests can simply use the bus as is with the existing pipeline, and Unit Tests can focus on handlers as a unit.</p> <h2>MicroBus Lifecycle</h2> <p>Lastly, I wanted to touch a little bit on Object Lifecycles in MicroBus. For a Bus setup using Autofac, most components will be registered as instance per lifetime scope except the bus itself. The bus is registered as transient and will create a new lifetime scope for each message. So even without using Autofac in WebAPI, each request would get a new instance of the bus and the pipeline.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 631px;" > <a class="gatsby-resp-image-link" href="/static/874835d18305241d477815b7b566b9d2/eef7a/MicroBus_Pipeline.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 14.263074484944532%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAwklEQVQI1wG3AEj/AKnJ6KLG5rrT6/n9/+vl46GtvJqtwparwc28tPPIrM28tJqtwp2uwqOvv+bEruzFrbGzu5iswparwb65vABnotldndZwptidw+Wnus1Zm9ZVnuBHlt2MqMSlsMCYrMNXoeFrq+Rgn9mcrL+nsb93pM9Vn+BQneGJp8cAn8Tlm8Hkss/o9Pr/5uLhlqq/kKrFjKjExrm27satxrm2kKrFlq3GmqzC4cKv5sOuqLC9jqnFjKjFt7e9NKh/9v8qFb4AAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="MicroBus Pipeline Lifecycle" title="MicroBus Pipeline Lifecycle" src="/static/874835d18305241d477815b7b566b9d2/eef7a/MicroBus_Pipeline.png" srcset="/static/874835d18305241d477815b7b566b9d2/064a4/MicroBus_Pipeline.png 225w, /static/874835d18305241d477815b7b566b9d2/44727/MicroBus_Pipeline.png 450w, /static/874835d18305241d477815b7b566b9d2/eef7a/MicroBus_Pipeline.png 631w" sizes="(max-width: 631px) 100vw, 631px" loading="lazy" /> </a> </span></p> <p>Things get a little more complicated when handlers themselves send messages. In that case, no new scope is created so lifetime scope registrations can be shared across nested pipelines as well. It's also possible to override when MicroBus creates new scopes by implementing the <code class="language-text">IDependencyScope</code> and <code class="language-text">IDependencyResolver</code> interfaces.</p> <h2>Getting Started</h2> <p>So there you have it. MicroBus, a tiny in memory message bus that can help you structure your app, reuse your cross-cutting concerns and decouple it from communication concerns.</p> <p>I hope you enjoyed learning a little bit about what MicroBus is and how it can help you. If you're, keep to see more make sure you check out the <a href="https://github.com/Lavinski/Enexure.MicroBus">MicroBus GitHub page</a>. Or just go right ahead and install the NuGet package and have a play yourself.</p> <blockquote> <p>PM> Install-Package <a href="https://www.nuget.org/packages/Enexure.MicroBus/">Enexure.MicroBus</a></p> </blockquote> <p>For more examples, you can also check out the <a href="https://github.com/Lavinski/Enexure.MicroBus/tree/master/src/Enexure.MicroBus.Tests">Enexure.MicroBus.Tests</a> project.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Generating Read Models with Event Sourcing ]]>
</title>
<description>
<![CDATA[ Event sourcing is a very powerful tool that allows you to capture information you didn't even know you wanted. One of the things you usually… ]]>
</description>
<link>https://daniellittle.dev/generating-read-models-with-event-sourcing</link>
<guid isPermaLink="false">https://daniellittle.dev/generating-read-models-with-event-sourcing</guid>
<pubDate>Tue, 21 Jul 2015 22:28:00 GMT</pubDate>
<content:encoded><p>Event sourcing is a very powerful tool that allows you to capture information you didn't even know you wanted. One of the things you usually find yourself doing when event sourcing is applying the principle of CQRS. CQRS effectively splits your application into two parts, a read side for queries and a write side for commands. These two sides are kept in sync by events that the read side listens to, which represent the results of the commands. One of the issues I've tackled recently is how to go about generating the read model from these events.</p> <div class="alert alert-danger"> Update! I've learnt a lot since writing this article and no longer recommend the conclusion I came to here. In short enriching events had unforeseen problems and I would instead recommend using only delta style events in a persisted event streams. To learn more read <a href="/event-sourcing-what-properties-should-domain-events-have">Event Sourcing: What Properties should Domain Event have?</a> </div> <p>So to set the scene, imagine a bank account, it contains a series of transactions and the total for the account. The two main events that we have to handle here are credits and debits. I'll skip over why they're not just one transaction event for this post. The part I want to focus on is what properties these events need. My first thought was that these events should just represent the deltas of the system. So my credit event would only need to specify the amount. The event would then be saved to the event store and published so any other potential listeners could handle it as well.</p> <h2>Handlers keeping track themselves</h2> <p>Ok, now it's time to update the read model! My read model is a typical set of database tables, accounts and transactions. I'll start with transactions because it's easy, all I need to do here is write in my event. Now for the tricky bit. My accounts table has a balance total column that I need to update in response to the event as well, but I don't know what the new total is. Could I use the existing value in the read model and just add my amount to it? No, that doesn't feel right at all, worse my values could drift between models. There's also another problem. If another service wanted to listen for these events and keep track of the total. They'd have to deal with the same problem, doing the calculation again themselves. They might not even have persisted memory to keep track of the total.</p> <blockquote> <p>The Credit Added event containing just the amount to add</p> </blockquote> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">/* CreditAddedEvent */ { &#39;amount&#39;: 10.0 }</code></pre></div> <blockquote> <p>With deltas each listener has to duplicate the work done</p> </blockquote> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Who needs the total: - Domain model - Read model to display total - Reporting</code></pre></div> <h2>Using the domain model's current state</h2> <p>It would be fantastic if I somehow had access to the information when the credit event is raised. The model in the write side keeps track of the balance total already. Can I get the information from the model when processing the event? This could work, but it would require exposing the total via a property so the handler could access it. </p> <blockquote> <p>I could get the information from the model when processing the event</p> </blockquote> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">// Maybe something like this public void Handle(Metadata&lt;CreditAddedEvent&gt; metadataEvent) { metadataEvent.DomainEvent.Amount metadataEvent.DomainModel.Total }</code></pre></div> <p>This didn't quite sit well with me either, one of the great things about the models in CRQS+ES is they can shed all their properties and properly encapsulate their state. If I expose properties here command handlers would then have access when they really shouldn't. There's also one other concern, tests. I also need to check the total in my tests and exposing this makes testing harder because my model is exposing more of its implementation. So either I can't change my model, or my tests become more prone to change. </p> <h2>Enriching the event</h2> <p>My last option to get the total is to put the total on the event itself (enriching the event). So that the event would then contain the amount of credit and the new total for the balance. I'd been avoiding this because the total could be derived from the events that just contained the credits and debits. Adding the derived totals would then mean they had to be persisted in the event store. However looking back this gives us exactly what we want and solves some other problems along the way.</p> <blockquote> <p>Enriching the event means that it now represents the state change</p> </blockquote> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">/* CreditAddedEvent */ { &#39;amount&#39;: 10.0, &#39;newTotal&#39;: 70.0 }</code></pre></div> <p>Enriching the event means that it now represents the state change of the aggregate. Therefore, the state change becomes completely explicit and simplifies usage of the event stream immensely. Consumers don't have to keep track of any state themselves, in my case keeping their own tally. Enriching the events also helps keep my code dry, all my calculations take place in the behaviours of my models. This also makes replaying my events blisteringly fast because only have to set fields; no other calculations are needed. This would be even more beneficial if derived values were computationally expensive. As for the idea of exposing properties, enriching the event means I don't need to expose any properties for tests or to generate the real model. Everything they need is on the events, and the aggregates completely encapsulate all their internal state. The domain models should only need to process commands and emit events as side effects. This also helps unit tests become more resilient to change while giving me more freedom to change the internals of the models. You'll also find that some state doesn't even need to be kept in the memory of the models but may only be used in the events and the read model.</p> <h2>Enriching the event but not storing it</h2> <p>However, there's one more possible path I could have taken. Which is to have two different events. The delta that is stored in the event store and the enriched event that is only in memory. There are also problems with this approach, but I want to include it for completeness. While this gives me most of the benefits from just having one event, replaying the events becomes a much more expensive operation. I'd also have to write two events instead of just one which adds a whole bunch of other complexities and raised a whole bunch of questions. Would the events have the same identity? Would I need to store things that are not deltas anyway, such as answers from external services? What would I call the new event? They are the same event but have different models, it feels awkward giving two events the same name. I'd much rather just store the extra data and have just one event. </p> <h2>In the end</h2> <p>Enriching my domain events and saving them in the event store lets me generate the read model I need easily and avoids unnecessary complexity. Thus keeping the application in a maintainable state. I get the benefits of fast replaying of events, having all state change explicitly represented in the events and fully encapsulated state in my domain models. I could also data mine the raw event stream much more easily without using my application to process the events or duplicating the logic in it. </p></content:encoded>
</item>
<item>
<title>
<![CDATA[ The Perfect Pot ]]>
</title>
<description>
<![CDATA[ Whether it's building software, a business, or some other project, chances are you'll almost never get it right the first time. Years ago, I… ]]>
</description>
<link>https://daniellittle.dev/the-perfect-pot</link>
<guid isPermaLink="false">https://daniellittle.dev/the-perfect-pot</guid>
<pubDate>Sat, 24 Jan 2015 06:25:49 GMT</pubDate>
<content:encoded><p>Whether it's building software, a business, or some other project, chances are you'll almost never get it right the first time. Years ago, I heard a story of a pottery teacher that tried an experiment on the class to find out the best way to teach pottery to the students.</p> <blockquote> <p>A high school pottery teacher was addressing the class, regarding their new assignment. The teacher told half of the class that they had the semester to create their best pot, which they would submit to be graded. To the other half of the class, the teacher said they would have to make 50 pots and that they would be graded on their best pot.</p> </blockquote> <p>Who do you think produced the best pot? If you said the second half of the class, you'd be correct. I think the story applies well to the art of software development and I don't mean just building 50 of something. So lets explore this a little bit, why did they do better?</p> <h2>Practice</h2> <p>This is the classical answer, and it has a lot to do with the way the mind works. Practice strengthens the neural pathway in the brain. When you first learn something, it requires a very conscious effort. But as you practice, you become more efficient until you can perform the task almost without thinking. Regardless of whether you're doing pottery or writing software, this not only makes you faster, but when you can do these things "without thinking," you can spend more time thinking about other things. In other words, it will free up your mind so you can focus on the finer details.</p> <h2>Blinded by Perfection</h2> <p>The first group were too busy trying to decide what makes the perfect pot, and they are never able to make it because they don't have the necessary skill to achieve their goal. However, the second half of the class was forced to make pot after pot and refine their process.</p> <p>In software, this is commonly referred to as analysis paralysis. Where you spend so long trying to figure out everything, you never get around to actually starting or finishing. However, when you're forced to spend more time just building things and finishing things, you get to experience a wider range of problems and solutions.</p> <h2>Destination Unknown</h2> <p>To me, this was the most important point. But what do I mean by destination unknown? Well, the first group did not know what the perfect pot would look like or how to make it. They did not know what would make the pot collapse and what would make it beautiful. They had a vague idea of what they wanted to make it but lacked the skills to get there. So, by focusing on building the perfect pot, they did not get the opportunity to learn as much. The second group, on the other hand, started out in the same place but through trial and error they built on their knowledge. They were free to experiment and refine their process as they went.</p> <p>The same applies to software development as well. Jumping in and building things lets you discover how a solution should look and how to build it. As you progress and encounter real issues, you can find the solutions as you need them. This is a much better way for us to learn, as we can see the reasons behind them much more clearly. You also don't need to solve everything upfront, which may be too much to hold in your head at one time. It's impossible to exactly know what to do upfront, you have to discover it along the way.</p> <blockquote> <p>The first half of the pottery class spent hours on a single pot, throwing it and rethrowing it. But by the end, none of them had made a perfect pot. Students that had to make 50 pots, on the other hand, made so many pots that they figured out what worked and what didn't. By the end of the semester, they could all throw a perfect pot.</p> </blockquote> <p>When writing software, the only time I knew what I should have done is after I've already tried something. You can't think of everything upfront. The best way to learn something is to try and do it.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Calling a Rest (Json) API with PowerShell ]]>
</title>
<description>
<![CDATA[ PowerShell makes working with rest API's easy. In PowerShell version 3, the cmdlets and where introduced. These cmdlets are a huge… ]]>
</description>
<link>https://daniellittle.dev/calling-a-rest-json-api-with-powershell</link>
<guid isPermaLink="false">https://daniellittle.dev/calling-a-rest-json-api-with-powershell</guid>
<pubDate>Tue, 11 Nov 2014 04:39:46 GMT</pubDate>
<content:encoded><p>PowerShell makes working with rest API's easy. In PowerShell version 3, the cmdlets <code class="language-text">Invoke-RestMethod</code> and <code class="language-text">Invoke-WebRequest</code> where introduced. These cmdlets are a huge improvement coming from the .NET model you had to work with previously turning a request into a concise one liner similar to curl (Which is also an alias for <code class="language-text">Invoke-WebRequest</code> in PowerShell).</p> <p>The difference between the two is quite small, <code class="language-text">Invoke-RestMethod</code> simply being a slightly more convenient wrapper around <code class="language-text">Invoke-WebRequest</code> as it only returns the content, omitting the headers.</p> <p>The most common case I tend to use this method for is querying or posting to a json rest API's. I usually end up just using <code class="language-text">Invoke-RestMethod</code> so I'll focus on it.</p> <p>The simplest call you can make is to just provide the URL. This will default to a <code class="language-text">GET</code> request, and any unsupplied optional parameters are omitted from the request. For example, this <code class="language-text">GET</code> request won't have a content type. However, if this parameter is omitted and the request method is <code class="language-text">POST</code>, <code class="language-text">Invoke-RestMethod</code> sets the content type to "application/x-www-form-urlencoded". Invoke-RestMethod -Uri $uri</p> <p>The value returned will be automatically parsed depending on the content type of the response. For a json endpoint, I'll automatically get a PowerShell object (hashtable) that represents the json response.</p> <p>So getting data from an endpoint is pretty easy but most rest APIs require an authentication token in order to verify your request. The most common way of supplying the token is via a HTTP header, which looks like this.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$apiKey = &quot;SomeKey&quot; $resource = &quot;http://localhost/api/books&quot; Invoke-RestMethod -Method Get -Uri $resource -Header @{ &quot;X-ApiKey&quot; = $apiKey }</code></pre></div> <p>Now we can query a json endpoint, but what about sending json. PowerShell objects can be represented using hashtables in a similar way to Javascript objects. PowerShell 2.0 also provides two functions (<code class="language-text">ConvertTo-Json</code> and <code class="language-text">ConvertFrom-Json</code>) for easily converting back and forth between JSON and PowerShell objects. The final step is to just construct a PS object and convert it.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$body = @{ Name = &quot;So long and thanks for all the fish&quot; } Invoke-RestMethod -Method Post -Uri &quot;$resource\new&quot; -Body (ConvertTo-Json $body) -Header @{&quot;X-ApiKey&quot;=$apiKey}</code></pre></div> <p>So in just four lines of code you an submit a simple POST to any HTTP endpoint. If you want some further reading, you can also find the documentation for <code class="language-text">Invoke-RestMethod</code> at Microsoft TechNet.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ MVC Architecture ]]>
</title>
<description>
<![CDATA[ The typical scaffolding tool and sample applications for MVC web apps are usually based on simple CRUD like systems. They'll, usually, have… ]]>
</description>
<link>https://daniellittle.dev/mvc-architecture</link>
<guid isPermaLink="false">https://daniellittle.dev/mvc-architecture</guid>
<pubDate>Thu, 25 Sep 2014 09:40:14 GMT</pubDate>
<content:encoded><p>The typical scaffolding tool and sample applications for MVC web apps are usually based on simple CRUD like systems. They'll, usually, have Views written in a templating language, with some kind of ORM and Models for persistence and Controllers to tie the two together.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 870px;" > <a class="gatsby-resp-image-link" href="/static/310746e4411235a72b4c6d5114f142ce/386eb/Basic-MVC.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 21.724137931034484%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAABnWAAAZ1gEY0crtAAAAoUlEQVQI1yVPCQ7DMAjr/1/aNc3JkYSmMLIhgWSDMRy6RDFaL151su3QnQONsvWqmOxd9m9M3nCT0ZYcDnRQR1iDFGIXhFFU9a1Xx0rQJJ8mgwRIUOF+sCK0hVm5HtvwkZTbnNM4V74L365dLaRSPyFxuuwZmUObxSgxwhmiEFhvh9tqC8bFt75U1LbrvhDi7+ym9fTXXqed9AEINpy8XPgFjnLnfxxyQyUAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="View, Controller and Model" title="View, Controller and Model" src="/static/310746e4411235a72b4c6d5114f142ce/386eb/Basic-MVC.png" srcset="/static/310746e4411235a72b4c6d5114f142ce/064a4/Basic-MVC.png 225w, /static/310746e4411235a72b4c6d5114f142ce/44727/Basic-MVC.png 450w, /static/310746e4411235a72b4c6d5114f142ce/386eb/Basic-MVC.png 870w" sizes="(max-width: 870px) 100vw, 870px" loading="lazy" /> </a> </span></p> <p>But there's a problem with this layout, and it's causing the Controllers to grow out of control. Because this scenario is based on CRUD the design here has found it's way into all kinds of applications, such as applications that need more than trivial amounts of business logic. Hopefully, now we can start to see the issue. All this logic ends up being placed in the Controllers which as a result become bloated. This also negatively impacts the Model, which effectively becomes just a data access layer.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 870px;" > <a class="gatsby-resp-image-link" href="/static/c1ea0e24e2093e282adf02797dce7547/386eb/Big-Controller.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 30.459770114942526%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAABnWAAAZ1gEY0crtAAAAxklEQVQY02VQi67DIAjt/39pt+m6IoKowLBLlt1cY0jgPDyy+f+j0/D555ZsnS/MfombjRaY88swG5eFN7R6uGm4fKoJaUkL4hI0b2AlhXBbxkKEOIVjxIM0GK3EE7zGdc7QjxCzStReoQDM+jI6tysS5ZwbV8dcBCaDN1T3/Dxu9yR9uM1ZHjiCkAiOfd97OXyJOymmlaTmMLMrm8LdhvgU1+6jKZ163gJSXjTvGBFMePt83X4XocNWKliasCNYrdB3YV/yG29dXh/YTZQ9AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Big Controller MVC" title="Big Controller MVC" src="/static/c1ea0e24e2093e282adf02797dce7547/386eb/Big-Controller.png" srcset="/static/c1ea0e24e2093e282adf02797dce7547/064a4/Big-Controller.png 225w, /static/c1ea0e24e2093e282adf02797dce7547/44727/Big-Controller.png 450w, /static/c1ea0e24e2093e282adf02797dce7547/386eb/Big-Controller.png 870w" sizes="(max-width: 870px) 100vw, 870px" loading="lazy" /> </a> </span></p> <p>So what's the alternative?</p> <p>In MVC, the Model is often confused with various other similar concepts such as DTOs or a data layer. However, the Model is a more general concept that refers to the entire set of concepts your application is modelling. Persistence isn't a concern of the MVC pattern. So you can think of the Model as the entire domain, which includes the behaviours (business logic) and state. It's also useful to remember that the MVW (Model View Whatever) patterns are user interface patterns and do not attempt to describe or constrain any of these parts other than to split the View from the Model.</p> <p>Moving the majority of application logic into the Model frees the Controller and View from dealing with those concerns and leaves them to focus on their primary role; which is to act as an interface to the outside world. This allows the Model to focus on the domain. Letting it properly encapsulate internal concepts, and exposing it's own facades where needed. It can even be self-contained with a well defined API of its own. With that in mind, the purpose of the controller becomes a bit clearer. Its job is simply to translate a request for the Model and any results back for the views.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/8f817d93325150f0512c6924a3e91bdd/feebe/Big-Model.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 28.04232804232804%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAABnWAAAZ1gEY0crtAAAAoklEQVQY042Q2woDIQxE9/+/tN3WJGq8rRobhRaWbaFhXmQ8kyHbOI0sXUemkbww9CUJKIE2fY/khI1k/vxUYyQa0U5XVlyr4p+jHaPXpSZ236RE9r4nVt4VomSklmZ3S2QJK957zRAfHEGzNIRDcN7PFQyb5EAIR5jLbUGXcdRDYQQA86x4U9jEPSaadRT2jERv+Gdtq7rUrqfafx5sfDvYC4o0XlfP9km+AAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Big Model MVC" title="Big Model MVC" src="/static/8f817d93325150f0512c6924a3e91bdd/fea0e/Big-Model.png" srcset="/static/8f817d93325150f0512c6924a3e91bdd/064a4/Big-Model.png 225w, /static/8f817d93325150f0512c6924a3e91bdd/44727/Big-Model.png 450w, /static/8f817d93325150f0512c6924a3e91bdd/fea0e/Big-Model.png 900w, /static/8f817d93325150f0512c6924a3e91bdd/feebe/Big-Model.png 945w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>In new applications, it's tempting to use the Models to generate the views and bind changes directly back onto the Models. However, this tends to lead back to large controllers that do too much, and <a href="https://www.infoq.com/news/2012/03/GitHub-Compromised">has other problems</a> as well. To avoid these issues instead of binding directly onto the Model (which may not even be possible such as when doing Domain Driven Design) data is bound onto a ViewModel. While View Models can sometimes look similar to objects in the Model they are distinct and ideally are never referenced from the Model. Separating them have a number of benefits including security, separation of concerns (think web validation) and most importantly decouple the Model from the View.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/7f65b0a07e82bc985e991ee390bb340a/b47b0/ViewModels.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 20.81497797356828%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAABnWAAAZ1gEY0crtAAAAsUlEQVQI1xWP27LDIAhF8/9f2clJ47E1XqKoKELJEzPsvZjFxjS5eGmJyyWjLZaxeLIQCy/iGjWSGrkXEWGsDFq+GYKsuXFNGrTWqGbM9ozFuGS+4e0heEMQAKDltLJrC1e5Bty6Wa0oqHDU4S+H6er3eYS8H/a1H/snft0fRmvN6e1J0QI1zq76j/03VCJD3HjqvSBYVJ4RxpI+GUk6Cc3+aA94nqo3q3YvygjCoz3xB8ux5gHWrCWjAAAAAElFTkSuQmCC'); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="View Models" title="View Models" src="/static/7f65b0a07e82bc985e991ee390bb340a/fea0e/ViewModels.png" srcset="/static/7f65b0a07e82bc985e991ee390bb340a/064a4/ViewModels.png 225w, /static/7f65b0a07e82bc985e991ee390bb340a/44727/ViewModels.png 450w, /static/7f65b0a07e82bc985e991ee390bb340a/fea0e/ViewModels.png 900w, /static/7f65b0a07e82bc985e991ee390bb340a/b47b0/ViewModels.png 908w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>Decoupling the Model is extremely important as not doing so will severely limit how easy it is to make changes to the system. As the View will diverge from the Model in most systems. A simple example would be a markdown editor where you stored both the original Markdown and generated HTML in the Model as an optimisation. Sharing the Model with the View would have effectively limited the application to basic CRUD as the View must always mirror the Model.</p> <p>However, there's still a problem even after introducing View Models. Applications not only diverge between the Model and the View Models. They also Diverge depending on the action you're performing. For example, when creating a record you may wish to include several fields that are read-only after that point. So updates need to use a different View Model from creates. They may even diverge depending on if the View Model is used for Input or Output. Using the same example, we may want to then show these fields as read-only when updating. Which would require them to exist in the Output Update View Model but not the Input Update View Model. In practice, I've found these View Models can start out looking very similar to your Models. But as time goes on and they diverge it becomes apparent the input (parameter) and output (return value) of each Action in the controller can be deserving of its own View Model.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/352c87a56ca733b2e73c1c8d5696d19f/b47b0/Split-ViewModels.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 37.55506607929516%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAABnWAAAZ1gEY0crtAAABEklEQVQY04WRbUsDMQzH7/t/NQXBN4Jzzo3bw12vd23Sh7S9JnZjoAhqSAIJgfzyTyfCNxdmMT5rl2aXWoaQ5Wp8d+afJUsn914FirPLYO1m+w6IChLVUqXK79YxThIhmAMu54uht/3p+WX7ujuOkCOOftkLIaPiFK47ghU/C1m2A2fqOEWPWHJinOu63kH4RokqNBILcVE1LK44BkXBWYACWsh1LZZpjA7ETaUUKjWvTKk0YgEFehwvZxz61bebnMAQ0bROXi6NqGOnJXlnDmDOkysa/Mdx0BBGKKGNwklyYK8537AjSDCS3fWQQl+CIVETqe/7h8en3f4w2hQKVeG/BPv+KuvTBFEjKRuMT/++6hPzo8+cPmy5QwAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Splitting the View Models" title="Splitting the View Models" src="/static/352c87a56ca733b2e73c1c8d5696d19f/fea0e/Split-ViewModels.png" srcset="/static/352c87a56ca733b2e73c1c8d5696d19f/064a4/Split-ViewModels.png 225w, /static/352c87a56ca733b2e73c1c8d5696d19f/44727/Split-ViewModels.png 450w, /static/352c87a56ca733b2e73c1c8d5696d19f/fea0e/Split-ViewModels.png 900w, /static/352c87a56ca733b2e73c1c8d5696d19f/b47b0/Split-ViewModels.png 908w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span></p> <p>Because of the similarities that View Models can have with the Model it can be possible to automate this process of converting between the two. In the past, I've used <a href="https://automapper.org/">AutoMapper</a> to do exactly this. However, as the View Models inevitably diverge you end up with so many mapping rules that it becomes easier to do the mappings explicitly. To read more about why using a mapper should be avoided check out the post <a href="https://www.uglybugger.org/software/post/friends_dont_let_friends_use_automapper">Friends don't let friends use AutoMapper</a>.</p> <p>So to recap, the aim of MVC is to separate the View from the Model of the application. The Model should be where the bulk of your application lies and is effectively your application without the user interface. The View and the View Models represent the user's representation of the system. The controller then sits between the two and is the glue that brings these two parts together. This results in increased flexibility due to the decoupling between the two sides. Which means changes to the application are both easier and faster as you don't have to fight the Model to fit the design.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Avoid null with Containers ]]>
</title>
<description>
<![CDATA[ In C# It's often recommended that you should avoidi using nulls wherever possible. Avoiding nulls is a great concept that can simplify your… ]]>
</description>
<link>https://daniellittle.dev/avoid-null-with-container-types</link>
<guid isPermaLink="false">https://daniellittle.dev/avoid-null-with-container-types</guid>
<pubDate>Wed, 27 Aug 2014 22:42:52 GMT</pubDate>
<content:encoded><p>In C# It's often recommended that you should avoidi using nulls wherever possible. Avoiding nulls is a great concept that can simplify your code. Even so, nulls (or some such equivalent concept) will always have their place, such as to convey data is not available.</p> <p>However, one case where I always pay close attention to using nulls is when working with what object-oriented developers call Containers. A container simply wraps around an instance or multiple insances of some type. This includes types such as Enumerable<T>, List<T>, Lazy<T>, Observable<T>, Task<T>, Nullable<T> (which is partially a special case because it never throws a NullReferenceException) arrays and other similar non-generic types. Typically in these cases returning an empty list or an empty Task over returning null makes the code much more clean and clear. By not returning null, you don't have to check for nulls and hence your code does not need to follow a different path based on the return value. </p> <p>Comparing between the two even in a simple case greatly increases the complexity of the code. The first example is a standard foreach over an enumerable.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">foreach (var item in enumerable) { item.Dump() }</code></pre></div> <p>Which when you need to worry about nulls would become the following</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">if (enumerable != null) { foreach (var item in enumerable) { item.Dump() } }</code></pre></div> <p>And for Tasks, here is the what it looks like without nulls</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var result = await DoAsync()</code></pre></div> <p>And when the function can return nulls you loose type inference or end up with deeply nested code.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">object result; var resultAwaitable = await DoAsync(); if (resultAwaitable != null) { result = await resultAwaitable; }</code></pre></div> <p>There are two main cases where you still might want to return a null value. Such as to be explicit about the difference between unavailable data and no data. The other is to avoid extra memory allocations in high-performance scenarios. However, I find both of these cases to be relatively rare.</p> <p>In the end, the most important thing is usually maintainability and standardizing on empty containers offers more reliable and concise code.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Example Web.Config files (3.5 and 4.5) ]]>
</title>
<description>
<![CDATA[ These are the default generated Web.Config files from Visual Studio 2013 Update 3. Web.Config for .NET Framework 4.5.1 Web.Config for .NET… ]]>
</description>
<link>https://daniellittle.dev/example-web-config-files-3-5-and-4-5</link>
<guid isPermaLink="false">https://daniellittle.dev/example-web-config-files-3-5-and-4-5</guid>
<pubDate>Mon, 04 Aug 2014 07:00:35 GMT</pubDate>
<content:encoded><p>These are the default generated Web.Config files from Visual Studio 2013 Update 3.</p> <ul> <li><a href="#Framework451">Web.Config for .NET Framework 4.5.1</a></li> <li><a href="#Framework35">Web.Config for .NET Framework 3.5</a></li> </ul> <p>Other variations are all quite similar but if you think I'm missing one that's useful leave a comment.</p> <p><a name="Framework451"><strong>Web.Config for .NET Framework 4.5.1</strong></a></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt; &lt;!-- For more information on how to configure your ASP.NET application, please visit https://go.microsoft.com/fwlink/?LinkId=301880 --&gt; &lt;configuration&gt; &lt;configSections&gt; &lt;!-- For more information on Entity Framework configuration, visit https://go.microsoft.com/fwlink/?LinkID=237468 --&gt; &lt;section name=&quot;entityFramework&quot; type=&quot;System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&quot; requirePermission=&quot;false&quot; /&gt; &lt;/configSections&gt; &lt;connectionStrings&gt; &lt;add name=&quot;DefaultConnection&quot; connectionString=&quot;Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WebApplication45-20140804053515.mdf;Initial Catalog=aspnet-WebApplication45-20140804053515;Integrated Security=True&quot; providerName=&quot;System.Data.SqlClient&quot; /&gt; &lt;/connectionStrings&gt; &lt;appSettings&gt; &lt;add key=&quot;webpages:Version&quot; value=&quot;3.0.0.0&quot; /&gt; &lt;add key=&quot;webpages:Enabled&quot; value=&quot;false&quot; /&gt; &lt;add key=&quot;ClientValidationEnabled&quot; value=&quot;true&quot; /&gt; &lt;add key=&quot;UnobtrusiveJavaScriptEnabled&quot; value=&quot;true&quot; /&gt; &lt;/appSettings&gt; &lt;system.web&gt; &lt;authentication mode=&quot;None&quot; /&gt; &lt;compilation debug=&quot;true&quot; targetFramework=&quot;4.5.1&quot; /&gt; &lt;httpRuntime targetFramework=&quot;4.5.1&quot; /&gt; &lt;/system.web&gt; &lt;system.webServer&gt; &lt;modules&gt; &lt;remove name=&quot;FormsAuthenticationModule&quot; /&gt; &lt;/modules&gt; &lt;/system.webServer&gt; &lt;runtime&gt; &lt;assemblyBinding xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot;&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.Helpers&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; /&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-3.0.0.0&quot; newVersion=&quot;3.0.0.0&quot; /&gt; &lt;/dependentAssembly&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.Mvc&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; /&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-5.1.0.0&quot; newVersion=&quot;5.1.0.0&quot; /&gt; &lt;/dependentAssembly&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.Optimization&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; /&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-1.1.0.0&quot; newVersion=&quot;1.1.0.0&quot; /&gt; &lt;/dependentAssembly&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.WebPages&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; /&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-3.0.0.0&quot; newVersion=&quot;3.0.0.0&quot; /&gt; &lt;/dependentAssembly&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;WebGrease&quot; publicKeyToken=&quot;31bf3856ad364e35&quot; /&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-1.5.2.14234&quot; newVersion=&quot;1.5.2.14234&quot; /&gt; &lt;/dependentAssembly&gt; &lt;/assemblyBinding&gt; &lt;/runtime&gt; &lt;entityFramework&gt; &lt;defaultConnectionFactory type=&quot;System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework&quot;&gt; &lt;parameters&gt; &lt;parameter value=&quot;v11.0&quot; /&gt; &lt;/parameters&gt; &lt;/defaultConnectionFactory&gt; &lt;providers&gt; &lt;provider invariantName=&quot;System.Data.SqlClient&quot; type=&quot;System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer&quot; /&gt; &lt;/providers&gt; &lt;/entityFramework&gt; &lt;/configuration&gt;</code></pre></div> <p><a name="Framework35"><strong>Web.Config for .NET Framework 3.5</strong></a></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&lt;?xml version=&quot;1.0&quot;?&gt; &lt;configuration&gt; &lt;configSections&gt; &lt;sectionGroup name=&quot;system.web.extensions&quot; type=&quot;System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;&gt; &lt;sectionGroup name=&quot;scripting&quot; type=&quot;System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;&gt; &lt;section name=&quot;scriptResourceHandler&quot; type=&quot;System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; requirePermission=&quot;false&quot; allowDefinition=&quot;MachineToApplication&quot;/&gt; &lt;sectionGroup name=&quot;webServices&quot; type=&quot;System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;&gt; &lt;section name=&quot;jsonSerialization&quot; type=&quot;System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; requirePermission=&quot;false&quot; allowDefinition=&quot;Everywhere&quot; /&gt; &lt;section name=&quot;profileService&quot; type=&quot;System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; requirePermission=&quot;false&quot; allowDefinition=&quot;MachineToApplication&quot; /&gt; &lt;section name=&quot;authenticationService&quot; type=&quot;System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; requirePermission=&quot;false&quot; allowDefinition=&quot;MachineToApplication&quot; /&gt; &lt;section name=&quot;roleService&quot; type=&quot;System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; requirePermission=&quot;false&quot; allowDefinition=&quot;MachineToApplication&quot; /&gt; &lt;/sectionGroup&gt; &lt;/sectionGroup&gt; &lt;/sectionGroup&gt; &lt;/configSections&gt; &lt;appSettings /&gt; &lt;connectionStrings /&gt; &lt;system.web&gt; &lt;compilation debug=&quot;true&quot;&gt; &lt;assemblies&gt; &lt;add assembly=&quot;System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089&quot;/&gt; &lt;add assembly=&quot;System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089&quot;/&gt; &lt;add assembly=&quot;System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add assembly=&quot;System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089&quot;/&gt; &lt;/assemblies&gt; &lt;/compilation&gt; &lt;!-- The &lt;authentication&gt; section enables configuration of the security authentication mode used by ASP.NET to identify an incoming user. --&gt; &lt;authentication mode=&quot;Windows&quot; /&gt; &lt;!-- The &lt;customErrors&gt; section enables configuration of what to do if/when an unhandled error occurs during the execution of a request. Specifically, it enables developers to configure html error pages to be displayed in place of a error stack trace. &lt;customErrors mode=&quot;RemoteOnly&quot; defaultRedirect=&quot;GenericErrorPage.htm&quot;&gt; &lt;error statusCode=&quot;403&quot; redirect=&quot;NoAccess.htm&quot; /&gt; &lt;error statusCode=&quot;404&quot; redirect=&quot;FileNotFound.htm&quot; /&gt; &lt;/customErrors&gt; --&gt; &lt;pages&gt; &lt;controls&gt; &lt;add tagPrefix=&quot;asp&quot; namespace=&quot;System.Web.UI&quot; assembly=&quot;System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add tagPrefix=&quot;asp&quot; namespace=&quot;System.Web.UI.WebControls&quot; assembly=&quot;System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;/controls&gt; &lt;/pages&gt; &lt;httpHandlers&gt; &lt;remove verb=&quot;*&quot; path=&quot;*.asmx&quot;/&gt; &lt;add verb=&quot;*&quot; path=&quot;*.asmx&quot; validate=&quot;false&quot; type=&quot;System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add verb=&quot;*&quot; path=&quot;*_AppService.axd&quot; validate=&quot;false&quot; type=&quot;System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add verb=&quot;GET,HEAD&quot; path=&quot;ScriptResource.axd&quot; type=&quot;System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; validate=&quot;false&quot;/&gt; &lt;/httpHandlers&gt; &lt;httpModules&gt; &lt;add name=&quot;ScriptModule&quot; type=&quot;System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;/httpModules&gt; &lt;/system.web&gt; &lt;system.codedom&gt; &lt;compilers&gt; &lt;compiler language=&quot;c#;cs;csharp&quot; extension=&quot;.cs&quot; warningLevel=&quot;4&quot; type=&quot;Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&quot;&gt; &lt;providerOption name=&quot;CompilerVersion&quot; value=&quot;v3.5&quot;/&gt; &lt;providerOption name=&quot;WarnAsError&quot; value=&quot;false&quot;/&gt; &lt;/compiler&gt; &lt;/compilers&gt; &lt;/system.codedom&gt; &lt;!-- The system.webServer section is required for running ASP.NET AJAX under Internet Information Services 7.0. It is not necessary for previous version of IIS. --&gt; &lt;system.webServer&gt; &lt;validation validateIntegratedModeConfiguration=&quot;false&quot;/&gt; &lt;modules&gt; &lt;remove name=&quot;ScriptModule&quot; /&gt; &lt;add name=&quot;ScriptModule&quot; preCondition=&quot;managedHandler&quot; type=&quot;System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;/modules&gt; &lt;handlers&gt; &lt;remove name=&quot;WebServiceHandlerFactory-Integrated&quot;/&gt; &lt;remove name=&quot;ScriptHandlerFactory&quot; /&gt; &lt;remove name=&quot;ScriptHandlerFactoryAppServices&quot; /&gt; &lt;remove name=&quot;ScriptResource&quot; /&gt; &lt;add name=&quot;ScriptHandlerFactory&quot; verb=&quot;*&quot; path=&quot;*.asmx&quot; preCondition=&quot;integratedMode&quot; type=&quot;System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add name=&quot;ScriptHandlerFactoryAppServices&quot; verb=&quot;*&quot; path=&quot;*_AppService.axd&quot; preCondition=&quot;integratedMode&quot; type=&quot;System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot;/&gt; &lt;add name=&quot;ScriptResource&quot; preCondition=&quot;integratedMode&quot; verb=&quot;GET,HEAD&quot; path=&quot;ScriptResource.axd&quot; type=&quot;System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&quot; /&gt; &lt;/handlers&gt; &lt;/system.webServer&gt; &lt;runtime&gt; &lt;assemblyBinding appliesTo=&quot;v2.0.50727&quot; xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot;&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.Extensions&quot; publicKeyToken=&quot;31bf3856ad364e35&quot;/&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-1.1.0.0&quot; newVersion=&quot;3.5.0.0&quot;/&gt; &lt;/dependentAssembly&gt; &lt;dependentAssembly&gt; &lt;assemblyIdentity name=&quot;System.Web.Extensions.Design&quot; publicKeyToken=&quot;31bf3856ad364e35&quot;/&gt; &lt;bindingRedirect oldVersion=&quot;1.0.0.0-1.1.0.0&quot; newVersion=&quot;3.5.0.0&quot;/&gt; &lt;/dependentAssembly&gt; &lt;/assemblyBinding&gt; &lt;/runtime&gt; &lt;/configuration&gt;</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ Unlocking locked files in Windows ]]>
</title>
<description>
<![CDATA[ Every developer has run into this issue at least once. There are a few different tools you can use to find out what process is locking a… ]]>
</description>
<link>https://daniellittle.dev/locked-files-in-windows</link>
<guid isPermaLink="false">https://daniellittle.dev/locked-files-in-windows</guid>
<pubDate>Fri, 01 Aug 2014 09:21:35 GMT</pubDate>
<content:encoded><p>Every developer has run into this issue at least once. There are a few different tools you can use to find out what process is locking a file. In the past I've used a few different tools.</p> <p>My favorite tool today is <a href="https://lockhunter.com">Lock Hunter</a> which is powerful and easy to use. It's packed with a bunch of useful features, integrates nicely into explorer and installs without any "bonus" software. I can't recommend it enough.</p> <p>Before Lock Hunter I used <code class="language-text">Unlocker</code> by Empty Loop as my go to solution but today it's bundled with a toolbar and isn't early as pleasant as Lock Hunter.</p> <p>If you're already using <a href="https://technet.microsoft.com/en-au/sysinternals/bb896653.aspx">Process Explorer</a> it can be a great solution. You can use it's <code class="language-text">Find Handle or DLL</code> to locate the culprit. On the downside (or maybe the upside depending on your point of view) there are is no explorer integration.</p> <p><a href="https://technet.microsoft.com/en-us/sysinternals/bb896655.aspx">Handle</a> is another tool by Systernals but aimed solely at the command like. This tool focus on the basics and leaves the action up to the user.</p> <p>Missed a tool you love to use? Leave a comment!</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Debugging Rx with Seq ]]>
</title>
<description>
<![CDATA[ Debugging Reactive Extensions can sometimes be a bit tricky. When you have a few stream to watch, pinpointing failures is time consuming… ]]>
</description>
<link>https://daniellittle.dev/debugging-rx-with-seq</link>
<guid isPermaLink="false">https://daniellittle.dev/debugging-rx-with-seq</guid>
<pubDate>Mon, 21 Jul 2014 08:34:02 GMT</pubDate>
<content:encoded><p>Debugging Reactive Extensions can sometimes be a bit tricky. When you have a few stream to watch, pinpointing failures is time consuming, and a can easily become a burden.</p> <p>Catching first-chance exceptions can be extremely helpful when debugging Rx. However, it's much more useful to see how events progress over time. After coming across a thread about <a href="https://social.msdn.microsoft.com/Forums/en-US/a0215434-8ad6-45e1-9f21-ed2f14d7317a/a-simple-trace-method?forum=rx">tracing in Reactive Extensions</a> I thought I could make a few improvements to their tracing methods by making use of Seq and <a href="https://serilog.net/">Serilog</a>.</p> <p><a href="https://getseq.net/">Seq</a> is fantastic tool that lets you visualise and explore log data quickly and easily. You can get Seq up and running within minutes. Just download the NuGet for <a href="https://github.com/serilog/serilog/wiki/Getting-Started">Serilog</a> and install <a href="https://getseq.net/Download">the latest version of Seq</a>.</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 900px;" > <a class="gatsby-resp-image-link" href="/static/5fbb67b11bac623886dbc97906e380ad/2ab4f/Seq.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 57.96676441837732%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsSAAALEgHS3X78AAACcklEQVQoz5WSWU/bQBSF819LN1XqIvUftFKrPvUZqTyAKkEoqlCBUBChhYTisJhA2JIQiOOxY2dzNqeQ5et1gMJDXzqaT+famnPmPExoJfyRtbkxVmdHWZ8fY/P7ONrSxDXLE8TkXyzyGT0+x/7mAsnNiJz/xMrkO1anBNGV8HuWR98S+fCa0MuZFA8mDxkJmDriYfiYR+GTv4xMHjESzvBktiAYPPumeDp9wvOvgnhfTCd59SXJ45kT3oyHCVW8Jo2WT7PdoeUHesfwWyi6LlbRRtkWVa9OpebhNX0a4vGabbxGi4bfJZWIEtK0BPF4DG1zg6KVQhk6tkpRyIua+5j5nSHK2MU412h4BWzLZj+5R3JPZ3dnm+2tBNmzHHuxeQnUD9jY2kHb1clL2IWYcrltsllN5gQX+QPOjRSGOsWqOJRbLWrSUimFaZpDLJmDlnpsgVCtC/UrqF4OyJcrnBbLZIQzt8KJXcJu9bB8UO0B9R7U5Ozvyys6HR/fv6HdptsHfV0aVi4lrDOg3OmSVzZZVcbrXhtL/oBzp4pZbWF5PqX2Fa7QH/DPtRsE1iW5ITcHt7vNS5zGFZ6EBZT9nlxQIm06ZEyXC9dD1dr0gsTBQPYN/f5d4FbyEG1HZzu5j+3mMO1TClZayFKuOThlE1U0hhRLinq7ybDg/cDBvcBoNMpiJMLy0iK5dIz0UZTM8U+ZNfq9buAcmrk1CoEGrW613+/dBM4Riv/S+LG2TnwjjmMfokwdS56LbR3zv2tvY5GQcXZMPivPIntISWWE9I1mqDoGNbdALdDhbFARta08jnlGsZClYF5IiXOKjiKxMs0fVs5gVYoFZzAAAAAASUVORK5CYII='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Rx events in Seq" title="Rx events in Seq" src="/static/5fbb67b11bac623886dbc97906e380ad/fea0e/Seq.png" srcset="/static/5fbb67b11bac623886dbc97906e380ad/064a4/Seq.png 225w, /static/5fbb67b11bac623886dbc97906e380ad/44727/Seq.png 450w, /static/5fbb67b11bac623886dbc97906e380ad/fea0e/Seq.png 900w, /static/5fbb67b11bac623886dbc97906e380ad/2ab4f/Seq.png 1023w" sizes="(max-width: 900px) 100vw, 900px" loading="lazy" /> </a> </span> <em>Some events in Seq.</em></p> <p>To hook this up in your application grab this updated <code class="language-text">Trace</code> extension method using Serilog.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public static IObservable&lt;TSource&gt; Trace&lt;TSource&gt;(this IObservable&lt;TSource&gt; source, string name) { var id = 0; return Observable.Create&lt;TSource&gt;(observer =&gt; { var itemId = ++id; Action&lt;string, object&gt; trace = (m, v) =&gt; Log.Information(&quot;{name}{id}: {method}({value})&quot;, name, itemId, m, v); trace(&quot;Subscribe&quot;, null); IDisposable disposable = source.Subscribe( v =&gt; { trace(&quot;OnNext&quot;, v); observer.OnNext(v); }, e =&gt; { trace(&quot;OnError&quot;, e); observer.OnError(e); }, () =&gt; { trace(&quot;OnCompleted&quot;, null); observer.OnCompleted(); }); return () =&gt; { trace(&quot;Dispose&quot;, null); disposable.Dispose(); }; }); }</code></pre></div> <p>Next wire up the trace.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Observable .Interval(100).Trace(&quot;Interval&quot;) .Take(2).Trace(&quot;Take&quot;) .Count();</code></pre></div> <p>Then just register Seq with Serilog and log away.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Log.Logger = new LoggerConfiguration() .WriteTo.Seq(&quot;http://localhost:5341&quot;) .CreateLogger();</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ Making great Octopus PowerShell step templates ]]>
</title>
<description>
<![CDATA[ Step templates, introduced in Octopus Deploy 2.4, are a great way to share and reuse useful PowerShell scripts. Anyone can make a step… ]]>
</description>
<link>https://daniellittle.dev/making-great-octopus-powershell-step-templates</link>
<guid isPermaLink="false">https://daniellittle.dev/making-great-octopus-powershell-step-templates</guid>
<pubDate>Mon, 14 Jul 2014 07:52:44 GMT</pubDate>
<content:encoded><p>Step templates, introduced in <a href="https://octopusdeploy.com/blog/2.4">Octopus Deploy 2.4</a>, are a great way to share and reuse useful PowerShell scripts.</p> <p>Anyone can make a step template and submit it via a pull request <a href="https://github.com/OctopusDeploy/Library">over at Github</a>. I've come up with a few tricks to make writing step templates easier.</p> <p>I wanted to make sure I could do a few things easily like testing the script outside of Octopus, handle errors as well as defaults and provide some structure around the layout of the script.</p> <p>The first thing I do is declare the parameters I want the script to have. Note the inclusion of the <code class="language-text">whatIf</code> switch parameter which makes it easy to test potentially dangerous scripts with a dry run.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">param( [string]$parameter1, [int]$parameter2, [switch]$whatIf )</code></pre></div> <p>By default PowerShell will attempt to continue to run a script after any errors so next I like to change that so an error will stop the script. <em>Note this is just for running outside Octopus, as Octopus also sets this for you.</em></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$ErrorActionPreference = &quot;Stop&quot;</code></pre></div> <p>Next I declare a helper function called <code class="language-text">Get-Param</code>. This function makes it much easier to run scripts outside Octopus by checking for an Octopus parameter and automatically falling back to use a variable. Additionally it also handles errors for required parameters and default values for optional ones.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">function Get-Param($Name, [switch]$Required, $Default) { $result = $null if ($OctopusParameters -ne $null) { $result = $OctopusParameters[$Name] } if ($result -eq $null) { $variable = Get-Variable $Name -EA SilentlyContinue if ($variable -ne $null) { $result = $variable.Value } } if ($result -eq $null) { if ($Required) { throw &quot;Missing parameter value $Name&quot; } else { $result = $Default } } return $result }</code></pre></div> <p>Following that you can then declare any other functions that you need.</p> <p>Finally, and most importantly is the main body of the script. It's executed last because of PowerShell requires you declare a function before you can use it. The body is a <a href="/self-executing-anonymous-function-in-powershell/">self executing anonymous function</a> similar to how you would do so in JavaScript. This lets you provide a child scope for the parameters and variables your script uses. Declaring the parameters here also ensures that the parameters have the correct types for both Octopus and script parameters.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&amp; { param( [string]$parameter1, [int]$parameter2 ) Write-Host &quot;Script Title&quot; Write-Host &quot;PrameterName1: $parameter1&quot; Write-Host &quot;PrameterName2: $parameter2&quot; # Main body of the script goes here! } ` (Get-Param &#39;parameter1&#39; -Required) ` (Get-Param &#39;parameter2&#39; -Default 10)</code></pre></div> <p>If you're wondering about the backticks, they allow the command to span multiple lines.</p> <p>Here's the whole script.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text"># Running outside octopus param( [string]$parameter, [switch]$whatIf ) $ErrorActionPreference = &quot;Stop&quot; function Get-Param($Name, [switch]$Required, $Default) { $result = $null if ($OctopusParameters -ne $null) { $result = $OctopusParameters[$Name] } if ($result -eq $null) { $variable = Get-Variable $Name -EA SilentlyContinue if ($variable -ne $null) { $result = $variable.Value } } if ($result -eq $null) { if ($Required) { throw &quot;Missing parameter value $Name&quot; } else { $result = $Default } } return $result } # More custom functions would go here &amp; { param( [string]$parameter ) Write-Host &quot;Script Title&quot; Write-Host &quot;PrameterName: $parameter&quot; # Main body of the script goes here! } ` (Get-Param &#39;parameter&#39; -Required)</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ Powershell typeof ]]>
</title>
<description>
<![CDATA[ Coming from C#, it provides the built in function that you can use to get the of a class. Powershell also makes it easy to get Type… ]]>
</description>
<link>https://daniellittle.dev/powershell-typeof</link>
<guid isPermaLink="false">https://daniellittle.dev/powershell-typeof</guid>
<pubDate>Mon, 14 Jul 2014 07:00:16 GMT</pubDate>
<content:encoded><p>Coming from C#, it provides the built in function <code class="language-text">typeof()</code> that you can use to get the <code class="language-text">Type</code> of a class. Powershell also makes it easy to get Type information.</p> <p>Wrapping the type in square brackets <code class="language-text">[TypeName]</code> evaluates to an instance of <code class="language-text">System.Reflection.TypeInfo</code>. Which you can then use to compare it as per normal.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">PS&gt;&quot;&quot;.GetType() -Eq [string] True PS&gt;(1).GetType() -Eq [int] True PS&gt;(1.0).GetType() -Eq [int] False</code></pre></div> <p>You can also assign the value to a variable if needed.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">PS&gt;$x = [bool] PS&gt;$x IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Boolean System.ValueType</code></pre></div> <p>I hope this will make it easier to find next time!</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Octopus Deploy ]]>
</title>
<description>
<![CDATA[ I'm happy to announce that I've joined forces with the amazing developers at Octopus Deploy. It's a fantastic product and if you havn't… ]]>
</description>
<link>https://daniellittle.dev/octopus-deploy</link>
<guid isPermaLink="false">https://daniellittle.dev/octopus-deploy</guid>
<pubDate>Tue, 27 May 2014 21:43:04 GMT</pubDate>
<content:encoded><p>I'm happy to announce that I've joined forces with the amazing developers at Octopus Deploy. It's a fantastic product and if you havn't heard of them yet make sure you <a href="https://octopusdeploy.com/">take a look</a>.</p> <p>Deployments are such an important part of every project, yet they're often overlooked until the last minute. Even the best of us make mistakes and when we're under the pressure of a new deployment things can easily be rushed or forgotten. Often resulting in more deployments. Which is just one reason why automated deployments and Octopus Deploy is such an important part of my toolset.</p> <p>I think that all deployments should be automated. Once you start automating deployments, you can guarantee they're consistently fast and reliable. Automating deployments isn't just about making them faster either. It opens up possibilities that simply weren't there before.</p> <p>I'm glad I'll get to contribute some of my ideas in this space, and help make automated deployments a part of everyone's toolset.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ An update on background tasks in ASP.NET ]]>
</title>
<description>
<![CDATA[ There are two types of background tasks that you'd want to use in .NET. Long running tasks which include things like background services… ]]>
</description>
<link>https://daniellittle.dev/an-update-on-background-tasks-in-asp-net</link>
<guid isPermaLink="false">https://daniellittle.dev/an-update-on-background-tasks-in-asp-net</guid>
<pubDate>Thu, 15 May 2014 10:16:12 GMT</pubDate>
<content:encoded><p>There are two types of background tasks that you'd want to use in .NET. Long running tasks which include things like background services that run every 5, 10 minutes or another interval. Long running tasks could be continuously running, possibly spanning several days. Then there are Short lived tasks which are great for running smaller asynchronous tasks. Long running tasks are not supported in ASP.NET however short lived tasks have always been possible, and just got a little easier. </p> <p>But first, To recap on why long-running tasks are problematic. The main issue is that IIS is a request driven web server. Which means, if there's no one hitting your website nothing will happen. You could work around the problem as Phil Haack describes in his post <a href="https://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/#feedback">The Dangers of Implementing Recurring Background Tasks In ASP.NET</a> although you still need some kind of request to trigger the website. In the end, it's much better to just pull the background "Service" out of your website and run it as a Windows Service instead.</p> <p>On the other hand, ASP.NET provides much better support for reliable short lived tasks through <code class="language-text">HostingEnvironment.RegisterObject</code>. Using <code class="language-text">RegisterObject</code> lets you register objects in IIS so it can provide a warning when the App Domain is being shutdown. Letting you finish up your work and terminate these background threads gracefully. This is extremely useful when you need to run asynchronous tasks like sending a batch of emails on a separate thread. However, implementing this interface is tedious and overly complicated.</p> <p>In ASP.NET 4.5.2 this has become much easier with the introduction of <code class="language-text">HostingEnvironment.QueueBackgroundWorkItem</code> which provides a much simpler alternative. By making use of the Task library for .NET you can invoke a lambda as a short running task. Two overloads are provided for the function. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text"> 1. Action&lt;CancellationToken&gt; 2. Func&lt;CancellationToken, Task&gt;</code></pre></div> <p>These methods are both functionally equivalent, fire and forget async. The first simply takes an Action and executes it in the background. The second is exactly the same but returns a <code class="language-text">Task</code> which is required in order to use <code class="language-text">async</code> lambda's, like so.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text"> HostingEnvironment.QueueBackgroundWorkItem(async cancellationToken =&gt; {     // Perform task });</code></pre></div> <p>Under the covers the QueueBackgroundWorkItem method still uses <code class="language-text">HostingEnvironment.RegisterObject</code> along with <code class="language-text">ThreadPool.QueueUserWorkItem</code> to execute the tasks. Meaning you'll still only get 30 seconds to finish what you were doing if cancellation is requested. Even so, this is still an addition that will be greatly appreciated.  </p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Implementing Domain Driven Design ]]>
</title>
<description>
<![CDATA[ I've talked about what Domain Driven Design is and what kind of benefits you can expect from it. The next concept to explore is what the… ]]>
</description>
<link>https://daniellittle.dev/implementing-domain-driven-design</link>
<guid isPermaLink="false">https://daniellittle.dev/implementing-domain-driven-design</guid>
<pubDate>Mon, 28 Apr 2014 01:55:35 GMT</pubDate>
<content:encoded><p>I've talked about <a href="https://lavinski.me/domain-driven-design/">what Domain Driven Design is</a> and what kind of benefits you can expect from it.</p> <p>The next concept to explore is what the implementation looks like. I'll be focusing on the architecture of such a system more than how to model a domain, which <a href="https://dddcommunity.org/book/evans_2003/">Eric Evans covers in his book</a>.</p> <p>The domain in DDD contains all the business logic in the application. Its equivalent in a layered system would be the domain/business layer. A typical domain implementation can be said to look like this:</p> <p><span class="gatsby-resp-image-wrapper" style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 474px;" > <a class="gatsby-resp-image-link" href="/static/fc99c86b0ae156caefb964c67eb7f752/37e1f/Domain-Driven-Design-Concepts.png" style="display: block" target="_blank" rel="noopener" > <span class="gatsby-resp-image-background-image" style="padding-bottom: 64.13502109704642%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABFUlEQVQoz5WRiW6EMAxE+f8/JbuQg9x2kk4S1BYkVu0ossD4xWa8KKWEeGmtW2u1VsTyZy0hBCml1sZaG7xHJObPDDO3oSWlhOZSql3uxhghBDIY4YkEA3jOuBCRsxbMuq5qDN+eyYnh4YRzziEmqYzURhl7OH+4QKXy5TTEnuQyTfmBY+bXtq/i9X7v2hy4hWrleQZM3PnEeOA7nJGrzfqA6lIbTkwE+2ZDCEaiag58h1OmbdvgWTejNu/DKtYQ41yeVjt0etG7XGEi7KZ67/FLY8jSU31hvW1hypRBTiPvMDPZw2Bf+NrqucNR3H4JL6fPFxh3H8Y4Z0dNac+6w9jztKHf3TvXz/B37LD9p2CNcy4OfQHxffu1oE6meAAAAABJRU5ErkJggg=='); background-size: cover; display: block;" ></span> <img class="gatsby-resp-image-image" alt="Domain Driven Design Concepts Diagram" title="Domain Driven Design Concepts Diagram" src="/static/fc99c86b0ae156caefb964c67eb7f752/37e1f/Domain-Driven-Design-Concepts.png" srcset="/static/fc99c86b0ae156caefb964c67eb7f752/064a4/Domain-Driven-Design-Concepts.png 225w, /static/fc99c86b0ae156caefb964c67eb7f752/44727/Domain-Driven-Design-Concepts.png 450w, /static/fc99c86b0ae156caefb964c67eb7f752/37e1f/Domain-Driven-Design-Concepts.png 474w" sizes="(max-width: 474px) 100vw, 474px" loading="lazy" /> </a> </span></p> <p>In Domain Driven Design there are three main types of objects the <code class="language-text">Aggregate Root</code>, <code class="language-text">Entities</code> and <code class="language-text">Value Objects</code>. These are objects in the typical object orientated sense and represent a concept from the domain/business. The other two concepts show are <code class="language-text">Aggregates</code> and <code class="language-text">Bounded Context</code>, which relate to the logical grouping of these domain objects.</p> <h3>Entities</h3> <p><code class="language-text">Entities</code> are a model of an object or concept in the domain and always have a distinct Id, usually a <code class="language-text">Guid</code>. An <code class="language-text">Entity</code> could be anything from such as a user, a product, or any other object. The <code class="language-text">Aggregate Root</code> shown is actually also an entity but it sits at the root of the hierarchy and has no direct references to it.</p> <p><code class="language-text">Entities</code> are a model of the business, but what does an <code class="language-text">Entity</code> actually look like? They are objects like, Product, Customer and Order which contain the behaviours (methods) of domain objects they are modeled after. These behaviours are owned by the <code class="language-text">Entities</code>, not stowed away in a manager or service. This also means that <code class="language-text">Entities</code> don't need to expose all those properties that services or managers would otherwise need. Instead, the state is encapsulated inside the object. <code class="language-text">Entities</code> are not <code class="language-text">Data Transfer Objects</code> and they should have very few, if any, properties. It also makes the behaviours discoverable, more expressive and more consistent as they are all local members of objects.</p> <p>Take the following two lines for example:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">company.Hire(newEmployee);</code></pre></div> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">companyService.Hire(company, newEmployee);</code></pre></div> <p>When <code class="language-text">Hire</code> is simply another behaviour of the company it becomes easy to find and clear to read.</p> <p>So if <code class="language-text">Entities</code> don't have any Properties how do you perform queries? The answer is; by using a read model not the domain model. The domain is primarily concerned with the business logic. It is only used to change the state of the domain. All queries are separated from the domain and instead a thin read layer is used. This is also known as Command and Query Responsibility Segregation or CQRS, which I'll talk about in a future post.</p> <p>Once entities have behaviours they sometimes need to use services or take other dependencies. However, an entity should never have any dependencies injected into it. Instead, it's better to make things explicit. It's actually the behaviours that have dependencies, not the <code class="language-text">Entities</code>. Therefore, when a service is needed, it can be provided as an argument in the method where it is used.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">user.ChangePassword(hashingService, newPassword);</code></pre></div> <p>In regards to validation in the domain, we can view it as just another aspect of the behaviour. Once the entities have behaviours it's quite straightforward to check the arguments are valid and invariants and are maintained. Then the entity itself can ensure it is never put into an invalid state. This also applies for any constructors, which really are just another behaviour.</p> <p>The final concern to address is persistence of the domain. The domain model should be persistence ignorant as it’s only concerned with the domain. Object relational mappers tend to make this more difficult although it is possible. However, I tend to use Domain Events to handle persistence and avoid ORMs altogether.</p> <h3>Values</h3> <p><code class="language-text">Values</code> on the other hand are just data and never have an Id. Their equality is determined as the sum of its parts. For example the value Position could contain Latitude and Longitude components. Two values where all the components are equal are also equal. For this reason <code class="language-text">Values</code> are usually also immutable.</p> <p>Now that I've explained <code class="language-text">Entities</code> and <code class="language-text">Values</code> I'll move up to <code class="language-text">Aggregates</code> and the <code class="language-text">Bounded Context</code>.</p> <h3>Aggregates</h3> <p>An <code class="language-text">Aggregate</code> is a boundary around one or more Entities. This boundary is also a transactional boundary. Such that all <code class="language-text">Entities</code> in one <code class="language-text">Aggregate</code> cannot directly reference <code class="language-text">Entities</code> in another. An <code class="language-text">Aggregate</code> would represent a single unit, for example a Tree. The aggregate is composed of the tree or trunk (the <code class="language-text">Aggregate Root</code>) and leaves (the other <code class="language-text">Entities</code>). <code class="language-text">Aggregates</code> are also the basic element of data storage, much like in a document database. You only save or load whole <code class="language-text">Aggregates</code>.</p> <p>I mentioned earlier that you cannot directly reference <code class="language-text">Entities</code> in another <code class="language-text">Aggregate</code>. Any references from outside the aggregate should only go to the aggregate root, as you cannot cross the <code class="language-text">Aggregate</code> boundary. Unlike references inside an <code class="language-text">Aggregate</code> that link directly to an instance. References to another <code class="language-text">Aggregate Root</code> will only use its identifier. This would also apply to circular references to the <code class="language-text">Aggregates</code> own <code class="language-text">Aggregate Root</code>.</p> <h3>Contexts</h3> <p>Context is extremely important in Domain Driven Design. An entity could logically exist in multiple <code class="language-text">Bounded Contexts</code> or even <code class="language-text">Aggregates</code> with different representations. As an Example, Human Resources sees a person as a resource with a different set of information and behaviours than Accountant would. In an online store items in a user’s cart could be different to items in their order, even though conceptually they're the same thing.</p> <p>Modeling one concept as multiple <code class="language-text">Entities</code> is more common in larger domain where it becomes much more difficult to find a single unified model. Especially when different groups of people need different things from the model.</p> <h3>Other Concepts</h3> <p>There are three other concepts I didn't fully cover here; Repositories, Domain Events and Services.</p> <p>Repositories are a very simple concept and simply load or save <code class="language-text">Aggregates</code>.</p> <p>I did briefly mention Domain Events; the basic premise here is that instead of an ORM implicitly tracking changes <code class="language-text">Events</code> are used to describe what changes happened.</p> <p>The concept of <a href="https://stackoverflow.com/questions/2268699/domain-driven-design-domain-service-application-service">services</a> which could be application, domain or infrastructure services.</p> <h3>In Conculsion</h3> <p>These are the core concepts of a Domain Driven Design implementation. The design of the domain model is built around the concepts of <code class="language-text">Aggregates</code> and <code class="language-text">Entities</code>. Modelling a domain in this way is results in code that is much more expressive, clear and cohesive.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Internet Explorer Won't Save Cookies On Domains With Underscores In Them. ]]>
</title>
<description>
<![CDATA[ All versions of Internet Explorer (version 5.5 all the way to version 11) will discard all cookies if the domain has an underscore in it… ]]>
</description>
<link>https://daniellittle.dev/internet-explorer-wont-save-cookies-on-domains-with-underscores-in-them</link>
<guid isPermaLink="false">https://daniellittle.dev/internet-explorer-wont-save-cookies-on-domains-with-underscores-in-them</guid>
<pubDate>Tue, 15 Apr 2014 23:41:23 GMT</pubDate>
<content:encoded><p>All versions of Internet Explorer (version 5.5 all the way to version 11) will discard all cookies if the domain has an underscore in it. This can lead to the following issues, which can be quite difficult to debug:</p> <ul> <li>Cookies are not set on the client system.</li> <li>ASP.NET Session variables are lost.</li> </ul> <p>When debugging web applications I can't recommend <a href="https://www.telerik.com/fiddler">Fiddler</a> enough. It will be able to pick up these kinds of issues and in this case provides the following warning.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">!! WARNING !!: Server hostname contains an underscore and this response sets a cookie. Internet Explorer does not permit cookies to be set on hostnames containing underscores. See https://support.microsoft.com/kb/316112.</code></pre></div> <p>It's perfectly legal for a domain to have an underscore in it, so this issue goes against the standard (See <a href="https://www.ietf.org/rfc/rfc1034.txt">RFC 2181</a>, section 11, "Name syntax"). Part of the reason it is hard to debug is that the domain will work fine in all other browsers.</p> <p>The support article has the following to say about the issue:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">PRB: Session Variables Do Not Persist Between Requests After You Install Internet Explorer Security Patch MS01-055 A potential security vulnerability exists in Internet Explorer versions 5.5 and 6.0 in which a malicious user could create a URL that allows a Web site to gain unauthorized access to cookies that are stored on a client computer and then (potentially) modify the values that are contained in these cookies. Because some Web sites use cookies that are stored on client computers to store sensitive information, this security vulnerability could expose personal information.</code></pre></div> <p>So this issue is caused to prevent a security issue on a deprecated version of Internet Explorer. I think it's about time this restriction was removed.</p> <p>You can vote to fix this issue at <a href="https://connect.microsoft.com/IE/feedback/details/853796/internet-explorer-wont-save-cookies-on-domains-with-underscores-in-them">Microsoft Connect</a>.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Self executing anonymous function in Powershell ]]>
</title>
<description>
<![CDATA[ One of the great features of JavaScript is the self-executing anonymous function. It's extremely useful because you can avoid polluting the… ]]>
</description>
<link>https://daniellittle.dev/self-executing-anonymous-function-in-powershell</link>
<guid isPermaLink="false">https://daniellittle.dev/self-executing-anonymous-function-in-powershell</guid>
<pubDate>Fri, 11 Apr 2014 02:40:27 GMT</pubDate>
<content:encoded><p>One of the great features of JavaScript is the self-executing anonymous function. It's extremely useful because you can avoid polluting the global scope and express your dependencies in an explicit manner.</p> <p>PowerShell lets you do something similar by taking advantage of <code class="language-text">blocks</code>, the <code class="language-text">param</code> keyword and the call operator <code class="language-text">&amp;</code>.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&amp; { param($msg) Write-Host $msg } &quot;Hello World&quot;</code></pre></div> <p>This function will be automatically invoked with the string <code class="language-text">&quot;Hello World&quot;</code>.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Ninject Modules ]]>
</title>
<description>
<![CDATA[ Ninject is a fantastic Dependency Injection framework for the .NET framework. You can bind to the kernel whenever you want however you… ]]>
</description>
<link>https://daniellittle.dev/ninject-modules</link>
<guid isPermaLink="false">https://daniellittle.dev/ninject-modules</guid>
<pubDate>Fri, 04 Apr 2014 21:08:50 GMT</pubDate>
<content:encoded><p><a href="https://github.com/ninject/ninject/wiki/Dependency-Injection-With-Ninject">Ninject</a> is a fantastic Dependency Injection framework for the .NET framework. You can bind to the kernel whenever you want however you usually want to setup all your binding in once place right, at the start of your application. Ninject provides the perfect place to declare all you bindings in a single place in the form of a <code class="language-text">NinjectModule</code>.</p> <p>To create a Kernel using a Module it is passed as a constructor parameter.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var kernel = new StandardKernel(new ApplicationBindingsModule());</code></pre></div> <p>Then you can simply declare the Module which requires you to implement the abstract <code class="language-text">Load</code> method.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public class ApplicationBindingsModule : NinjectModule { public override void Load() { Bind&lt;IClock&gt;().To&lt;Clock&gt;().InSingletonScope(); // If you use Ninject.Extensions.Convention you have to use `this` to use the extension method syntax. //this.Bind(x =&gt; x.FromThisAssembly()... } }</code></pre></div> <p>Using Modules allows you to easily swap out bindings when creating a Kernel and provides a standard location for all your bindings.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ What is Domain Driven Design? ]]>
</title>
<description>
<![CDATA[ In 2004, Erick Evans coined the term Domain Driven Design in his book also called Domain Driven Design. Since then there has been lots of… ]]>
</description>
<link>https://daniellittle.dev/domain-driven-design</link>
<guid isPermaLink="false">https://daniellittle.dev/domain-driven-design</guid>
<pubDate>Mon, 31 Mar 2014 08:57:51 GMT</pubDate>
<content:encoded><p>In 2004, Erick Evans coined the term Domain Driven Design in his book also called <a href="https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215">Domain Driven Design</a>.</p> <p>Since then there has been lots of talk about using Domain Driven Design to tackle high complexity business problems, but what about everyday development. Just like all software there are tradeoffs. The difference between projects not complex enough for Domain Driven Design and projects that are is not discrete and is entirely superficial; the domain itself is much more important. I'm hoping I can look at some key ideas presented in the Domain Driven Design space and see how they apply to everyday software.</p> <p>Traditionally when we set out to design a system we'd start by looking at the database. Relational databases have been so ingrained into us that it's become the only way that we have thought about our applications. We'd model our systems after the tables and their columns. As a result, the business logic was spread between all kinds of manager objects and in the heads of the users.</p> <p>The focus of Domain Driven Design is to <a href="https://martinfowler.com/bliki/UbiquitousLanguage.html">develop a consistent language</a> that describes both entities and their <em>behaviours</em> in the domain. Identifying and modelling the behaviours, instead of properties and data, makes the system self describing allowing us to clearly see the business requirements. This is fantastic for the developers as it becomes much easer to see intent. The second thing it provides developers is the ability to use encapsulation instead of exposing all their data via properties. I'll explain why this leads to better software in a later post. On the business side it enables developers and the domain experts to share the same understanding of the domain and communicate effectively. This is very valuable because changing business requirements map very easily back into the application.</p> <p>Domain Driven Design has the potential to provide many benefits to business and to developers. If your software is the driving force in your business, Domain Driven Design is definitely worth looking into.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Why use NuGet ]]>
</title>
<description>
<![CDATA[ I've had a few people ask me why they should use NuGet and the occasional person that's never heard of it. If you are currently developing… ]]>
</description>
<link>https://daniellittle.dev/why-use-nuget</link>
<guid isPermaLink="false">https://daniellittle.dev/why-use-nuget</guid>
<pubDate>Sat, 22 Mar 2014 03:04:31 GMT</pubDate>
<content:encoded><p>I've had a few people ask me why they should use NuGet and the occasional person that's never heard of it. If you are currently developing software without a package manager, here is why you should be interested.</p> <h2>What is NuGet?</h2> <p><a href="https://www.nuget.org/">NuGet</a> is the official package manager for .NET managed by the <a href="https://www.outercurve.org/">Outercurve Foundation</a>.</p> <p>But firstly what is a package manager?</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">In software, a package management system, also called package manager, is a collection of software tools to automate the process of installing, upgrading, configuring, and removing software packages.</code></pre></div> <p>A typical NuGet Package consists simply of a metadata file and some <code class="language-text">dll</code> files for the supported .NET versions.</p> <div style="width: 200px"> ![Package structure](https://pfcjjq.dm2302.livefilestore.com/y2pCBjkRcauQ0pM0ZHiJea7P_cFZgdGtfN6PqYQNV5ldF7nphagBs5D_TNrlGoctoObNNSvNZ_qj82nD3EhJ-LAW4TebxfVtb5GC0_eEYGf7fM/NuGet.png) </div> <p>These packages don't just have to contain dlls, they can also contain content such as JavaScript libraries and other text files.</p> <h2>I've never needed NuGet before, what's wrong with just referencing them directly like it's always been?</h2> <p>Let’s say you just started working on a new project. You want to use a library to help you out. It could be an SQL Generation library to help write a dynamic report viewer.</p> <p>So you search around for a library and find a one you're happy with. Next you locate and download the binaries for the library and copy them to your project. Now you can reference them from Visual Studio and start work.</p> <p>The next thing you'll need to worry about is updating that library. If you run into a bug and or want to update the project to get the latest updates or features you have to go through most of the download process again. You'll also never be able to tell if there's an update ready without going to their website.</p> <p>The worst part is you have to do this for every library you want to use. This is a lot of work.</p> <p>It gets even worse if that library happened to depend on another project, such as logger, which you or any other projects might also want to depend on.</p> <h2>How does NuGet make it easier for me?</h2> <p>NuGet can provide consistency, every library you need can be added with just one click. All configuration you need is automatic and any dependencies are automatic added as well.</p> <p><img src="https://plcceq.dm2302.livefilestore.com/y2pzM2P0BBh5gNBIpVJ8B1HICQ7yvbJOVg35sT30cEwzU-IDtAARn2cBdlRzxPvBq192Qd-D4ACNei9ldB-bLdJe51Q1aKBEDj5mIIECE38jUo/NuGet_Window.png?psid=1" alt="Package Manager"></p> <p>Every library you have can be updated with one command. With each package automatically updated to the correct version taking into account each package that depends on it.</p> <h2>Is NuGet perfect?</h2> <p>Nothing is without flaws and NuGet is no exception. NuGet is community driven and while this is great it also means packages, just like libraries, are only as good as their creators.</p> <p>It's also leaky abstraction, which just means you still need to know how assemblies work and get referenced.</p> <h2>Who is actually using it?</h2> <p>The .NET framework team itself <a href="https://blogs.msdn.com/b/dotnet/archive/2013/10/16/nuget-is-a-net-framework-release-vehicle.aspx">has been adopting NuGet</a> as the primary method of delivery over the last few years. The ASP.NET and EntityFramework teams have been leading that trend. The core .NET team started using NuGet in 2012 and have now been releasing parts of the <code class="language-text">Base Class Library</code> with NuGet.</p> <p>Along with a community including thousands of projects NuGet has become the standard method of delivering and using .NET libraries.</p> <h2>How do I get started?</h2> <p>Once you open Visual Studio and create a new project you're already using NuGet.</p> <p>To check out the packages you're using and to add new ones select <code class="language-text">Manage NuGet Packages...</code> from the References menu.</p> <p><img src="https://qfcceq.dm2304.livefilestore.com/y2pmX8RSm6h-KYvyAvxeysD9vrM8suDBMBkNJ6ney-svPuGxDL_9bdtBh84BXh9z-bAJacCUthnj6OvMcdBY4Lp_PxLMLfG8YlJSCDkKls4AlM/NuGet_Open.png?psid=1" alt="Package Manager"></p> <p>From here you can browse through and install the great range of available packages.</p> <p>NuGet allows people to share and take advantage of numerous fantastic projects. Allowing the .NET community to innovate and deliver at an accelerated rate. So next time you're looking for a great library, check NuGet first.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ What's in a Buzzword ]]>
</title>
<description>
<![CDATA[ It's sometimes tempting to dismiss things as the next Fad or Buzzword. There's never enough time to learn everything and some things are… ]]>
</description>
<link>https://daniellittle.dev/whats-in-a-buzzword</link>
<guid isPermaLink="false">https://daniellittle.dev/whats-in-a-buzzword</guid>
<pubDate>Fri, 14 Mar 2014 11:08:12 GMT</pubDate>
<content:encoded><p>It's sometimes tempting to dismiss things as the next Fad or Buzzword. There's never enough time to learn everything and some things are genuinely bad but if you get into the habit of dismissing everything you're also going to miss a lot of good things.</p> <p>Next time you see a new name or word that's buzzing, take the time to investigate what it's about and make your own choices. Names help us to convey our ideas. Terms like <code class="language-text">Domain Driven Design</code> and <a href="https://martinfowler.com/articles/microservices.html"><code class="language-text">Microservices</code></a> hold with them a host of <a href="https://blog.8thlight.com/craig-demyanovich/2014/07/09/pattern-language-of-thieves.html">implicit knowledge</a>. Wrapping up a bunch of existing concepts and providing it to us a concise whole.</p> <p>Don't feel bad because you don't know a word, everyone has to say <a href="https://blog.42floors.com/i-dont-know/">i don't know</a> every once in a while.</p> <p>So next time you see a new library, pattern or architecture take a deeper look. Who knows, you might just learn something.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ OWIN and System.Web.Optimizations ]]>
</title>
<description>
<![CDATA[ I struck out to see if I could make use of the Microsoft ASP.NET Web Optimization Framework (version 1.1.2) in my self hosted OWIN Nancy… ]]>
</description>
<link>https://daniellittle.dev/post-post</link>
<guid isPermaLink="false">https://daniellittle.dev/post-post</guid>
<pubDate>Sat, 01 Feb 2014 05:37:07 GMT</pubDate>
<content:encoded><p>I struck out to see if I could make use of the Microsoft ASP.NET Web Optimization Framework (version 1.1.2) in my self hosted OWIN Nancy application.</p> <p>The only real resource I could find on the topic was the page <a href="https://github.com/NancyFx/Nancy/wiki/How-to-use-System.Web.Optimization-Bundling-with-Nancy">How to use System.Web.Optimization Bundling with Nancy</a> in the Nancy wiki on GitHub. Which looked good at first sight untill I looked a little deeper. This page is not only wildly out of date but didn't even get me close to a working solution.</p> <p>The System.Web.Optimization project unfortunately has a large dependency on System.Web. Which for all practicle purposes makes it unusable when using Microsoft.Owin.Hosting.</p> <p>While might still be possible to get it working without IIS by replacing the <code class="language-text">BundleHandler</code>, providing a <code class="language-text">HttpContext</code> and emulating a virtual directory for the app domain. Which would look something like the this...</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var domain = Thread.GetDomain(); domain.SetData(&quot;.appDomain&quot;, &quot;&quot;); domain.SetData(&quot;.appVPath&quot;, &quot;/&quot;); domain.SetData(&quot;.appPath&quot;, &quot;/&quot;); domain.SetData(&quot;.appId&quot;, &quot;&quot;);</code></pre></div> <p>I think I'll just wait for some official OWIN support and see how <a href="https://getcassette.net/">Cassette</a> goes in the meantime.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Git - When to Merge ]]>
</title>
<description>
<![CDATA[ Many people use git pull and merge frequently in an effort to keep a branch up to date while working a feature. However it's actually… ]]>
</description>
<link>https://daniellittle.dev/git-when-to-merge</link>
<guid isPermaLink="false">https://daniellittle.dev/git-when-to-merge</guid>
<pubDate>Thu, 12 Sep 2013 01:00:00 GMT</pubDate>
<content:encoded><p>Many people use git pull and merge frequently in an effort to keep a branch up to date while working a feature. However it's actually recommended not to merge into a feature branch until it's complete and ready to be integrated back into the development branch. </p> <p>The reason for this is that merge is a is a semantic action and actually has additional meaning than just update this branch. For example a feature branch should only be concerned with adding a single feature to a point in time. This makes development easier, you don't want the system changing around you as you develop a feature. Merge does a great job at integrating branches when they're ready (As long as you're project isn't completely different [if it is you have bigger problems]). It also lets you become more flexible, branches can merge with other branches or features without getting changes they're not interested in.</p> <p>It's also good to remember if you just want to sync with a remote such as the origin you can use fetch which avoids the implicit merge of pull.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ TechEd Australia 2013 ]]>
</title>
<description>
<![CDATA[ The first day at TechEd offered two main sessions the developer kick off and the Keynote. The developer kick off touched on a new Visual… ]]>
</description>
<link>https://daniellittle.dev/teched-at-2013</link>
<guid isPermaLink="false">https://daniellittle.dev/teched-at-2013</guid>
<pubDate>Wed, 04 Sep 2013 01:00:00 GMT</pubDate>
<content:encoded><p>The first day at TechEd offered two main sessions the developer kick off and the Keynote. The developer kick off touched on a new Visual Studio 2013 feature called Browser Link for ASP.NET and Team Foundation Service.</p> <p>The kick off started by introducing One ASP.NET which is the unification of all web related .NET technologies, frameworks and libraries like MVC, SignalR and Web Forms can be mixed and matched however you like and all fall under the one ASP.NET umbrella. There has been a range of improvement to intellisense across the board particularly in html and CSS editors. The main highlight was the introduction to Browser Link by the creator of Web Essentials for Visual Studio.</p> <p>Brower link enables a persistent link from Visual Studio to whatever web browser you use. It enables a few interesting scenarios the first of which being changes made to CSS are instantly reflected in all the browsers connected by Browser Link. Edits to razor files require a little more than a save (one key combo) because behind the scenes you're telling each connected browser to refresh the page but you neve have to leave Visual Studio. Imagine you're trying to iron out a few CSS quirks across two or more browsers. You can have two browsers open at the same time and CSS changes appear instantly on both browsers as soon as you save the file making comparisons efficient and easy.</p> <p>Browser link also lets you do the inverse, you can use the web browser to jump to the exact line in your razor template that an element corresponds to via the inspector (Ctrl-Alt-I). You can also go one step further, ctrl-alt-d enables edit mode which can let you do thinks link edit html or Action Links and other <code class="language-text">Html</code> helpers which are updated in real time and this all works in any browser.</p> <p>The next session introduced Team Foundation Service which has a set of features coming to the next version of Team Foundation Server. There are a few interesting features including git support, a free tier for up to 5 users, a scrum style backlog and Trello-esk cards. Also notably was the addition of an integrated persistent chat room through which you can share news and chat with other members but also see general activity in the project such as build and code review events.</p> <p>The primary keynote had a few speakers, the main talk was from the CEO of Yammer. This was the one of the best talks I've seen and it talked about organisations and change. The theme was Blink and you'll miss it. The rate at which technology is changing is happening so fast that it's becoming even more important for people and organisations to be able to learn and react faster. If you wait too long it's already irrelevant. This means instead of long release cycles where failure means 2-3 years of work goes down the drain, moving to pushing updates every month. This means the cost of failure is much smaller as well. What's worse changing one month of work or one year's worth. This is so important for organisations and this quote by Jack Welch describes it perfectly.</p> <p>"If the rate of change on the outside exceeds the rate of change on the inside, the end is near."</p> <p>There have been an increasing number of disruptive changes happening in the last 5 or so years. Communication has enabled modern society to move ideas and information much faster than ever before. The problem we see in companies these days is that people inside organisations don't communicate very well, especially across departments. The outside world is moving so fast because it's a network of self motivated people and we need to bring that into our companies and organisations. These types of organisations are called Responsive Organisations and you can read more about what it means to be one at <a href="https://www.theresponsiveorg.com/manifesto">https://www.theresponsiveorg.com/manifesto</a>.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ John Carmack Keynote ]]>
</title>
<description>
<![CDATA[ John Carmack's keynote this year was a fantastic talk about software engineering. Parts three and four of the keynote touched on all the key… ]]>
</description>
<link>https://daniellittle.dev/john-carmack-keynote</link>
<guid isPermaLink="false">https://daniellittle.dev/john-carmack-keynote</guid>
<pubDate>Sat, 03 Aug 2013 01:00:00 GMT</pubDate>
<content:encoded><p>John Carmack's keynote this year was a fantastic talk about software engineering. Parts <a href="https://www.youtube.com/watch?v=93GwwNLEBFg">three</a> and <a href="https://www.youtube.com/watch?v=1PhArSujR_A">four</a> of the keynote touched on all the key hot topics including Code Quality, Functional Programming, Static Typing vs Dynamic Typing, Static Analysis and Garbage Collection. Defiantly worth watching if you're into professional development, and if not it's still worth watching.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ My PowerShell Profile ]]>
</title>
<description>
<![CDATA[ This is my PowerShell profile, it does a few nice things such as add and commands to the shell. Most importantly though it customizes my… ]]>
</description>
<link>https://daniellittle.dev/my-powershell-profile</link>
<guid isPermaLink="false">https://daniellittle.dev/my-powershell-profile</guid>
<pubDate>Wed, 03 Jul 2013 01:00:00 GMT</pubDate>
<content:encoded><p>This is my PowerShell profile, it does a few nice things such as add <code class="language-text">open</code> and <code class="language-text">edit</code> commands to the shell. Most importantly though it customizes my prompt to shorten it while still showing how deep I am in the directory hierarchy. I've also set up <code class="language-text">poshgit</code> as well as a few other helpers and functions.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">function Open($path) { explorer $path } function Edit { [CmdletBinding()] Param( [Parameter(Mandatory = $False, ValueFromPipeline = $True, ValueFromRemainingArguments = $True, Position = 0)] $File ) Process { $app = &quot;C:\Program Files (x86)\Notepad++\notepad++.exe&quot; if ($File -ne $null) { $parameters = &#39;&quot;&#39; + $File + &#39;&quot;&#39; $options = New-Object &quot;System.Diagnostics.ProcessStartInfo&quot; $options.FileName = $app $options.Arguments = $parameters $options.WorkingDirectory = $pwd $temp = [Diagnostics.Process]::Start($options).WaitForInputIdle(500) } Invoke-Item $app } } # This was already here function elevate-process { $file, [string]$arguments = $args; $psi = new-object System.Diagnostics.ProcessStartInfo $file; $psi.Arguments = $arguments; $psi.Verb = &quot;runas&quot;; $psi.WorkingDirectory = get-location; [System.Diagnostics.Process]::Start($psi); } set-alias sudo elevate-process; # WebGet function get-html([string]$url) { $webClient = (New-Object System.Net.WebClient); $webClient.DownloadString($url); } function shorten-path([string] $path) { $loc = $path.Replace($HOME, &#39;~&#39;) # remove prefix for UNC paths $loc = $loc -replace &#39;^[^:]+::&#39;, &#39;&#39; # make path shorter like tabs in Vim, # handle paths starting with \\ and . correctly return ($loc -replace &#39;\\(\.?)([^\\])[^\\]*(?=\\)&#39;,&#39;\$1$2&#39;) } function prompt { # our theme $cdelim = [ConsoleColor]::DarkCyan $chost = [ConsoleColor]::Green $cloc = [ConsoleColor]::Cyan $default = [ConsoleColor]::White # Reset color, which can be messed up by Enable-GitColors $Host.UI.RawUI.ForegroundColor = $default write-host (shorten-path (pwd).Path) &quot;&quot; -n -f $cloc Write-VcsStatus return &#39;&gt; &#39; } # gci . *.cs -Recurse | select-string . | Group Filename | Measure-Object Count -Min -Max -Average function CountLines($directory) { $pattern = &quot;*.cs&quot; $directories = [System.IO.Directory]::GetDirectories($directory) $files = [System.IO.Directory]::GetFiles($directory, $pattern) $lineCount = 0 foreach($file in $files) { $lineCount += [System.IO.File]::ReadAllText($file).Split(&quot;`n&quot;).Count } foreach($subdirectory in $directories) { $lineCount += CountLines $subdirectory } $lineCount } $msbuildPath = &quot;C:\Windows\Microsoft.NET\Framework\v4.0.30319\&quot; $gitPath = (Get-Item &quot;Env:LocalAppData&quot;).Value + &quot;\GitHub\PortableGit_93e8418133eb85e81a81e5e19c272776524496c6\cmd\&quot; $env:path += &quot;;$gitPath;$msbuildPath;&quot; function Enable-Git { . &#39;C:\Users\me\Documents\WindowsPowerShell\Modules\posh-git\profile.example.ps1&#39; } #Write-Host &quot;For git use &#39;Enable-Git&#39;&quot; function Load-Profile { . $Profile } function Edit-Profile { edit &quot;C:\Users\me\Documents\WindowsPowerShell\Profile.ps1&quot; } function Git-Log([switch]$OneLine, $Length) { $Length = 1000; if ($OneLine) { git log --pretty=oneline -n $Length } else { git log -n $Length } }</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ Testing emails in .NET ]]>
</title>
<description>
<![CDATA[ Testing emails can sometimes be a bit challenging. smtp4dev is a small program that intercepts all received emails so you can quickly send… ]]>
</description>
<link>https://daniellittle.dev/testing-emails-with-smtp4dev</link>
<guid isPermaLink="false">https://daniellittle.dev/testing-emails-with-smtp4dev</guid>
<pubDate>Mon, 29 Apr 2013 01:00:00 GMT</pubDate>
<content:encoded><p>Testing emails can sometimes be a bit challenging. <a href="https://smtp4dev.codeplex.com/">smtp4dev </a>is a small program that intercepts all received emails so you can quickly send and view emails from any application that uses it as the SMTP server.</p> <p>For a .NET application just add this to the config file.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&lt;mailSettings&gt; &lt;smtp&gt; &lt;network host=&quot;localhost&quot;/&gt; &lt;/smtp&gt; &lt;/mailSettings&gt;</code></pre></div> <p>Now all emails that the application sends will appear for your viewing pleasure in the email list (pictured below).</p> <p><img src="https://media.tumblr.com/ae0bed5688e8d01ea2d03a68430b17cf/tumblr_inline_mm04feyvwV1qz4rgp.png"></p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Loading Settings From web.config ]]>
</title>
<description>
<![CDATA[ It's always a good idea to be as consistent as possible when you're writing code. So when you're using settings from a configuration file it… ]]>
</description>
<link>https://daniellittle.dev/loading-settings-dotnet</link>
<guid isPermaLink="false">https://daniellittle.dev/loading-settings-dotnet</guid>
<pubDate>Sat, 20 Apr 2013 01:00:00 GMT</pubDate>
<content:encoded><p>It's always a good idea to be as consistent as possible when you're writing code. So when you're using settings from a configuration file it's a good idea to avoid sprinkling <code class="language-text">ConfigurationManager.AppSettings[&quot;MySetting&quot;]</code> around the codebase, especially if you've making multiple calls to it.</p> <p>A great way to provide consistency and to remove this duplication is to create a settings class either one static global one or multiple instance classes which I'll then manage with dependency injection. Then I load all the settings from configuration into that class on start up.</p> <p>I've also written a little library that makes use of reflection to make this even easier.</p> <p>Once my settings are in my config file</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt; &lt;configuration&gt; &lt;appSettings&gt; &lt;add key=&quot;Domain&quot; value=&quot;example.com&quot; /&gt; &lt;add key=&quot;PagingSize&quot; value=&quot;30&quot; /&gt; &lt;add key=&quot;Invalid.C#.Identifier&quot; value=&quot;test&quot; /&gt; &lt;/appSettings&gt; &lt;/configuration&gt;</code></pre></div> <p>I make a static or instance class depending on my needs. For simple applications with only a few settings one static class is fine.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">private static class Settings { public string Domain { get; set; } public int PagingSize { get; set; } [Named(&quot;Invalid.C#.Identifier&quot;)] public string ICID { get; set; } }</code></pre></div> <p>Then using my library call either <code class="language-text">Inflate.Static</code> or <code class="language-text">Inflate.Instance</code> and the cool thing is I can use any key value source.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">using Fire.Configuration; Inflate.Static( typeof(Settings), x =&gt; ConfigurationManager.AppSettings[x] ); var settings = new SpecificSettings(); Inflate.Instance( settings, x =&gt; ConfigurationManager.AppSettings[x] );</code></pre></div> <p>All the code for this is in bitbucket at <a href="https://bitbucket.org/Lavinski/fire">https://bitbucket.org/Lavinski/fire</a></p> <p>There is even a nuget package <a href="https://nuget.org/packages/Fire/">https://nuget.org/packages/Fire/</a></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Install-Package Fire</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ Wildcards hostname in your hosts file ]]>
</title>
<description>
<![CDATA[ If you've ever wanted to setup a wildcard entry in your hosts file so you don't have to add an entry for every IIS binding you'll be happy… ]]>
</description>
<link>https://daniellittle.dev/wildcard-hostnames</link>
<guid isPermaLink="false">https://daniellittle.dev/wildcard-hostnames</guid>
<pubDate>Wed, 10 Apr 2013 01:00:00 GMT</pubDate>
<content:encoded><p>If you've ever wanted to setup a wildcard entry in your hosts file so you don't have to add an entry for every IIS binding you'll be happy to know there is a way.</p> <p>The trick however is not to use the hosts file but a local DNS proxy instead. <a href="https://mayakron.altervista.org/wikibase/show.php?id=AcrylicHome">Acrylic DNS</a> is a free and open source which you can download <a href="https://mayakron.altervista.org/wikibase/show.php?id=AcrylicHome">here</a>. You use it in much the same way you would use a hosts file.</p> <p>Stackoverflow has a great answer detailing how to set it up:</p> <h3><a href="https://stackoverflow.com/posts/9695861/edit">Configuring Acrylic DNS Proxy</a></h3> <p><strong>To configure Acrylic DNS Proxy, install it from the above link then go to:</strong></p> <ol> <li>Start</li> <li>Programs</li> <li>Acrilic DNS Proxy</li> <li>Config</li> <li>Edit Custom Hosts File</li> </ol> <p><strong>Add the folowing lines on the end of the file:</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">127.0.0.1 *.localhost 127.0.0.1 *.local</code></pre></div> <p><strong>Restart the Acrilic DNS Proxy service:</strong></p> <ol> <li>Start</li> <li>Programs</li> <li>Acrilic DNS Proxy</li> <li>Config</li> <li>Restart Acrilic Service</li> </ol> <p><strong>You will also need to adjust your DNS setting in you network interface settings:</strong></p> <ol> <li>Start</li> <li>Control Panel</li> <li>Network and Internet</li> <li>Network Connections</li> <li>Local Area Connection Properties</li> <li>TCP/IPv4</li> </ol> <p><strong>Set "Use the following DNS server address":</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Preferred DNS Server: 127.0.0.1</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ Multiple https bindings in IIS7 for developers ]]>
</title>
<description>
<![CDATA[ When working with websites that require https (SSL) developers always ending up facing the problem: Why can't you use hostnames with https… ]]>
</description>
<link>https://daniellittle.dev/iis-multi-https-bindings</link>
<guid isPermaLink="false">https://daniellittle.dev/iis-multi-https-bindings</guid>
<pubDate>Wed, 20 Mar 2013 02:00:00 GMT</pubDate>
<content:encoded><p>When working with websites that require https (SSL) developers always ending up facing the problem: <strong>Why can't you use hostnames with https</strong>. This is because hostname is encrypted so IIS needs to establish the SSL connection before it can even read the hostname.</p> <p>However we can get around this problem by making use of a wildcard certificate. Then it won't matter what the hostname is and we can happily use SSL on all our internal dev sites.</p> <p>You can't actually use IIS to setup a wildcard certificate so I'll be using a bit of Powershell to move things along.</p> <p>The first step is to create the self signed certificate. Any clients will also have to trust this certificate.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$cert = New-SelfSignedCertificate -DnsName &quot;*.company.internal&quot; -CertStoreLocation cert:\LocalMachine\My Export-Certificate -Cert $cert -FilePath &quot;company.internal.cer&quot; $password = ConvertTo-SecureString -String &quot;SecretHeHe&quot; -Force –AsPlainText Export-PfxCertificate -Cert $cert -FilePath &quot;company.internal.pfx&quot; -Password $password</code></pre></div> <p>Next add the bindings to IIS, this script will add a http and https binding for each combination of site and environment.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$sites = @( &quot;website&quot; ) $envs = @( &quot;test&quot;, &quot;stage&quot; ) Import-Module WebAdministration foreach ($name in $sites) { foreach ($env in $envs) { $name = &quot;$name ($env)&quot; $siteName = &quot;$name ($env)&quot; New-WebBinding -Name $siteName -Port 80 -Protocol http -HostHeader &quot;$env.$name.company.internal&quot; New-WebBinding -Name $siteName -Port 443 -Protocol https -HostHeader &quot;$env.$name.company.internal&quot; } }</code></pre></div> <p>Just one thing left, setup IIS to use the certificate. To do that open IIS and import the certificate. Then select the open one of the https bindings and select the certificate (it won't matter which one, any site on that port will use it).</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Properties Visual Studio passes to MSBuild ]]>
</title>
<description>
<![CDATA[ It always takes me ages to kind what properties Visual Studio makes available to the MSBuild project files so here's the full set. Source… ]]>
</description>
<link>https://daniellittle.dev/visual-studio-msbuild</link>
<guid isPermaLink="false">https://daniellittle.dev/visual-studio-msbuild</guid>
<pubDate>Fri, 08 Mar 2013 02:00:00 GMT</pubDate>
<content:encoded><p>It always takes me ages to kind what properties Visual Studio makes available to the MSBuild project files so here's the full set.</p> <pre style="max-height: 300px"> $(RemoteMachine) Set to the value of the Remote Machine property on the Debug property page. See Changing Project Settings for a C/C++ Debug Configuration for more information. $(Configuration) The name of the current project configuration (for example, "Debug"). $(Platform) The name of current project platform (for example, "Win32"). $(ParentName) (Deprecated.) Name of the item containing this project item. This will be the parent folder name, or project name. $(RootNameSpace) The namespace, if any, containing the application. $(IntDir) Path to the directory specified for intermediate files relative to the project directory. This path should have a trailing slash. This resolves to the value for the Intermediate Directory property. $(OutDir) Path to the output file directory, relative to the project directory. This path should have a trailing slash. This resolves to the value for the Output Directory property. $(DevEnvDir) The installation directory of Visual Studio 2010 (defined as drive + path); includes the trailing backslash '\'. $(InputDir) (Deprecated; migrated.) The directory of the input file (defined as drive + path); includes the trailing backslash '\'. If the project is the input, then this macro is equivalent to $(ProjectDir). $(InputPath) (Deprecated; migrated.) The absolute path name of the input file (defined as drive + path + base name + file extension). If the project is the input, then this macro is equivalent to $(ProjectPath). $(InputName) (Deprecated; migrated.) The base name of the input file. If the project is the input, then this macro is equivalent to $(ProjectName). $(InputFileName) (Deprecated; migrated.) The file name of the input file (defined as base name + file extension). If the project is the input, then this macro is equivalent to $(ProjectFileName). $(InputExt) (Deprecated; migrated.) The file extension of the input file. It includes the '.' before the file extension. If the project is the input, then this macro is equivalent to $(ProjectExt). $(ProjectDir) The directory of the project (defined as drive + path); includes the trailing backslash '\'. $(ProjectPath) The absolute path name of the project (defined as drive + path + base name + file extension). $(ProjectName) The base name of the project. $(ProjectFileName) The file name of the project (defined as base name + file extension). $(ProjectExt) The file extension of the project. It includes the '.' before the file extension. $(SolutionDir) The directory of the solution (defined as drive + path); includes the trailing backslash '\'. $(SolutionPath) The absolute path name of the solution (defined as drive + path + base name + file extension). $(SolutionName) The base name of the solution. $(SolutionFileName) The file name of the solution (defined as base name + file extension). $(SolutionExt) The file extension of the solution. It includes the '.' before the file extension. $(TargetDir) The directory of the primary output file for the build (defined as drive + path); includes the trailing backslash '\'. $(TargetPath) The absolute path name of the primary output file for the build (defined as drive + path + base name + file extension). $(TargetName) The base name of the primary output file for the build. $(TargetFileName) The file name of the primary output file for the build (defined as base name + file extension). $(TargetExt) The file extension of the primary output file for the build. It includes the '.' before the file extension. $(VSInstallDir) The directory into which you installed Visual Studio 2010. This property contains the version of the targeted Visual Studio, which might be different that the host Visual Studio. For example, when building with $(PlatformToolset) = v90, $(VSInstallDir) contains the path to the Visual Studio 2008 installation. $(VCInstallDir) The directory into which you installed Visual C++ 2010. This property contains the version of the targeted Visual C++, which might be different that the host Visual Studio. For example, when building with $(PlatformToolset) = v90, $(VCInstallDir) contains the path to the Visual C++ 2008 installation. $(FrameworkDir) The directory into which the .NET Framework was installed. $(FrameworkVersion) The version of the .NET Framework used by Visual Studio. Combined with $(FrameworkDir), the full path to the version of the .NET Framework use by Visual Studio. $(FrameworkSDKDir) The directory into which you installed the .NET Framework. The .NET Framework could have been installed as part of Visual Studio 2010 or separately. $(WebDeployPath) The relative path from the web deployment root to where the project outputs belong. Returns the same value as RelativePath. $(WebDeployRoot) The absolute path to the location of <localhost>. For example, c:\inetpub\wwwroot. $(SafeParentName) (Deprecated.) The name of the immediate parent in valid name format. For example, a form is the parent of a .resx file. $(SafeInputName) (Deprecated.) The name of the file as a valid class name, minus file extension. $(SafeRootNamespace) (Deprecated.) The namespace name in which the project wizards will add code. This namespace name will only contain characters that would be permitted in a valid C++ identifier. $(FxCopDir) The path to the fxcop.cmd file. The fxcop.cmd file is not installed with all Visual C++ editions. </pre> <p>Source: <a href="https://msdn.microsoft.com/en-us/library/c02as0cs.aspx">https://msdn.microsoft.com/en-us/library/c02as0cs.aspx</a></p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Switch from 'Entity Framework Linq' to 'Linq to Objects' with AsEnumerable ]]>
</title>
<description>
<![CDATA[ Most people know what when writing a Linq query with Entity Framework that until that query is enumerated it won't call out to the database… ]]>
</description>
<link>https://daniellittle.dev/ef-linq-as-emumerable</link>
<guid isPermaLink="false">https://daniellittle.dev/ef-linq-as-emumerable</guid>
<pubDate>Thu, 14 Feb 2013 02:00:00 GMT</pubDate>
<content:encoded><p>Most people know what when writing a Linq query with Entity Framework that until that query is enumerated it won't call out to the database. Sometimes it's necessary to do some more work with the results such as use a method as part of the projection. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var result = from people in Context.People where people.DateOfBirth &lt; twentyYearsAgo select people; function GetAge(DateTime dateOfBirth) { ...</code></pre></div> <p>This is where <code class="language-text">AsEnumerable</code> comes in. This generic function allows you to switch from the <code class="language-text">IQueryable</code> source to <code class="language-text">IEnumerable</code> which will use Linq to Objects. Using AsEnumerable instead of <code class="language-text">ToList</code> allows us to still delay the execution of the query until it's needed.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var query = from people in Context.People where people.DateOfBirth &lt; twentyYearsAgo select people; var result = from people in query.AsEnumerable() select GetAge(people.DateOfBirth);</code></pre></div> <p>You could do the same thing by casting to the IEnumerable type but for anonymous objects you'll find you need to use AsEnumerable anyway to infer the type from the query.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Using ProviderName to get the database connection ]]>
</title>
<description>
<![CDATA[ When setting your connection string in a .NET config file you can make use of the attribute by using and passing it the provider name. ]]>
</description>
<link>https://daniellittle.dev/dbproviderfactories</link>
<guid isPermaLink="false">https://daniellittle.dev/dbproviderfactories</guid>
<pubDate>Fri, 01 Feb 2013 02:00:00 GMT</pubDate>
<content:encoded><p>When setting your connection string in a .NET config file you can make use of the <code class="language-text">providerName</code> attribute by using <code class="language-text">DbProviderFactories.GetFactory</code> and passing it the provider name. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var connectionStringSettings = ConfigurationManager.ConnectionStrings[&quot;DefaultConnection&quot;]; connection = DbProviderFactories.GetFactory(connectionStringSettings.ProviderName).CreateConnection(); connection.ConnectionString = connectionStringSettings.ConnectionString; connection.Open();</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ Entity Framework and Foreign key constraint may cause cycles or multiple cascade paths ]]>
</title>
<description>
<![CDATA[ Today I ran into the issue for the first time. The first thing to note is the error isn't actually from Entity Framework it's from SQL… ]]>
</description>
<link>https://daniellittle.dev/ef-multiple-cascade-paths</link>
<guid isPermaLink="false">https://daniellittle.dev/ef-multiple-cascade-paths</guid>
<pubDate>Mon, 21 Jan 2013 02:00:00 GMT</pubDate>
<content:encoded><p>Today I ran into the <code class="language-text">Foreign key constraint may cause cycles or multiple cascade paths</code> issue for the first time. The first thing to note is the error isn't actually from Entity Framework it's from <a href="https://stackoverflow.com/questions/851625/foreign-key-constraint-may-cause-cycles-or-multiple-cascade-paths">SQL Server</a>.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Introducing FOREIGN KEY constraint &#39;ConstraintName&#39; on table &#39;TableName&#39; may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.</code></pre></div> <p>I was however using EF5 Code First so I fist needed to figure out why my model was giving me back this error. The error message itself pointed me to the Schema table referring to the Project table. Note my schema looks a bit like this:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Project { Id, Name } Schema { Id, ProjectId, ... } Node { Id, ProjectId, ... }</code></pre></div> <p>As you can see there are two relationships to the Projects table, which is usually fine. The issue comes from the fact that EF using the <code class="language-text">OneToManyCascadeDeleteConvention</code> convention my default. Which was not what I wanted for these two relationships.</p> <p>My EF model takes the convention and attribute approach, I try to avoid the fluent API to keep everything in the one place. However there is currently no attribute to turn off cascade delete.</p> <p>Here is how to do it using the fluent API:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">internal sealed class SchemaConfiguration : EntityTypeConfiguration&lt;Schema&gt; { public SchemaConfiguration() { this .HasRequired(x =&gt; x.Project) .WithMany() .WillCascadeOnDelete(false); } } /// &lt;summary&gt; /// Model Creating Event Handler. /// &lt;/summary&gt; protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new NodeConfiguration()); }</code></pre></div> <p><a href="https://stackoverflow.com/questions/5532810/entity-framework-code-first-defining-relationships-keys">Need more help</a></p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Ninject and Singletons in the WebAPI with Scopes ]]>
</title>
<description>
<![CDATA[ The new Activation Blocks in Ninject are great for automatically resolving dependencies in the request scope. However they suffer from one… ]]>
</description>
<link>https://daniellittle.dev/ninject-webapi</link>
<guid isPermaLink="false">https://daniellittle.dev/ninject-webapi</guid>
<pubDate>Fri, 11 Jan 2013 02:00:00 GMT</pubDate>
<content:encoded><p>The new <a href="https://www.planetgeek.ch/2012/04/23/future-of-activation-blocks/#more-3392">Activation Blocks</a> in Ninject are great for automatically resolving dependencies in the request scope. However they suffer from one flaw which is they don't respect Constant or Singletons in fact they ignore the scope completely!</p> <p>In my application I needed a reference my dependency injection container in one of my objects. This would end up throwing <code class="language-text">Error loading Ninject component ICache</code> at the end of the request because now I had two kernels. Not good at all however I still had hope.</p> <p>Luckily there is one type of binding the <code class="language-text">ActivationBlock</code> can't ignore. The <code class="language-text">ToMethod</code> binding. So now I can make a small <code class="language-text">ScopedResolver</code> class which I can then inject into my class instead.</p> <p><strong>Binding</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">kernel.Bind&lt;ScopedResolver&gt;().ToMethod(x =&gt; { return new ScopedResolver((IActivationBlock)x.GetScope()); });</code></pre></div> <p><strong>ScopedResolver</strong></p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public class ScopedResolver { IActivationBlock resolver; public ScopedResolver(IActivationBlock resolver) { this.resolver = resolver; } public T TryGet&lt;T&gt;() { return resolver.TryGet&lt;T&gt;(); } }</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ Silverlight Page Transition Complete Event ]]>
</title>
<description>
<![CDATA[ While creating a mixed silverlight and xna WP7 application I started to add in page transitions with the silverlight toolkit. For the… ]]>
</description>
<link>https://daniellittle.dev/silverlight-page-transition</link>
<guid isPermaLink="false">https://daniellittle.dev/silverlight-page-transition</guid>
<pubDate>Sun, 07 Oct 2012 01:00:00 GMT</pubDate>
<content:encoded><p>While creating a mixed silverlight and xna WP7 application I started to add in page transitions with the silverlight toolkit. For the silverlight part of the application they work perfectly however when transitioning to the game screen the animation was not present.</p> <p>This is because in <code class="language-text">OnNavigatedTo</code> i'm obtaining the graphics device which overrides the rendering and this occurs <em>before</em> the animations starts.</p> <p>At this point you have two choices, implements a transition like effect manually in xna or delay obtaining the graphics device until the animation completes and display some content to transition with.</p> <p>I'm going to give a sample of how to do the latter.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public GamePage() { tansitionEnd = new RoutedEventHandler(GamePage_EndTransition); } protected override void OnNavigatedTo(NavigationEventArgs e) { TransitionService.GetNavigationInTransition(this).EndTransition += tansitionEnd; base.OnNavigatedTo(e); } protected void GamePage_EndTransition(object sender, RoutedEventArgs e) { TransitionService.GetNavigationInTransition(this).EndTransition -= tansitionEnd; }</code></pre></div> <p>The reason I picked the latter is because I will be using silverlight to render some parts of the UI. It's also important to note that as soon as you share the graphics device page level transitions will not render as xna takes over. However as stated above it's still possible to create a transition manually inside xna.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ SharePoint WebConfig Modifications ]]>
</title>
<description>
<![CDATA[ Example for adding or removing a webconfig modification in SharePoint 2010. Usage: ]]>
</description>
<link>https://daniellittle.dev/sharepoint-webconfig-mods</link>
<guid isPermaLink="false">https://daniellittle.dev/sharepoint-webconfig-mods</guid>
<pubDate>Wed, 25 Jul 2012 01:00:00 GMT</pubDate>
<content:encoded><p>Example for adding or removing a webconfig modification in SharePoint 2010. </p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">private void UpdateWebConfig(string name, string path, string owner, SPWebConfigModification.SPWebConfigModificationType type, string value, SPWebApplication app, bool removeModification) { if (removeModification) { var removals = app.WebConfigModifications.Where(item =&gt; item.Name == name).ToList(); foreach (var item in removals) { app.WebConfigModifications.Remove(item); } } else { SPWebConfigModification modification = new SPWebConfigModification(); modification.Name = name; modification.Path = path; modification.Owner = owner; modification.Sequence = 0; modification.Type = type; modification.Value = value; app.WebConfigModifications.Add(modification); } app.Update(); app.Farm.Services.GetValue&lt;SPWebService&gt;().ApplyWebConfigModifications(); }</code></pre></div> <p>Usage:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">UpdateWebConfig( &quot;add[@name=&#39;handlerName&#39;]&quot;, &quot;configuration/system.webServer/handlers&quot;, &quot;FeatureName&quot;, SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, &quot;&lt;add name=&#39;handlerName&#39; verb=&#39;*&#39; path=&#39;service.axd&#39; type=&#39;Namespace, Assembily, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0x0xx00000x00xx0&#39; /&gt;&quot;, webApplication, false );</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ Inheriting SharePoint masterpages with Powershell ]]>
</title>
<description>
<![CDATA[ If you want your subsites to inherit their masterpages from their parents the first thing you need to know is the difference between normal… ]]>
</description>
<link>https://daniellittle.dev/sharepoint-masterpages-powershell</link>
<guid isPermaLink="false">https://daniellittle.dev/sharepoint-masterpages-powershell</guid>
<pubDate>Wed, 06 Jun 2012 01:00:00 GMT</pubDate>
<content:encoded><p>If you want your subsites to inherit their masterpages from their parents the first thing you need to know is the difference between normal sites and publishing sites: Only publishing sites actually support inheriting masterpages. If you're site is not a publishing site you have to iterate over all the <code class="language-text">Webs</code> and set the property manually.</p> <p>If you have a publishing site your in luck SharePoint makes it easy for you but it's not completely obvious what to do. My first attempt at setting these properties to <code class="language-text">Inherit</code> was by setting the site property. And while this does make the UI say the right thing, it doesn't actually change the property <code class="language-text">CustomMasterUrl</code> in any way and you'll just get the old masterpage.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$web.AllProperties[&quot;__InheritsCustomMasterUrl&quot;] = &quot;True&quot; // This is wrong</code></pre></div> <p>What you have to do is update the <code class="language-text">CustomMasterUrl</code> as well, but then you're getting into unsupported functionality and it's also unnecessary work. Conveniently SharePoint already provides you with a <code class="language-text">PublishingWeb</code> class that supports inheritance for these properties.</p> <p>Here is an example:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">$isPubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::IsPublishingWeb($web) if ($isPubWeb) { $pubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web) } if ($xmlNode.CustomMaster -ne $null) { if ($xmlNode.CustomMaster -eq &quot;Inherit&quot;) { if ($isPubWeb) { # https://msdn.microsoft.com/en-us/library/ms562472.aspx $pubWeb.CustomMasterUrl.SetInherit($true, $false) } else { Write-Host -Fore Red &quot;You cannot inherit without a publishing web!&quot; } } else { $url = $($site.ServerRelativeUrl + &quot;/_catalogs/masterpage/&quot; + $xmlNode.CustomMaster) if ($isPubWeb) { $pubWeb.CustomMasterUrl.SetValue($url, $false) } else { $web.CustomMasterUrl = $url } } }</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ If you are going to do something, do it right ]]>
</title>
<description>
<![CDATA[ I love this quote and I think it really fits in with what I'm doing with this blog, and in my everyday life. Taking pride in your work is… ]]>
</description>
<link>https://daniellittle.dev/do-it-right</link>
<guid isPermaLink="false">https://daniellittle.dev/do-it-right</guid>
<pubDate>Sat, 26 May 2012 01:00:00 GMT</pubDate>
<content:encoded><p>I love this quote and I think it really fits in with what I'm doing with this blog, and in my everyday life. Taking pride in your work is the only way to ensure that it's as good as it can be. Every day I like to feel that things are better than when I started. It's oftern the little things that count the most and here I have the opportunity to explain why.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Physics for games ]]>
</title>
<description>
<![CDATA[ I'm revisiting a lot of the physics and I predict trigonometry that was once a daily part of my life before graduating university. I'm… ]]>
</description>
<link>https://daniellittle.dev/physics-for-games</link>
<guid isPermaLink="false">https://daniellittle.dev/physics-for-games</guid>
<pubDate>Tue, 22 Nov 2011 02:00:00 GMT</pubDate>
<content:encoded><p>I'm revisiting a lot of the physics and I predict trigonometry that was once a daily part of my life before graduating university.</p> <p>I'm surprised by how much I'd forgotten and writing it down always helps you remember it. Especially when it's on a blog and you can search for it later ;).</p> <p>The system I'll be focusing on is Rigid Body Dynamics so lets start with the basics.</p> <p>Any input into the system should be in the form of an impulse, which is basically a force against a point on a body. If all the impulses act against the center off mass we can deal with it just like a simple force.</p> <p>The formula for a force:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">force = mass x acceleration</code></pre></div> <p>Which can be rewritten as:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">acceleration = force / mass</code></pre></div> <p>Which is great because our input is a force and mass can be whatever fits for our simple system which gives us acceleration.</p> <p>The next thing we need is the velocity formula:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">velocity = acceleration x Δtime</code></pre></div> <p>Now for those of you that don't know Δ or in in English Delta means change or in this case change in time.</p> <p>You should keep track of your objects velocity and add to it whenever the body experiences acceleration.</p> <p>So now we have velocity and here comes position which we also keep track off and add to.</p> <p>Position formula:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">position = velocity x Δtime</code></pre></div> <p>Now we can do all the way from the initial push to there the body ends up after a known change in time. The same also applies to angular forces and motion but that's something I'll get to later. To be honest I'm still trying to wrap my head around <a href="https://en.wikipedia.org/wiki/Inertia_tensor">inertia tensors</a> which you need to</p> <p>Helpful links <a href="https://en.wikipedia.org/wiki/Dynamical_simulation">Dynamical simulation</a></p></content:encoded>
</item>
<item>
<title>
<![CDATA[ WP7 Mango Unit Testing Framework "Cannot find a Resource with the Name/Key typeNameConverter" ]]>
</title>
<description>
<![CDATA[ When trying to setup unit testing I was slightly dissapoited you couldn't test a silverlight library using a normal test project. However… ]]>
</description>
<link>https://daniellittle.dev/wp7-typenameconverter</link>
<guid isPermaLink="false">https://daniellittle.dev/wp7-typenameconverter</guid>
<pubDate>Tue, 18 Oct 2011 01:00:00 GMT</pubDate>
<content:encoded><p>When trying to setup unit testing I was slightly dissapoited you couldn't test a silverlight library using a normal test project. However you can use the testing framework by using the <a href="https://www.jeff.wilcox.name/2010/05/sl3-utf-bits/">Silverlight 3 libraries here</a>.</p> <p>However you have to make sure you get the right version. I didn't and instead I found a link to an older tutorial and got the nice error <code class="language-text">Cannot find a Resource with the Name/Key typeNameConverter</code> and the only <a href="https://www.silverlightshow.net/news/A-Batch-File-for-Closing-Zune-and-Launching-the-WPConnect-Tool-Workaround-for-WP7-Mango-Unit-Testing-Framework-Cannot-find-a-Resource-with-the-Name-Key-typeNameConverter.aspx">real match</a> for the error had a broken link. The solution was simple though, find the source and update to the Mango version.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ C# and casting ]]>
</title>
<description>
<![CDATA[ I see alot of people using the keywork where they really just want to do a cast. Most of the time a cast will be what you want because it's… ]]>
</description>
<link>https://daniellittle.dev/c-casting</link>
<guid isPermaLink="false">https://daniellittle.dev/c-casting</guid>
<pubDate>Tue, 27 Sep 2011 01:00:00 GMT</pubDate>
<content:encoded><p>I see alot of people using the <code class="language-text">as</code> keywork where they really just want to do a cast. Most of the time a cast will be what you want because it's faster and will fail early when somthing goes wrong.</p> <p>When should you <code class="language-text">cast</code>? You should cast when you already know what type the object is. A cast also will **not ** fail your value is null.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var value = (Apple)appleDictionary[key];</code></pre></div> <p>When should you use <code class="language-text">as</code>? When you don't know the type of object.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">bool makeA = true; BaseClass baseClass = null; baseClass = makeA ? new SuperClassA() : new SuperClassB(); SuperClassB val = baseClass as SuperClassB; if (val != null) { //...</code></pre></div> <p>You will almost always be compairing the value to <code class="language-text">null</code> after using as.</p> <p>It's important to know <code class="language-text">as</code> does not replace <code class="language-text">cast</code> in any way, always pick the one you need for your situation.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ IIS Background Thread Abort Exception ]]>
</title>
<description>
<![CDATA[ One of my applications creates a background thread on startup which executes a series of tasks at a regular interval. However I get a after… ]]>
</description>
<link>https://daniellittle.dev/iis-background-threads</link>
<guid isPermaLink="false">https://daniellittle.dev/iis-background-threads</guid>
<pubDate>Sat, 27 Aug 2011 01:00:00 GMT</pubDate>
<content:encoded><p>One of my applications creates a background thread on startup which executes a series of tasks at a regular interval. However I get a <code class="language-text">ThreadAbortException</code> after my application pool is recycled.</p> <p>The problem is simply IIS is aborting my thread and my application is not handling it well. I found the solution in <a href="https://stackoverflow.com/questions/4347870/how-can-i-find-out-why-my-thread-is-being-stopped-in-asp-net">this Stack Overflow question</a>. You have to tell your thread to stop via the Application_End method in Global.asax.cs which gets called when the application is recycled.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ C# and AOP (Aspect-oriented programming) ]]>
</title>
<description>
<![CDATA[ I just had a very interesting experience with AOP in C#. I have a function with a return type List which is being intercepted and that's all… ]]>
</description>
<link>https://daniellittle.dev/c-apo</link>
<guid isPermaLink="false">https://daniellittle.dev/c-apo</guid>
<pubDate>Fri, 26 Aug 2011 01:00:00 GMT</pubDate>
<content:encoded><p>I just had a very interesting experience with AOP in C#. I have a function with a return type List<Update> which is being intercepted and that's all well and good. However the interceptor function is a validator style function and can prevent the real function by being called and returning the boolean false.</p> <p>So the code looks a little bit like this:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">List&lt;Update&gt; updates = Manager.ValidateAndCreate(); // protected void Save(List&lt;Update&gt; updates) { .... Save(updates);</code></pre></div> <p>The Method Interceptor looks like the following</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">public class ExceptionAdvice : AopAlliance.Intercept.IMethodInterceptor { public object Invoke(AopAlliance.Intercept.IMethodInvocation invocation) { if (isValid(invocation)) { return invocation.Proceed(); } else { return false; } } private bool isValid( ... }</code></pre></div> <p>Now after validation fails the value of updates is actually a boolean not a List<Update>, I thought there would be some kind of runtime error here but there was not, so:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">updates.GetType().Name == &quot;Boolean&quot;</code></pre></div> <p>But:</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">updates is bool == false</code></pre></div> <p>So save will still accept its mutated list of updates and will complain later on when you try to use it.</p> <p>So how is this possible in a type safe language like C#? btw it's spring-aop.</p> <p><a href="https://stackoverflow.com/questions/7200572/c-and-aop-aspect-oriented-programming-how-does-this-work">Link to the StackOverflow question</a></p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Object-Relational Mapper Exceptions ]]>
</title>
<description>
<![CDATA[ When working with Object-Relational Mappers like nhibernate and Entity Framework 4 it can seem like a good idea to setup a Session or… ]]>
</description>
<link>https://daniellittle.dev/orm-exceptions</link>
<guid isPermaLink="false">https://daniellittle.dev/orm-exceptions</guid>
<pubDate>Fri, 19 Aug 2011 01:00:00 GMT</pubDate>
<content:encoded><p>When working with Object-Relational Mappers like nhibernate and Entity Framework 4 it can seem like a good idea to setup a Session or Context at the start of a request and finalise it at the end of a request.</p> <p>This is exactly what I was doing until I figured out how wrong it was. I'll be using <em><a href="https://stackoverflow.com/questions/2478081/entity-framework-4-poco-where-to-start">Entity framework</a></em> for my examples so I'm not repeating myself. So the problem is basically that a Context is not your database access object but a <em>Unit of Work</em> that will be committed to the database. This is an extremely important point and this is because of exception handling.</p> <p>Now for a nice example, say you want to save a record to the users table but the username has a uniqueness constraint. If we're using one context per request and try to add a new user with an unavailable username we get a nice <em>UpdateException</em>. Now once this happens you can't use the context anymore. As a work around you can test for error states in a transaction before they happen, but that's allot of work and doesn't sound too nice.</p> <p>The solution therefore is to perform actions as a Unit of Work. That way if one doesn't work out you can handle it properly and recover.</p> <p>Take a look at this article to point you in the right direction <a href="https://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx">Using Repository and Unit of Work patterns with Entity Framework 4.0</a>.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Sharepoint People Picker Displays Selection as Html ]]>
</title>
<description>
<![CDATA[ When adding a people picker to a custom Html page I encountered an interesting error. When submitting the page the content would return… ]]>
</description>
<link>https://daniellittle.dev/sharepoint-peope-picker-bug</link>
<guid isPermaLink="false">https://daniellittle.dev/sharepoint-peope-picker-bug</guid>
<pubDate>Tue, 02 Aug 2011 01:00:00 GMT</pubDate>
<content:encoded><p>When adding a people picker to a custom Html page I encountered an interesting error. When submitting the page the content would return hidden html from the control along with the message “You are only allowed to enter one item”.</p> <p>The html looks like this.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">&lt; span id=’span xxxxx’ tabindex=’-1’ contentEditable=’false’ class=’ms-entity-resolved’ title=’xxxxx’ /&gt;</code></pre></div> <p>The issue seems to be I’m using IE 9 Standards mode, as SharePoint usualy runs in quirks mode.</p> <p>Similar issues: <a href="https://blog.richfinn.net/blog/CommentView,guid,4fce2e56-8e53-48cb-b6d9-6249af8e2141.aspx">https://blog.richfinn.net/blog/CommentView,guid,4fce2e56-8e53-48cb-b6d9-6249af8e2141.aspx</a></p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Sharepoint Permissions ]]>
</title>
<description>
<![CDATA[ The SharePoint permission model uses user impersonation, where a typical asp.net application will run under the permissions of the… ]]>
</description>
<link>https://daniellittle.dev/sharepoint-permissions</link>
<guid isPermaLink="false">https://daniellittle.dev/sharepoint-permissions</guid>
<pubDate>Tue, 05 Jul 2011 01:00:00 GMT</pubDate>
<content:encoded><p>The SharePoint permission model uses user impersonation, where a typical asp.net application will run under the permissions of the application pool SharePoint runs under the users credentials.</p> <p>The scenario we’ll be looking at is updating a sharepoint list programmatically.</p> <p>SharePoint has four default user groups, Read, Contributor, Designer and Full Control. Users would usually be in any of these groups or anything in between. This means that unless the users are also given explicit access to the list directly or via a group they may not have access to update a list even if allow unsafe updates is on.</p> <p>To resolve this issue there are two solutions.</p> <p>*The first is no revert back to the app pool, using this method means you have to identify the current user manually and by default all updates will appear as created or modified by the system account. *The second option is to assign users access to the list explicitly or create a group with access and add the group to the users (either automatically or manually via SharePoint).</p> <p>In my case I needed a solution where users could not access the list normally but using my custom solution allowed them to make updates. Therefore option one was the way to go for me.</p></content:encoded>
</item>
<item>
<title>
<![CDATA[ Audit Data of Sharepoint List Items ]]>
</title>
<description>
<![CDATA[ Here is how to read list item data in sharepoint 2007. ]]>
</description>
<link>https://daniellittle.dev/audit-data-sharepoint-list-items</link>
<guid isPermaLink="false">https://daniellittle.dev/audit-data-sharepoint-list-items</guid>
<pubDate>Fri, 01 Jul 2011 01:00:00 GMT</pubDate>
<content:encoded><p>Here is how to read list item data in sharepoint 2007.</p> <div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">var listItem = getMyItem(); string creator = listItem[&quot;Created By&quot;]; DateTime created = listItem[&quot;Created&quot;];</code></pre></div></content:encoded>
</item>
<item>
<title>
<![CDATA[ AppHarbor - First Impressions ]]>
</title>
<description>
<![CDATA[ App Harbor is a great new cloud hosting service, which I’ve been trying out over the last few weeks. It deploys straight from source code… ]]>
</description>
<link>https://daniellittle.dev/appharbor-first-impressions</link>
<guid isPermaLink="false">https://daniellittle.dev/appharbor-first-impressions</guid>
<pubDate>Tue, 28 Jun 2011 01:00:00 GMT</pubDate>
<content:encoded><p>App Harbor is a great new cloud hosting service, which I’ve been trying out over the last few weeks. It deploys straight from source code using msbuild to transform your webconfigs, run your tests and deploy to the servers. </p> <p>However there’s a few things that I didn’t realise untill I’d started using it for a while. Firstly GIT support on windows if not the greatest and while it has been working fine Mercurial has been getting some popularity as an alternative and appharbor even has some support for working with it with bitbucket. </p> <p>Secondly its cloud based and when you try to get a CMS running you quickly realise they don’t work too well across multiple servers. As you need a central storage location for uploaded files, and CMS managed files. You can get it working and it’s something App Harbor is also looking into but it’s no simple deploy at the moment. </p></content:encoded>
</item>
<item>
<title>
<![CDATA[ About Daniel Little ]]>
</title>
<description>
<![CDATA[ I'm a Software Engineer based in Brisbane Australia, with a focus on developing web based systems. I enjoy functional programming, domain… ]]>
</description>
<link>https://daniellittle.dev/about</link>
<guid isPermaLink="false">https://daniellittle.dev/about</guid>
<pubDate>Fri, 23 Apr 2010 00:00:00 GMT</pubDate>
<content:encoded><p>I'm a Software Engineer based in Brisbane Australia, with a focus on developing web based systems. I enjoy functional programming, domain driven design, distributed systems and event sourcing. But most of all I enjoy solving problems. As a developer I have the ability to create something from nothing. To make peoples jobs and lives, better and more enjoyable. It's an amazing feeling to make a real impact to companies and people everyday.</p> <p>In software development, you never get far alone. The best software is backed by amazing teams built on trust, empathy and humility. These teams know that working software is the best measure of progress; you must deliver working software frequently. They know technical excellence always aligns with the business objectives; you can't go faster by cutting corners. And they know communication is the most crucial element in software development.</p> <p>I value good work culture because people and technology are intrinsically intertwined. I know having context is key for building great software and I try to always optimise for people. I believe technical excellence always aligns with the business objectives and I value and strive to be more authentic to share and discover real stories.</p> <p>You can find me on twitter at <a href="https://twitter.com/daniellittledev">https://twitter.com/daniellittledev</a></p> <p>And at other places on the web such as:</p> <ul> <li><a href="https://stackoverflow.com/users/200442/daniel-little">Stackoverflow</a></li> <li><a href="https://github.com/daniellittledev">Github</a></li> <li><a href="https://www.linkedin.com/in/daniellittle">LinkedIn</a></li> </ul></content:encoded>
</item>
</channel>
</rss>