<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
    <title>HutchCodes</title>
    <link>https://hutchcodes.net/</link>
    <atom:link href="https://hutchcodes.net/rss.xml" rel="self" type="application/rss+xml" />
    <description></description>
    <language>en-us</language>
    <pubDate>Wed, 07 May 2025 13:50:08 UTC</pubDate>
    <lastBuildDate>Wed, 07 May 2025 13:50:08 UTC</lastBuildDate>
    
    <item>
      
      <category>Blazor</category>
      
      
      <category>CodeProject</category>
      

      <title>App Settings in Client-Side Blazor</title>
      <link>https://hutchcodes.net/2019/12/blazor-wasm-app-settings/</link>
      <pubDate>Tue, 17 Dec 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/12/blazor-wasm-app-settings/</guid>
      <description>&lt;p&gt;I’ve been spoiled by Asp.Net and expect app settings to just work, but there is no easily configured app settings story for client-side Blazor &lt;em&gt;yet&lt;/em&gt;. What I’m looking for is the ability to set some settings on a per-environment (dev/test/beta/prod) through Azure App Service Application Settings. The goal is one build artifact that moves from environment to environment with zero changes.&lt;/p&gt;

&lt;p&gt;If you host the Blazor app as static files you’d need to change the app settings file for each different environment. So, I’ve gone with Asp.Net Core Web Hosted. I’ve named the app AppSettingsExample, so in the solution we have AppSettingsExample.Client (the WASM app), AppSettingsExample.Server (the host app), and AppSettingExample.Shared (code that is shared between the Client and Server)&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;loading-client-app-settings&quot;&gt;Loading Client App Settings&lt;/h3&gt;

&lt;p&gt;We’ll store and access the client app settings through the built-in configuration in AppSettingsExample.Server. To do that we’ll add an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appsettings.json&lt;/code&gt; with the following values.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{
  &quot;ClientAppSettings&quot;: {
    &quot;BaseApiUrl&quot;: &quot;http://somesite.com/api&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’ll also create a class in the AppSettingsExample.Shared project to hold those configurations.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public class ClientAppSettings
{
    public string BaseApiUrl { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then in the AppSettingsExample.Server’s Startup we’ll get a reference to the application’s configuration and store it in a local variable.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;private readonly IConfiguration _configuration;

public Startup(IConfiguration configuration)
{
    _configuration = configuration;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This allows us to use that config to load the settings from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appsettings.json&lt;/code&gt; and add it to the dependency injection config as a singleton.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton(_configuration.GetSection(&quot;ClientAppSettings&quot;).Get&amp;lt;ClientAppSettings&amp;gt;());
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;exposing-the-settings-to-the-client&quot;&gt;Exposing the Settings to the Client&lt;/h3&gt;

&lt;p&gt;There isn’t an easy way to just pass the settings into the client-side Blazor app, so we’ll need the app to request them from the server. We’ll create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClientAppSettingsController&lt;/code&gt; to AppSettingsExample.Server to serve up these settings.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[Route(&quot;api/[controller]&quot;)]
[ApiController]
public class ClientAppSettingsController : ControllerBase
{
    private readonly ClientAppSettings _clientAppSettings;

    public ClientAppSettingsController(ClientAppSettings clientAppSettings)
    {
        _clientAppSettings = clientAppSettings;
    }

    [HttpGet]
    public ClientAppSettings GetClientAppSettings()
    {
        return _clientAppSettings;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;getting-the-settings-from-the-client&quot;&gt;Getting the Settings from the Client&lt;/h3&gt;

&lt;p&gt;This is where I had the most trouble. I need to completely load these settings before the application can move on. If I did it asynchronously, it would start running the Initialization and ParameterSet methods on the current page before the settings load completed. If I tried to force the asynchronous web request to complete synchronously by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.Wait()&lt;/code&gt;, the application locked up.&lt;/p&gt;

&lt;p&gt;To get around this we can create a component that loads the settings and once loaded displays its child content. Then we can wrap our content in this component to make sure it doesn’t start initializing or setting parameters until the settings are loaded. First, we create &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppSettingsLoader.razor&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@using AppSettingExample.Shared
@inject HttpClient http

@if (IsLoaded)
{
    @ChildContent
}


@code 
{
    [Parameter]
    public RenderFragment ChildContent { get; set; }

    public bool IsLoaded { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        if (!IsLoaded)
        {
            var appSettings = await http.GetJsonAsync&amp;lt;ClientAppSettings&amp;gt;(&quot;api/ClientAppSettings&quot;);
            AppSettings.BaseApiUrl = appSettings.BaseApiUrl;
            IsLoaded = true;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Because we can’t (or I couldn’t) load the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClientAppSettings&lt;/code&gt; instance into the Dependency Injection to make it available throughout the application, I’m just putting the values in a static &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppSettings&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Now, in the MainLayout.razor we can wrap the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@body&lt;/code&gt; with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppSettingsLoader&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;AppSettingsLoader&amp;gt;
@Body
&amp;lt;/AppSettingsLoader&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And finally, from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Index.razor&lt;/code&gt; page we can reference the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppSettings.BaseApiUrl&lt;/code&gt;. To prove it out, I’ll just display it on the page.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@page &quot;/&quot;
&amp;lt;h1&amp;gt;Hello, world!&amp;lt;/h1&amp;gt;

@AppSettings.BaseApiUrl
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And now we can set any setting we like in the ClientAppSettings sections of the AppSettings.json and it will be treated just like a normal app setting, including being able to set the setting through Configuration section of an Azure App Service.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - Code Definition Keyboard Shortcuts</title>
      <link>https://hutchcodes.net/2019/04/visual-studio-tips-code-definition-keyboard-shortcuts/</link>
      <pubDate>Wed, 24 Apr 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/04/visual-studio-tips-code-definition-keyboard-shortcuts/</guid>
      <description>&lt;p&gt;Often when we’re coding, we need to take a look at the definition or sometimes the implementation of a method we’re calling. Visual Studio has a few great ways to speed these tasks.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;goto-definition&quot;&gt;Goto Definition&lt;/h3&gt;

&lt;p&gt;To see the definition of a variable, class, interface or method, you place your cursor on the thing you want to see the definition of, and either press &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F12&lt;/code&gt; or right click and choose &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Goto Definition&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One catch with Goto Definition is that when you use it to go to a definition of a property or method, it goes it goes to the definition of the object as it is declared. That means that if you hit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F12&lt;/code&gt; on all of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SayHello()&lt;/code&gt; methods below you would go to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IGreeter.SayHello&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greeter1&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SimpleGreeter.SayHello&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greeter2&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greeter3&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WorldGreeter.SayHello()&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greeter4&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;            &lt;span class=&quot;n&quot;&gt;IGreeter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greeter1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SimpleGreeter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greeter1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SayHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;SimpleGreeter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greeter2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SimpleGreeter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greeter2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SayHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;SimpleGreeter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greeter3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;WorldGreeter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greeter3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SayHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;WorldGreeter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greeter4&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;WorldGreeter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greeter4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SayHello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;peek-definition&quot;&gt;Peek Definition&lt;/h3&gt;

&lt;p&gt;If you wanted to take a peek at the definition without navigating to its definition, you can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Alt+F12&lt;/code&gt; or right click and choose &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Peek Definition&lt;/code&gt;. This brings up the definition in a little window within the code editor. You can still scroll through the code of the definition without losing your place in the code you are editing. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Esc&lt;/code&gt; closes the Peek window.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/PeekDefinition.jpg&quot; alt=&quot;alt text&quot; title=&quot;View hierarchy window&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;goto-implementation&quot;&gt;Goto Implementation&lt;/h3&gt;

&lt;p&gt;If you want to view the implementation of a method or property rather than its definition you can press &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+F12&lt;/code&gt; or right click and choose &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Goto Implementation&lt;/code&gt;. If there is only one implementation for a method, Visual Studio takes you directly to the implementation. If there are multiple implementations, it brings up a window that lists the implementations. You can view the implementations by using your arrow keys or by clicking on them.&lt;/p&gt;

&lt;p&gt;For the code above it would go directly to the implementation for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greeter4.SayHello()&lt;/code&gt;, for all the others it would bring up the implementation selector window.&lt;/p&gt;

&lt;h3 id=&quot;find-all-references&quot;&gt;Find All References&lt;/h3&gt;

&lt;p&gt;Sometimes it’s helpful to see what other code is referencing a method or property. For that, you can use the official shortcut &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+K+R&lt;/code&gt;, or the unlisted shortcut &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Shift+F12&lt;/code&gt;, or you can right click and choose &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Find All References&lt;/code&gt;. This brings up a window that lists all the references to that method. This displays the same list regardless of how the object is declared.&lt;/p&gt;

&lt;h3 id=&quot;view-call-hierarchy&quot;&gt;View Call Hierarchy&lt;/h3&gt;

&lt;p&gt;Sometimes it is handy to be able to see what code is calling a method or property, and what code led to that call. To see that you can right click on the method or property you’re interested in and choose ‘View Call Hierarchy’ or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+K, Ctrl+T&lt;/code&gt;. This brings up a tree view with the method or property you’re interested in and allows you to dig in until you get to the initial action that caused the method or property to be called. In the case below we can see that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SayHello()&lt;/code&gt; method was called by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Run()&lt;/code&gt; method which was called by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Main([string])&lt;/code&gt;. In the right pane, we can see the line and column that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Run()&lt;/code&gt; is called from and double-clicking that takes us to that location.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/ViewCallHierarchy.jpg&quot; alt=&quot;alt text&quot; title=&quot;View hierarchy window&quot; /&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - Bulk Editing Shortcuts</title>
      <link>https://hutchcodes.net/2019/04/visual-studio-tips-editing-shortcuts/</link>
      <pubDate>Mon, 15 Apr 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/04/visual-studio-tips-editing-shortcuts/</guid>
      <description>&lt;p&gt;One of the most tedious things we do as developers is making repetitive changes. Maybe we need to set a handful of properties on a single object, or perhaps we want to add a property to the instantiation of a bunch of test objects. Here are a few shortcuts to help you with that.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;multi-caret-editing&quot;&gt;Multi-Caret Editing&lt;/h3&gt;

&lt;p&gt;Let’s start with adding a property to the instantiation of some test objects. This is often the perfect scenario for “muti-caret editing.” To start this you can do two things. The first is to position your caret where you’d like to start editing on the first line, then hold &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Shift+Alt&lt;/code&gt; and either use your arrows or the mouse to select a column or area. The beautiful thing about this method is it allows you to select a block of text to replace.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/MultiCaretReplace.gif&quot; alt=&quot;alt text&quot; title=&quot;Using Shift Alt to replace text on multiple lines&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The drawback of using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Shift+Alt&lt;/code&gt; is that the columns you want to edit must line up vertically. But frequently that isn’t the case, and that’s where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+Alt&lt;/code&gt; comes into play. With &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+Alt&lt;/code&gt; you set the multiple carets by holding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+Alt&lt;/code&gt; and clicking where you want to edit. You can then insert text in all those places, even multiple times on the same line.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/MultiCaretInsert.gif&quot; alt=&quot;alt text&quot; title=&quot;Using Control Alt to insert text on multiple lines&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;duplicate-line&quot;&gt;Duplicate Line&lt;/h3&gt;

&lt;p&gt;Those work great if the lines you want to edit already exist, or if you know how many lines you need to create at once. But I often find myself wanting to duplicate a line and make a few changes to it. For that, you can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+E, Ctrl+V&lt;/code&gt; keyboard shortcut which duplicates the line your cursor is on.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/DuplicateLine.gif&quot; alt=&quot;alt text&quot; title=&quot;Duplicate line with Control E, Control V&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;clipboard-ring&quot;&gt;Clipboard Ring&lt;/h3&gt;

&lt;p&gt;Another feature I find very useful when I’m making repeated edits is the Clipboard Ring. When you hit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+Shift+V&lt;/code&gt;, it brings up your clipboard ring which includes the last nine things you’ve copied or cut (more recently used at the top). You can then select the item you want to paste by typing the number, using your arrow keys or clicking with your mouse.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/ClipboardRing.gif&quot; alt=&quot;alt text&quot; title=&quot;Using Clipboard Ring&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This can be useful when you need to copy multiple things from one file to another. You no longer need to flip back and forth, just copy, copy, paste, paste.&lt;/p&gt;

&lt;h3 id=&quot;insert-file-as-text&quot;&gt;Insert File as Text&lt;/h3&gt;

&lt;p&gt;This last feature I just stumbled upon while looking for something in the Edit menu. It’s not something I expect to use a lot, but it might be useful. In the edit menu is a command “Insert File as Text”, and the command does just what it says.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/InsertFileAsText.gif&quot; alt=&quot;alt text&quot; title=&quot;Using Edit, Insert File as Text to insert a file as text&quot; /&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - Test Explorer</title>
      <link>https://hutchcodes.net/2019/04/visual-studio-tips-test-explorer/</link>
      <pubDate>Mon, 08 Apr 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/04/visual-studio-tips-test-explorer/</guid>
      <description>&lt;p&gt;The Test Explorer has a great ability to filter tests in a number of different ways so you don’t have to run your whole test suite when you’re just working on something that only affects a handful of tests.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;First when running tests, remember the few handy keyboard shortcuts&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+R,T&lt;/code&gt; - Run all tests&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+R,Ctrl+T&lt;/code&gt; - Debug all tests&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+R,L&lt;/code&gt; - Re-run last test run&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+R,Ctrl+L&lt;/code&gt; - Debug last test run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ability to re-run the last test run can be very handy if you don’t want to take the time to filter your test run down. You can right click and run the test or group of tests that makes sense, then use the keyboard shortcut re-run that set of tests until you’re ready to move on.&lt;/p&gt;

&lt;h3 id=&quot;group-by&quot;&gt;Group By&lt;/h3&gt;

&lt;p&gt;By default, the Test Explorer window uses the ‘Test Hierarchy’ view which displays tests based on Project, Namespace, Class, Test, TestCase. If you turn off the ‘Test Hierarchy’ view you have the option to change the grouping to one of the following views:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Class - Groups tests by Class, Test, TestCase. Though the namespace isn’t displayed classes with the same name in different namespaces are shown separately.&lt;/li&gt;
  &lt;li&gt;Duration - Groups tests into 3 buckets. Fast (&amp;lt;100ms), Medium, Slow (&amp;gt;1s)&lt;/li&gt;
  &lt;li&gt;Namespace - Grouped by Namespace, Class, Test, TestCase&lt;/li&gt;
  &lt;li&gt;Project - Grouped by Project, Test, TestCase (ignores Namespace)&lt;/li&gt;
  &lt;li&gt;Outcome - Groups tests by Passed, Failed and Not Run. This is handy when you’re trying to fix a handful of failing tests.&lt;/li&gt;
  &lt;li&gt;Trait - Groups tests by various traits about the tests. Tests can be listed in this multiple times and combined with filters this can be a very powerful view.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/TestExplorerGroups.gif&quot; alt=&quot;alt text&quot; title=&quot;Animation of selecting various group by options&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;traits&quot;&gt;Traits&lt;/h3&gt;

&lt;p&gt;How you assign Traits for tests differs depending on what unit testing framework you choose. This example shows some basic traits from nUnit.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Integration_Tests&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Property&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Priority&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BazTests&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;BazTest1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Fail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Explicit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Slow_Tests&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Useless_Tests&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;BazTest2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Fail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’ve assigned all of the tests in the TestClass to the ‘Integration_Tests’ category, and also labeled that as ‘Priority 2’. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BazTest2&lt;/code&gt; test has been also marked as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Explicit&lt;/code&gt;, and it has been assigned that test to both the ‘Slow_Tests’ and the ‘Useless_Tests’ category.&lt;/p&gt;

&lt;p&gt;Now, when I view my test suite from the Test Explorer it looks like this&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/TestExploreTraits.jpg&quot; alt=&quot;alt text&quot; title=&quot;Tests grouped by Traits&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I can then apply a filter to that view to narrow it down. Let’s say I wanted to look at just ‘Integration_Tests’, I can add the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Trait:&quot;Integration_Tests&quot;&lt;/code&gt; filter to the search area of the Test Explorer. That removes all the tests that don’t meet that criteria, which still leaves me with 2 tests, but it still shows the other &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Traits&lt;/code&gt; related to those tests. I could just right click on the ‘Slow_Tests’ node and choose ‘Run Selected Tests’ and I would just run the BazTest2.&lt;/p&gt;

&lt;h3 id=&quot;playlists&quot;&gt;Playlists&lt;/h3&gt;

&lt;p&gt;Playlists allow you to create a custom group of tests by whatever criteria you decide. Maybe you have a group of tests that you want to run whenever you’re working on a certain part of the code. You can add those tests to a playlist then select the playlist to filter your tests. You can also check in these playlists for others to use.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/TestExplorerPlaylist.gif&quot; alt=&quot;alt text&quot; title=&quot;Animation of adding tests to a playlist&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;run-tests-after-build&quot;&gt;Run Tests After Build&lt;/h3&gt;

&lt;p&gt;Once you have your list of tests filtered just the way you want it, I recommend clicking the ‘Run Tests After Build’ button to ensure that your filtered list of tests runs after every build (tests marked &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Explicit&lt;/code&gt; will not run).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/TestExplorerRunOnBuild.jpg&quot; alt=&quot;alt text&quot; title=&quot;Run on build button&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Depending on how many tests you have in your filtered list, their performance and how well isolated they are, you may also want to have them run in parallel.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/TestExplorerRunParallel.jpg&quot; alt=&quot;alt text&quot; title=&quot;Run Parallel button&quot; /&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - Window Management</title>
      <link>https://hutchcodes.net/2019/04/visual-studio-tips-window-management/</link>
      <pubDate>Thu, 04 Apr 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/04/visual-studio-tips-window-management/</guid>
      <description>&lt;p&gt;Everyone has their own favorite layout for the various tool windows in Visual Studio. But sometimes you want different Window layouts based on what you’re working on, or whether you have external screens attached to your laptop.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;First the basics of tool windows.&lt;/p&gt;

&lt;p&gt;You can click and hold any window by its header (or its tab if it is already docked) and drag it. While drag it you will see a bunch of little blue boxes indicating where it can docked, if you drop it on one of those it will dock, otherwise it will float and can even be moved to a second monitor.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/WindowsDocking.gif&quot; alt=&quot;alt text&quot; title=&quot;Animation of docking a window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If a window is docked, you can Pin a window with the Thumbtack icon to make it always visible, or if it’s already pinned you can Unpin it to make it Autohide.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/WindowPinUnpin.jpg&quot; alt=&quot;alt text&quot; title=&quot;Window header with pin/unpin icon highlighted&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;save-your-window-layouts&quot;&gt;Save Your Window Layouts&lt;/h3&gt;

&lt;p&gt;Once you have all your windows where you want them you can Save the layout by going to Window -&amp;gt; Save Window Layout. You’ll be prompted to name your layout. This saves which windows are open, where they are docked, whether they are pinned or autohidden, &lt;strong&gt;and&lt;/strong&gt; their size.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/WindowSaveLayout.jpg&quot; alt=&quot;alt text&quot; title=&quot;Window Save Layout menu item&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once you’ve save a layout or two, you can either go back to the Window menu, click Apply Window Layout and select your layout from the list. Or you can use the hot key combination for the layout (ie &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+Shift+1&lt;/code&gt; for layout 1)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/WindowApplyLayout.jpg&quot; alt=&quot;alt text&quot; title=&quot;Window Apply Layout menu item&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;the-catch&quot;&gt;The Catch&lt;/h3&gt;

&lt;p&gt;The one slightly unintuitive part of saving window layouts is that when you save a layout, that is for both the layout for editing &lt;em&gt;and&lt;/em&gt; the layout for debugging which are often different. So to set a layout, you need to get all the windows where you want them in edit mode, then start a debug session to get all of those windows where you want them, then save the layout. Otherwise you’ll find yourself needing to switch layouts every time you go from editing to debugging and back.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - Keyboard Shortcuts for Debugging</title>
      <link>https://hutchcodes.net/2019/04/visual-studio-tips-debug-keyboard-shortcuts/</link>
      <pubDate>Wed, 03 Apr 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/04/visual-studio-tips-debug-keyboard-shortcuts/</guid>
      <description>&lt;p&gt;There are literally hundreds of keyboard shortcuts in Visual Studio, and few people have them all memorized, but it is definitely worthwhile to memorize at least a few. Here are some that are useful while you’re debugging.&lt;/p&gt;

&lt;!--more--&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F5&lt;/code&gt; - Run - This both starts the debugging session and continues the debugging session if the session is paused.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F10&lt;/code&gt; - Step Over - This runs just the next statement. If the next statement is a function call, it runs the whole function before pausing execution again (unless there is a breakpoint in the function).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F11&lt;/code&gt; - Step Into - This runs just the next statement. If the next statement is a function call, it will bring you to that function and pause before the first statement in there is run.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Shift+F11&lt;/code&gt; - Step Out - This runs until the code returns from the currently running function. It’s really handy when you are done debugging a function, but that function still has a lot of statements to execute.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+F10&lt;/code&gt; - Run to Cursor - This allows you to move the cursor to a line of code then run until the debugger gets there. This is handy if you want to skip over a block of code. You could also press &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F9&lt;/code&gt; then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F5&lt;/code&gt; which would add a Breakpoint at your cursor, then run to it.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+Shift+F10&lt;/code&gt; - Set Next Statement - This sets the line your cursor is on as the next statement the debugger will run. Really handy if you missed something and want to backup and debug it again.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Alt+Num *&lt;/code&gt; - Show Next Statement - Sorry laptop users, this one only works with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt; on the number pad. This one takes you to the next statement that will run. Really handy if you’ve been sifting through code and want to quickly return to your debugging without executing any statements.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Shift+F5&lt;/code&gt; - Stop Debugging - Ends your debugging session.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+Shift+F5&lt;/code&gt; - Restart Debugging - Getting the message “Edits were made to the code which cannot be applied while debugging”? This will quickly restart the debug session and have you on your way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these are of course available through the UI, but if you often find yourself looking for them in the command bar, or right clicking and trying to find them in the context menu, memorizing at least some of these shortcuts will keep you focused on the debugging.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - Trace Points</title>
      <link>https://hutchcodes.net/2019/04/visual-studio-tips-trace-points/</link>
      <pubDate>Tue, 02 Apr 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/04/visual-studio-tips-trace-points/</guid>
      <description>&lt;p&gt;Tracepoints are not a new feature, they’ve been in Visual Studio since 2005, but they are a new feature to me. I just stumbled on them while researching for this series of posts. Tracepoints allow you to turn a Breakpoint into what is essentially a call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Debug.WriteLine()&lt;/code&gt;.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;A Tracepoint is just a special kind of Breakpoint that allows you to log a message to the Output window and continue execution. This can be really helpful in situations where stopping at a breakpoint makes reproducing a bug difficult or impossible.&lt;/p&gt;

&lt;p&gt;And since Tracepoints are just a kind of Breakpoint, you can also put conditions on them and manage them just like Breakpoints. To learn more about Breakpoints see this &lt;a href=&quot;/2019/03/visual-studio-break-points/&quot;&gt;post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To set a Tracepoint, you set a normal breakpoint, then go into the settings of that Breakpoint and check &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Actions&lt;/code&gt;. That will display a textbox for you to create your log message and another checkbox to specify whether execution should stop or continue.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/Tracepoints.gif&quot; alt=&quot;alt text&quot; title=&quot;Visual of creating and using a Tracepoint.&quot; /&gt;&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - Using Data Tips</title>
      <link>https://hutchcodes.net/2019/04/visual-studio-tips-using-data-tips/</link>
      <pubDate>Mon, 01 Apr 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/04/visual-studio-tips-using-data-tips/</guid>
      <description>&lt;p&gt;Data tips, the Visual Studio feature that allows you to hover over a variable and see its value while debugging, can be super useful. Here are a few tricks that you may not know about them.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Have you ever been looking in the DataTips then need to look at the code behind them? Great news, you can. Just press and hold &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl&lt;/code&gt; key, the DataTips become transparent until you release the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl&lt;/code&gt; key. This is particularly useful when you’ve drilled down a bit in the DataTip or you’re trying to compare&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/DataTipsTransparent.gif&quot; alt=&quot;alt text&quot; title=&quot;Visual of making the data tips transparent.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Another thing you can do is either pin the DataTips. This persists the DataTip so you can navigate to other code, restart debugging or even restart Visual Studio and still have the DataTip be there when you break in that block the next time. Once you’ve pinned a DataTip you can move the data tip around by clicking and dragging, you can remove it by clicking the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;, or you can float the DataTip by clicking the pin icon. This allows you to view that DataTip while you scroll the code or view another file.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/DataTipsPinFloat.gif&quot; alt=&quot;alt text&quot; title=&quot;Visual of pinning, floating and closing a DataTip&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once you’ve pinned a DataTip, you can add expressions to that DataTip by right-clicking on the DataTip and choosing “Add Expression”. This can let you pin something more useful than what might normally display for an object. In this case, the &lt;a href=&quot;/2019/03/visual-studio-tips-debugger-display/&quot;&gt;DebuggerDisplay&lt;/a&gt; shows &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LastName, FirstName&lt;/code&gt;, but we can add an expression to display the Person object as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FirstName LastName&lt;/code&gt;. This is really handy for when you can’t change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DebuggerDisplay&lt;/code&gt; of an object.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/DataTipsAddExpression.gif&quot; alt=&quot;alt text&quot; title=&quot;Visual of adding a DataTip comment&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The other interesting feature of DataTips is that you can add comments to them.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/DataTipsComment.gif&quot; alt=&quot;alt text&quot; title=&quot;Visual of adding a DataTip comment&quot; /&gt;&lt;/p&gt;

&lt;p&gt;But what good are comments if you can’t share them? Well, you can export your DataTips to an XML file and either share them or check them in with your source. You could have a set of DataTips that you load up whenever you’re facing a common debugging scenario.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/DataTipsImportExport.jpg&quot; alt=&quot;alt text&quot; title=&quot;Visual of adding a DataTip comment&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You might also notice there are options in there to “Clear All DataTips”, and “Clear All DataTips from [CurrentFileName]”.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - Solution Explorer Search</title>
      <link>https://hutchcodes.net/2019/03/visual-studio-solution-explorer-search/</link>
      <pubDate>Fri, 29 Mar 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/03/visual-studio-solution-explorer-search/</guid>
      <description>&lt;p&gt;Solution Explorer Search has been in Visual Studio for a while, but there are a few features that I think many developers overlook (myself included). Here are a few that you might have missed.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;By default, the search will search &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+;&lt;/code&gt; both the file names and the contents. This is what we want most of the time, but it is possible to search just the file names.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/SolutionExplorerSearchNoContents.gif&quot; alt=&quot;alt text&quot; title=&quot;Visual of disabling search within file contents.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Some other filters you can apply to your search are Open Files &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+[,O&lt;/code&gt; and Pending Changes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+[,P&lt;/code&gt;. These can be particularly useful when you’re working on a feature that requires changes across multiple files in different layers of your solution. In the gif below I show these filters being used via the UI.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/SolutionExplorerSearchFilters.gif&quot; alt=&quot;alt text&quot; title=&quot;Visual of using search search filters.&quot; /&gt;&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - Breakpoints</title>
      <link>https://hutchcodes.net/2019/03/visual-studio-break-points/</link>
      <pubDate>Thu, 28 Mar 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/03/visual-studio-break-points/</guid>
      <description>&lt;p&gt;Most of us know about Breakpoints and how to use them, but there are a few under-utilized features of breakpoints that you should be aware of.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;You can set a simple breakpoint in a number of ways&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Move the cursor to the line you want to break on and hit the F9 key&lt;/li&gt;
  &lt;li&gt;Right click on the line of code&lt;/li&gt;
  &lt;li&gt;Clicking in the gutter&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you have a breakpoint set you can do a few things with it. First, you can disable it, if you don’t need the breakpoint right now, but think you might come back to it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/BreakpointDisable.gif&quot; alt=&quot;alt text&quot; title=&quot;Visual of disabling a breakpoint.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can also disable all breakpoints from Debug -&amp;gt; Disable all breakpoint. This is handy for when you need to run and get reset, then re-enable all breakpoints and start your debugging again.&lt;/p&gt;

&lt;p&gt;You can also make the breakpoint conditional based on the value of a variable or any boolean expression (yes, you can use the &lt;a href=&quot;/2019/03/visual-studio-tips-no-side-effects-function-eval/&quot;&gt;No Side Effects&lt;/a&gt; formatter). This can be helpful if you want to break when the value of a variable is a certain value.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/BreakpointConditional.gif&quot; alt=&quot;alt text&quot; title=&quot;Visual of creating a conditional breakpoint based on a boolean expression.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can also make the breakpoint conditional base on the number of times a breakpoint is hit. For example, you might know that the first time a breakpoint is hit isn’t interesting to your debugging scenario but every time after that is interesting. You could set hit count &amp;gt; 1.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/BreakpointHitcount.gif&quot; alt=&quot;alt text&quot; title=&quot;Visual of creating a conditional breakpoint based on hit count.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can also filter your breakpoints to a single thread or to exclude a thread, either by name or id.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - Source Map in the Scroll Bar</title>
      <link>https://hutchcodes.net/2019/03/visual-studio-tips-source-map-scroll-bar/</link>
      <pubDate>Wed, 27 Mar 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/03/visual-studio-tips-source-map-scroll-bar/</guid>
      <description>&lt;p&gt;Do you find yourself scrolling up and down in a large file in Visual Studio? “Show Source Maps in Scroll Bar” gives you a 1000 foot view of your code and allows you to navigate with a simple click.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;To turn this feature on go to Tool -&amp;gt; Options -&amp;gt; Text Editor -&amp;gt; Scroll Bars. In the Behavior section select “Use map mode for vertical scroll bar”. I also like to select “Show Preview Tooltip” as well. You can choose your own width, but I’ve been happy with “Medium”.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/TurnOnSourceMap.jpg&quot; alt=&quot;alt text&quot; title=&quot;Visual of turning on Source Map scroll bar.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once that’s done you can navigate your code like this&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/SourceMapScrollBar.gif&quot; alt=&quot;alt text&quot; title=&quot;Visual of turning on using the Source Map scroll bar.&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Note that both there are 3 artifacts on the Source Map.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;A white bar that indicates where you are in the document&lt;/li&gt;
  &lt;li&gt;A white block on the left side of the source map to indicate a bookmark&lt;/li&gt;
  &lt;li&gt;A red block on the left side of the source map to indicate a breakpoint&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - Evaluate a Function Without Side Effects</title>
      <link>https://hutchcodes.net/2019/03/visual-studio-tips-no-side-effects-function-eval/</link>
      <pubDate>Tue, 26 Mar 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/03/visual-studio-tips-no-side-effects-function-eval/</guid>
      <description>&lt;p&gt;Ever been debugging and wanted to know what the result a function call would but calling it would change the state in a way that would make continuing difficult or impossible? Well, you can evaluate it and specify that it does not have any side effects.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Take this simple class that tracks a count and has a method for incrementing that count.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Count&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AddOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we want to see what the result of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddOne()&lt;/code&gt; method would be, but we don’t want to actually increment the count because we can’t set it back we can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nse&lt;/code&gt; (no side effects) format specifier in both the watch window and the Immediate Window.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddOne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nse&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/NoSideEffects.gif&quot; alt=&quot;alt text&quot; title=&quot;Loop showing calling AddOne method with and with out nse&quot; /&gt;&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - View Uncaptured Exception</title>
      <link>https://hutchcodes.net/2019/03/visual-studio-tips-view-uncaptured-exception/</link>
      <pubDate>Mon, 25 Mar 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/03/visual-studio-tips-view-uncaptured-exception/</guid>
      <description>&lt;p&gt;Ever have code where you catch an exception because to handle it, but you don’t need to use the exception itself? Maybe just knowing the exception type is enough for you. But then you sometimes want to see it while debugging?&lt;/p&gt;

&lt;p&gt;Previously I would just capture the exception and just live with the warning about an unused variable, but now I do this.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;First, what do I mean when I say caught but not captured? In the code below I have caught the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;InvalidOperationException&lt;/code&gt; thrown by trying to get the first item from an empty collection. But I haven’t captured the exception in a variable.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;First&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InvalidOperationException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//Do something like logging or retry&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Without having to change the code at all we can view the exception by viewing the contents of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$exception&lt;/code&gt; pseudovariable which holds the value of the most recent exception. You can either get the value by adding it to your watch list or by evaluating it in the immediate window.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/UncapturedExceptionWatch.jpg&quot; alt=&quot;alt text&quot; title=&quot;Watch window showing the value of $exception&quot; /&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>VSTips</category>
      
      
      <category>CodeProject</category>
      

      <title>Visual Studio Tips - DebuggerDisplay</title>
      <link>https://hutchcodes.net/2019/03/visual-studio-tips-debugger-display/</link>
      <pubDate>Fri, 22 Mar 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/03/visual-studio-tips-debugger-display/</guid>
      <description>&lt;p&gt;When you look at an object in the Watch window what you see is whatever comes out of the ToString() method. But what if you could control what was displayed so that you could see some meaningful value? Well, you can.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;If we have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Person&lt;/code&gt; class define like this&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;VSTips.DebuggerDisplay&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we create an instance and look at it in the watch window all we see is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{VSTips.DebuggerDisplay.Person}&lt;/code&gt;. We can of course drill in to see the individual properties, and that isn’t so bad when you’re looking at a single object, but when you look at a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List&amp;lt;Person&amp;gt;&lt;/code&gt; and see this, you know you’re going to spend a lot of time clicking to find the object you’re looking for.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/NoDebuggerDisplay.jpg&quot; alt=&quot;alt text&quot; title=&quot;Ojects dispalyed without DebuggerDisplay attribute&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If we go back to the definition of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Person&lt;/code&gt; class and add an attribute we can make the watch window display whatever we want. In this case, we’ll display the last name and the first 5 characters of the first name (taking the first 5 just to show the flexability).&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Diagnostics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;VSTips.DebuggerDisplay&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;DebuggerDisplay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{LastName,nq}, {FirstName.Length &amp;gt;= 5 ? FirstName.Substring(0, 5) : FirstName,nq}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When you look at the watch list with this Debugger Display what you see is much more helpful.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2019/WithDebuggerDisplay.jpg&quot; alt=&quot;alt text&quot; title=&quot;Ojects dispalyed without DebuggerDisplay attribute&quot; /&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Sql</category>
      
      
      <category>CodeProject</category>
      

      <title>Random Value Per Row in SQL</title>
      <link>https://hutchcodes.net/2019/01/random-value-per-row-sql/</link>
      <pubDate>Tue, 08 Jan 2019 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2019/01/random-value-per-row-sql/</guid>
      <description>&lt;p&gt;Occasionally you need to update a table with a random value per row. And thanks to some optimizations SQL Server does, it’s not exactly straight forward.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;If you just try to update with a random value like this, every row ends up with the same ‘random’ value.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyTable&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;   
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is because SQL Server only runs the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rand()&lt;/code&gt; once because it doesn’t depend on any value from the row. My next thought was to see the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rand()&lt;/code&gt; with a value from each row.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyTable&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;--Where Id is in Int&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This wasn’t as random as I had hoped. Since my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Id&lt;/code&gt; column was an identity column the ‘random’ numbers were almost sequential as well. For example, I got the following ‘random’ numbers for the following &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Id&lt;/code&gt; values:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Id&lt;/th&gt;
      &lt;th&gt;Rand(Id)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;101&lt;/td&gt;
      &lt;td&gt;0.715436657367485&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;102&lt;/td&gt;
      &lt;td&gt;0.715455290338744&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;103&lt;/td&gt;
      &lt;td&gt;0.715473923310002&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;104&lt;/td&gt;
      &lt;td&gt;0.715473923310002&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;So, I needed to come up with a way to get the seed value to vary for each row. So I decided to get the MD5 hash of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Id&lt;/code&gt; column.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;update&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyTable&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HASHBYTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;md5&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That results in these values:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Id&lt;/th&gt;
      &lt;th&gt;rand(HASHBYTES(‘md5’, convert(varchar, Id)))&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;101&lt;/td&gt;
      &lt;td&gt;0.954016112182829&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;102&lt;/td&gt;
      &lt;td&gt;0.249482833129777&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;103&lt;/td&gt;
      &lt;td&gt;0.863832691946289&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;104&lt;/td&gt;
      &lt;td&gt;0.751055796147016&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;And that was random enough for my needs.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      <category>Blazor</category>
      
      <category>Razor Components</category>
      
      
      <category>CodeProject</category>
      

      <title>Data Driven Layout in Server-side Blazor</title>
      <link>https://hutchcodes.net/2018/09/data-driven-layout-in-razor-components/</link>
      <pubDate>Mon, 24 Sep 2018 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2018/09/data-driven-layout-in-razor-components/</guid>
      <description>&lt;p&gt;One thing I stumbled on with Blazor was how to create a layout that changed based on the data on the page. For example, you may want to include bread crumbs in the header of your page. You could get the URL and try to parse out where in the application from your MainLayout, and then figure out what you need to figure out to create your breadcrumbs. But ideally you’d have each page figure out it’s own breadcrumbs and pass that data to the header.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;In Razor Pages you could do this with a an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RenderSection&lt;/code&gt; in your layout, then defining the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Section&lt;/code&gt; in your page, which could be a component that you pass some values to. But, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RenderSection&lt;/code&gt; hasn’t been implemented in Blazor (I’m not sure if it’s coming or not). Here’s two alternative techniques.&lt;/p&gt;

&lt;p&gt;First thing we’ll need to do is open the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_ViewImports.cshtml&lt;/code&gt; and comment out or delete the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@layout MainLayout&lt;/code&gt; that defines the layout for all the pages in the folder.&lt;/p&gt;

&lt;p&gt;Then we’ll create an AppState class to hold the data we want to pass between the page and the layout. For now we’ll just capture the page name. This piece will be common between both techniques.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AppState&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CurrentPageName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The two techniques also share the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NavMenu&lt;/code&gt; which takes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppState&lt;/code&gt; and uses that to display the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CurrentPageName&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@if (!string.IsNullOrEmpty(appState.CurrentPageName))
{
    &amp;lt;div class=@(collapseNavMenu ? &quot;collapse&quot; : null) onclick=@ToggleNavMenu&amp;gt;
        &amp;lt;ul class=&quot;nav flex-column&quot;&amp;gt;
            &amp;lt;li class=&quot;nav-item px-3&quot; style=&quot;color:white;&quot;&amp;gt;
                Current Page: @appState.CurrentPageName
            &amp;lt;/li&amp;gt;
        &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
}

@functions {
    [Parameter] protected AppState appState { get; set; }

    bool collapseNavMenu = true;

    void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;layout-component&quot;&gt;Layout Component&lt;/h4&gt;

&lt;p&gt;For the Layout Component technique we’ll create a Blazor Component called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MainLayout2 &lt;/code&gt; that takes it’s child content from the calling markup. It has two key parameters, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppState&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ChildContent&lt;/code&gt;. It just passes the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppState&lt;/code&gt; along to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NavMenu&lt;/code&gt; component.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@inherits BlazorLayoutComponent

&amp;lt;div class=&quot;sidebar&quot;&amp;gt;
    &amp;lt;NavMenu appState=&quot;@appState&quot; /&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div class=&quot;main&quot;&amp;gt;
    &amp;lt;div class=&quot;top-row px-4&quot;&amp;gt;
        &amp;lt;a href=&quot;https://blazor.net&quot; target=&quot;_blank&quot; class=&quot;ml-md-auto&quot;&amp;gt;About&amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class=&quot;content px-4&quot;&amp;gt;
        @ChildContent
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

@functions
{
    [Parameter] protected AppState appState { get; set; }
    [Parameter] protected RenderFragment ChildContent { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Not that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RenderFragment&lt;/code&gt; must be named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ChildContent&lt;/code&gt; in order for Blazor to get the content correctly later.&lt;/p&gt;

&lt;p&gt;Then from the page we wrap the content of the page in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;MainLayout&amp;gt;&lt;/code&gt; tag and from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OnInit&lt;/code&gt; set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppState.CurrentPageName&lt;/code&gt; to the name of the page’&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@page &quot;/counter&quot;
@inherits BlazorComponent
&amp;lt;MainLayout2 AppState=&quot;@appState&quot;&amp;gt;
    &amp;lt;h1&amp;gt;Counter&amp;lt;/h1&amp;gt;

    &amp;lt;p&amp;gt;Current count: @currentCount&amp;lt;/p&amp;gt;

    &amp;lt;button class=&quot;btn btn-primary&quot; onclick=&quot;@IncrementCount&quot;&amp;gt;Click me&amp;lt;/button&amp;gt;    
&amp;lt;/MainLayout2&amp;gt;
@functions {
    int currentCount = 0;

    void IncrementCount()
    {
        currentCount++;
    }

    protected AppState appState { get; set; } = new AppState();

    protected override void OnInit()
    {
        appState.CurrentPageName = &quot;Counter&quot;;
        base.OnInit();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dependency-injection&quot;&gt;Dependency Injection&lt;/h3&gt;

&lt;p&gt;Another possibility is to use Dependency Injection to inject a single instance of the AppState into both the page and the layout, then updates to that object in the page will be visible to the layout.&lt;/p&gt;

&lt;p&gt;First we need register the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppState&lt;/code&gt; class in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StartUp.ConfigureServices&lt;/code&gt;. We need to register this as a Scoped lifetime. See my post on &lt;a href=&quot;/2018/09/dependency-injection-lifetimes-in-razor-components&quot;&gt;Blazor DI Lifetimes&lt;/a&gt; for a better understanding of the various lifetimes in Blazor.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddScoped&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AppState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MainLayout.cshtml&lt;/code&gt; we inject the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppState&lt;/code&gt; and pass that to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NavMenu&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@inherits BlazorLayoutComponent
@inject AppState appState

&amp;lt;div class=&quot;sidebar&quot;&amp;gt;
    &amp;lt;NavMenu appState=&quot;@appState&quot; /&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div class=&quot;main&quot;&amp;gt;
    &amp;lt;div class=&quot;top-row px-4&quot;&amp;gt;
        &amp;lt;a href=&quot;https://blazor.net&quot; target=&quot;_blank&quot; class=&quot;ml-md-auto&quot;&amp;gt;About&amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class=&quot;content px-4&quot;&amp;gt;
        @Body
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We also need to inject the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppState&lt;/code&gt; into the page, and set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CurrentPageName&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OnInit&lt;/code&gt; method. In this case since we’ve removed the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@layout&lt;/code&gt; directive from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_ViewImports.cshtml&lt;/code&gt; we need specify the layout in the page.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@page &quot;/counter2&quot;
@inject AppState appState
@layout MainLayout

&amp;lt;h1&amp;gt;Counter2&amp;lt;/h1&amp;gt;

&amp;lt;p&amp;gt;Current count: @currentCount&amp;lt;/p&amp;gt;

&amp;lt;button class=&quot;btn btn-primary&quot; onclick=&quot;@IncrementCount&quot;&amp;gt;Click me&amp;lt;/button&amp;gt;
@functions {
    int currentCount = 0;

    void IncrementCount()
    {
        currentCount++;
    }
    protected override void OnInit()
    {
        appState.CurrentPageName = &quot;Counter&quot;;
        base.OnInit();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;which-is-better&quot;&gt;Which is better&lt;/h3&gt;

&lt;p&gt;The biggest difference is the lifetime of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppState&lt;/code&gt;. With the Layout Component technique you create a new instance of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppState&lt;/code&gt; each time the page loads. With the Dependency Injection technique you keep the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppState&lt;/code&gt; until the user refreshes.&lt;/p&gt;

&lt;p&gt;This is a double edged sword. On the one hand, if you need to retrieve some data from the database or an API, you have built in caching. On the other hand you need to keep in mind that data might be stale.&lt;/p&gt;

&lt;p&gt;For an example of this you can download and run the complete project, navigate to /Counter2, then to FetchData. You’ll see that the current page is still listed as Counter2 because the line to set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CurrentPageName&lt;/code&gt; is commented out.&lt;/p&gt;

&lt;p&gt;The Layout Component technique on requires you to wrap your content in the layout tag. Not only is this extra boilerplate in every page, it’s may make it more difficult to do things like nested layouts.&lt;/p&gt;

&lt;p&gt;Full source &lt;a href=&quot;&quot;&gt;https://github.com/hutchcodes/Blazor.DataDrivenLayout&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      <category>Blazor</category>
      
      <category>Razor Components</category>
      
      
      <category>CodeProject</category>
      

      <title>Dependency Injection Lifetimes in Blazor</title>
      <link>https://hutchcodes.net/2018/09/dependency-injection-lifetimes-in-razor-components/</link>
      <pubDate>Mon, 17 Sep 2018 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2018/09/dependency-injection-lifetimes-in-razor-components/</guid>
      <description>&lt;p&gt;I’ve been playing with Server-side Blazor for a few days and I’ve been really impressed. I can see that this will be an immensely powerful technology and I hope to make it my main web platform going forward. But it’s model does change some things. Since you’re running the app on the server and just using SignalR to update the browser’s UI it changes the lifetime of Scoped objects in Asp.Net’s dependency injection.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;For a great analysis of DI scopes and lifetimes checkout Michal Dudak’s &lt;a href=&quot;https://blog.dudak.me/2018/dependency-lifetime-in-asp-net-core/&quot;&gt;post&lt;/a&gt;. I based my testing of scopes off of his simple scenario to see how the scopes differed in Server-side Blazor.&lt;/p&gt;

&lt;p&gt;First I created 3 simple services&lt;/p&gt;
&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SingletonService&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ScopedService&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TransientService&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then I registered those services with Asp.Net in startup.cs.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConfigureServices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IServiceCollection&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Since Blazor is running on the server, we can use an application service&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// to read the forecast data.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddSingleton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WeatherForecastService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddSingleton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SingletonService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddScoped&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ScopedService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddTransient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransientService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Then in the Configure method of startup.cs I requested an instance of the services and incremented the counters.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IBlazorApplicationBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;app&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SingletonService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ScopedService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransientService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;++;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then I added a new page that gets those services injected, increments the counters and displays the results.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@page &quot;/dilifetimes&quot;
@using Blazor.DI.Lifetimes.App.Services
@inject SingletonService singletonService
@inject ScopedService scopedService
@inject TransientService transientService

&amp;lt;table class=&quot;table&quot;&amp;gt;
    &amp;lt;thead&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;Lifetime Type&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;Count&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
    &amp;lt;/thead&amp;gt;
    &amp;lt;tbody&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;Singleton&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;@singletonService.Counter&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;Scoped&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;@scopedService.Counter&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
        &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;Transient&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;@transientService.Counter&amp;lt;/td&amp;gt;
        &amp;lt;/tr&amp;gt;
    &amp;lt;/tbody&amp;gt;
&amp;lt;/table&amp;gt;

@functions
{
    protected override void OnInit()
    {
        singletonService.Counter++;
        scopedService.Counter++;
        transientService.Counter++;

        base.OnInit();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you would expect the values of counters are:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Singleton: 2
Scoped: 2
Transient: 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And if you refresh, the values match what you see in a normal Asp.Net application&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Singleton: 4
Scoped: 2
Transient: 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But if you then navigate to a different page, then back to the DILifetimes page you get an odd result (literally);&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Singleton: 5
Scoped: 3
Transient: 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Transient works just as we’d expect. Every time we request an instance of that service we get a new instance. The instance that is incremented in the Configure method is different from the instance we get injected in the DILifetimes page.&lt;/p&gt;

&lt;p&gt;And when we refresh the page both Singleton and Scoped work as we’d expect. The singleton service is the same instance that has already been incremented twice when we loaded the page. It gets incremented again in Configure and again in DILifetimes. We get a new Scoped service in the Configure method and increment it a second time in DILifetimes.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;odd&lt;/em&gt; thing happens. We navigate away from the page and back, and we only increment Singleton and Scoped once, from the DILifetimes page. This is because we haven’t actually done a full web request when we navigated. We actually sent a message through SignalR to tell Server-side Blazor that we navigated. Blazor then did the navigation at the server and sent back the changes to the DOM which are then updated on the screen. The Configure method is never run.&lt;/p&gt;

&lt;p&gt;The message here is that Scoped services have a much longer lifetime in Server-side Blazor than they did in a traditional Asp.Net application. This can be good or bad, but it’s definitely good to be aware of.&lt;/p&gt;

&lt;p&gt;Full source available &lt;a href=&quot;&quot;&gt;https://github.com/hutchcodes/Blazor.DI.Lifetimes&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      
      <category>CodeProject</category>
      

      <title>Removing Items From a List</title>
      <link>https://hutchcodes.net/2018/08/removing-items-from-a-list/</link>
      <pubDate>Wed, 08 Aug 2018 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2018/08/removing-items-from-a-list/</guid>
      <description>&lt;p&gt;It’s not at all uncommon to need to iterate through a List to remove an item. And about half the time when I do so I get a “Collection was modified; enumeration operation may not execute.” exception the first time I run the code. Then I do something fancy like use a for loop to iterate through the list backward and remove the items from the list. Something like this:&lt;/p&gt;

&lt;!--more--&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;var foo = new List&amp;lt;string&amp;gt;();
foo.Add(&quot;Fizz&quot;);
foo.Add(&quot;Zebra&quot;);
foo.Add(&quot;Buzz&quot;);
foo.Add(&quot;Bazz&quot;);

for(var i=foo.Count()-1; i&amp;gt;=0; i--)
{
    if (foo[i].Equals(&quot;Zebra&quot;)){
        foo.Remove(foo[i]);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But somehow after an embarrassingly long time of doing that I’ve found a much simpler way, that I suspect everyone else has known about for a while, but just in case, here it is.&lt;/p&gt;

&lt;p&gt;Just take your list and cal &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ToList()&lt;/code&gt;, iterate through the new list and remove items from the original.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;foreach (var s in foo.ToList())
{
    if (s.Equals(&quot;Zebra&quot;)){
        foo.Remove(s);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Of course, this technique may have some memory or performance consequences. If I run into a case where that becomes a problem I can go back and optimize then. From here forward I’ll optimize for readability.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>Working Remote</title>
      <link>https://hutchcodes.net/2018/06/working-remote/</link>
      <pubDate>Thu, 07 Jun 2018 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2018/06/working-remote/</guid>
      <description>&lt;p&gt;One of my coworkers will be moving and switching to working remotely. He asked me to share my thoughts about working remote and it turns out I have a lot. Hopefully, they are worth sharing.&lt;/p&gt;

&lt;p&gt;I’ve been remote for 4 years now as an employee, and also worked remotely for about 7 years while as an independent consultant. The consulting was more solo work and less teamwork and was much more isolating, but it did help me form some boundaries around working from home.
At this point, I hope never to work in an office again. Here’s what I think are the keys to being happy working from home:&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;boundaries&quot;&gt;Boundaries&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Have a separate office space. This way you “go to work” by walking through a door, and you “come home” later. That’s not to say that you can’t “leave work” to do something at home for 5-10 minutes or a few hours (which I definitely do), just that you want to make sure you’re not mixing home and work because work will eventually start intruding on home life.&lt;/li&gt;
  &lt;li&gt;Keep “regular hours” and don’t worry about being unavailable when you’re not “at work”. I generally try to work from 7:30-3:30 or 4 (depending on school drop-offs) every day. There will still be some flexibility, but again the worry is that work will start to creep into home life if you don’t.&lt;/li&gt;
  &lt;li&gt;Consider adding some “commute time” to your day. When you work in an office, you have some time on your commute where you transition from home to work and back again. It can sometimes be difficult to make that same transition over just a dozen steps. I just need a few deep breaths, but I’ve heard of people walking around their house or around the block.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;communication&quot;&gt;Communication&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Ask yourself if you’re using the right communication tool. Don’t just rely on chat for all communication. Chat is a great communication tool, but you lose tone of voice and body language. If you’re in a long complicated chat, pick up the phone or consider a screen share or video chat.&lt;/li&gt;
  &lt;li&gt;Get comfortable with your video camera and encourage your coworkers to do the same. Try to have at least few video chats a week with your people from your team. Being able to see someone’s face rather than them just being a disembodied voice helps create connections.&lt;/li&gt;
  &lt;li&gt;Buy a decent USB camera and put it at the top of your main monitor. Then when a video chat starts put the video screen centered right below the camera. Otherwise, you’re sharing the side of your head or an up-the-nose shot (thanks for putting the camera at the bottom of the screen Dell). Remember that “eye contact” is made by looking at the camera, not at people’s eyes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;socializing&quot;&gt;Socializing&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Embrace on-site trips. A few days face to face with your co-workers goes a long way towards building the relationships needed to work effectively while remote.&lt;/li&gt;
  &lt;li&gt;Figure out how to get your socialization outside of work. You’re not going to have as many informal chats in the kitchen and you’re not going to go out to lunch with coworkers. You need to find a way to fill this gap or it will slowly wear you down.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;enjoy&quot;&gt;Enjoy&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Take full advantage of being remote. Take a walk or a nap mid-day, spend a bit of time with the kids when they get home from school, start cooking dinner in the middle of the afternoon. Take a conference call on the couch or out on the patio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the things that I feel have made working remotely work well for me. Others may find something here completely unimportant to them or may see something I completely missed, but it’s a place to start.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>Networking Online</title>
      <link>https://hutchcodes.net/2017/12/networking-online/</link>
      <pubDate>Wed, 27 Dec 2017 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2017/12/networking-online/</guid>
      <description>&lt;p&gt;Which online social network is the best when looking for a new job? If you had asked me 2 weeks ago I would have told you it was LinkedIn, but it turns out LinkedIn is a distant second.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;I have always maintained a bit of separation in my social networks.&lt;/p&gt;

&lt;p&gt;Facebook is for friends and family and a few people from the “&lt;em&gt;work world&lt;/em&gt;” that I trust won’t hold my occasional political rant against me. I almost never post anything work related there.&lt;/p&gt;

&lt;p&gt;LinkedIn is primarily just work-related folks. I post almost exclusively work related stuff here. Stuff I wouldn’t mind prospective employers seeing.&lt;/p&gt;

&lt;p&gt;Twitter is where I let the two worlds meet. I follow a broad range of people and I tweet personal, political, humorous and work stuff.&lt;/p&gt;

&lt;p&gt;My expectation has always been that if I needed to find a job, my LinkedIn network would be the most valuable. And when it recently became apparent that my current employer wasn’t going to work out long-term I posted the following on LinkedIn:&lt;/p&gt;

&lt;iframe width=&quot;504&quot; height=&quot;255&quot; src=&quot;https://www.linkedin.com/embed/feed/update/urn:li:activity:6344628286802456576&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;I also posted this similar message on Twitter:&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Anyone in need of of a Senior/Lead C# Developer with a load of experience in both Azure and AWS? I&amp;#39;m primarily looking for remote.  A retweet might get the right eyes on this.&lt;/p&gt;&amp;mdash; Jeremy Hutchinson (@hutchcodes) &lt;a href=&quot;https://twitter.com/hutchcodes/status/938831065086681089?ref_src=twsrc%5Etfw&quot;&gt;December 7, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;The response from LinkedIn was OK, I guess.  few people liked it, a few of my former coworkers suggested positions at their current companies, and a recruiter contacted me, but never responded after I said I was only willing to make the 2hr drive to the office a few times a month.&lt;/p&gt;

&lt;p&gt;The response on Twitter was overwhelming. A few people liked it, a bunch of people re-tweeted it, and total strangers contacted me about open positions that allowed remote. Most of those positions were at the companies they worked, but a few people pointed me to positions at companies they didn’t work for but knew were hiring remote developers.&lt;/p&gt;

&lt;p&gt;Twitter resulted in interviews with 3 companies that I’d be interested in working for.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;LinkedIn&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Twitter&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Followers&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;231&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;425&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Views&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;877&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;16.3k&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Likes&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;9&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;22&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Comments&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;6&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Shares&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;99&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Job Openings&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;3&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;15&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Interesting to Me&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Interviews&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;3&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;why-twitter&quot;&gt;Why Twitter?&lt;/h3&gt;

&lt;p&gt;I’m just guessing here, but I think it comes down to two things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Twitter is more active. I check LinkedIn just about once a week. And I rarely if ever scroll through the feed there.&lt;/li&gt;
  &lt;li&gt;Part of the Twitter experience is re-tweeting. Sharing posts is an option in LinkedIn, but it’s not used as often.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;takeaways&quot;&gt;Takeaways&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Build your Twitter network as best as you can. I’ve put work into providing some good content over the years to get to the number of followers I have.&lt;/li&gt;
  &lt;li&gt;Return the favor. When you see someone post that they are looking for work, retweet that. Same for companies looking to fill positions.&lt;/li&gt;
  &lt;li&gt;Nurture the rest of your network too. Twitter was far more effective for me, but I did get some leads from LinkedIn, those came from people that aren’t active on Twitter as far as I know. Those positions weren’t interesting this time, but you never know what’s going to come up.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      
      <category>Azure</category>
      
      <category>DevOps</category>
      
      
      <category>CodeProject</category>
      

      <title>Simple Deploy to Azure from Command Line</title>
      <link>https://hutchcodes.net/2017/09/azure-deploy-command-line/</link>
      <pubDate>Fri, 01 Sep 2017 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2017/09/azure-deploy-command-line/</guid>
      <description>&lt;p&gt;I’m currently working on moving our product from AWS to Azure and as part of the planning for that move, one of the problems I needed to solve was deployment. Our current deployments are handled by an automated build on Bamboo, but Bamboo doesn’t have a “Deploy to Azure” task. I needed to do the deploy from the command line (CMD or Powershell), and I wanted to avoid including publish profiles in the projects.&lt;/p&gt;

&lt;p&gt;The first part, running from the command line was easy to find through with a Google search. You can just tell MSBuild to publish to Azure&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;msbuild MyWeb\MyWeb.csproj /t:TransformWebConfig;Publish /p:TargetProfile=ProdMyWebApp /p:Configuration=AzDev

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But the catch is that you can’t do it without a publish profile as part of your project or at least I wasn’t able to make it work.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Instead of trying to do it with just MSBuild I used MSBuild to build a deployment package.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;MSBuild MyWeb\MyWeb.csproj 
	/target:TransformWebConfig;Package 
	/p:Configuration=Prod;PackageLocation=&quot;Deployment\Prod.zip&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That transforms the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;web.config&lt;/code&gt; and creates a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.cmd&lt;/code&gt; executable that we can call and tell to publish to Azure or IIS is WebDeploy is enabled.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Deployment\Prod.Deploy.cmd 
	/M:https://mywebapp.scm.azurewebsites.net:443/MSDeploy.axd 
	/a:basic 
	/U:$mywebapp 
	/P:[userPWD from your publish profile] 
	/Y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You do still need to download the publish profile from the Azure portal and open it in a text editor to pull out the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;publishUrl&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;userName&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;userPWD&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Y&lt;/code&gt; means that it will go through with the deploy. You can also use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/T&lt;/code&gt; to do a ‘What If’.&lt;/p&gt;

&lt;p&gt;With these commands, I was able to automatically deploy our web app to Azure during our build process. And since I didn’t need to store the publish profile in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.csproj&lt;/code&gt; file, I don’t need to worry about someone deploying something from their machine without checking the code into source control.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Azure</category>
      
      <category>AWS</category>
      
      <category>Sql</category>
      
      
      <category>CodeProject</category>
      

      <title>Azure SQL vs AWS RDS Performance and Cost</title>
      <link>https://hutchcodes.net/2017/08/azure-sql-vs-aws-rds-performance-and-cost/</link>
      <pubDate>Fri, 11 Aug 2017 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2017/08/azure-sql-vs-aws-rds-performance-and-cost/</guid>
      <description>&lt;p&gt;I’ve been doing a series of blog posts comparing Azure and AWS services that I’ve used in production. This post is before production usage, but I’ve been researching and experimenting in preparation for proposing moving our databases to Azure and wanted to share my results so far.&lt;/p&gt;

&lt;p&gt;Before I could propose this move I needed to understand the cost differences. To do that I needed to know which level of Azure SQL was equivalent to our m1.medium instance at AWS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An AzureSQL Standard Tier S3 database performs is about 7% faster than a SQL Server SE 2008 R2 database running on an m1.medium instance of AWS RDS. Price comparison are hard because AWS RDS has a sea of options to choose from, but if you meet the requirements for SQL Server Web licensing then pricing is similar.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;performance&quot;&gt;Performance&lt;/h3&gt;
&lt;p&gt;Performance in Azure is measured in DTUs (Database Transaction Units), a 100DTU database is twice as powerful as a 50DTU database and ten times as powerful as a 10DTU database.&lt;/p&gt;

&lt;p&gt;At AWS you are purchasing an EC2 instance with SQL Server installed. They provide some guidance about how various instance will perform via their ECU ratings (EC2 Compute Unit), but it’s pretty coarse. An m1.Large is rated at 2ECU, and an m1.medium is 1ECU, but an m1.small is also rated 1ECU and is ~half as fast as the m1.medium, so it’s not a great comparison.&lt;/p&gt;

&lt;p&gt;Since AWS and Azure don’t use the same measure for performance I did some benchmarking with &lt;a href=&quot;https://github.com/SQLServerIO/TPCCBench&quot;&gt;TPCCBench&lt;/a&gt;. This tool runs an industry standard workload against a database. I ran it without the “thinking time” that the official TPC-C benchmarks would normally run with, but it with the same settings on both clouds.&lt;/p&gt;

&lt;p&gt;On Azure I benchmarked a ton of different performance levels. All the way from Basic(5DTUs $5/month) up to a the Premium P15(400DTUs $16,000/month). As advertised, the performance at different levels went up in lockstep with the DTUs. A 100DTUs is ~10 times as fast as 10DTUs. When I got up to the Premium tiers, the load test utility couldn’t max out the instances. So at 250DTUs I was only able to use ~85% of the DTUs and with the P15 4000DTU instance I was only able to ~7% of the DTUs.&lt;/p&gt;

&lt;p&gt;On AWS there you can choose from Express, Standard, Web and Enterprise licensing for SQL Server. These all have different costs, but should perform the same for the loads we’re looking at (look for someone to correct me in the comments). You can also choose between versions from 2008 R2 up to 2016, but once you get to 2016 you start to be limited in which EC2 instances you can choose.&lt;/p&gt;

&lt;p&gt;I only benchmarked m1.small and m1.medium instance running SQL Server SE 2008 R2 on AWS because that’s all I had standing up at the time, and though I wouldn’t mind looking at the performance of some other instance sizes and SQL versions, I didn’t have time/money to go through the setup and config.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Cloud&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Tier/Pricing Level&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Orders/min&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;AWS&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;m1.small&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2875&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;AWS&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;m1.medium&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;5690&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Azure&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Standard S3 (100 DTUs)&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;6103&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Azure&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Standard S2 (50 DTUs)&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;3051&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Our production database runs on SQL Server SE 2008 R2 on an m1.medium instance, that load can easily be handled by an AzureSQL Standard Tier database with 100DTUs (either an S3 or as part of an Elastic Database Pool). That answers my first question.&lt;/p&gt;

&lt;h3 id=&quot;costs&quot;&gt;Costs&lt;/h3&gt;
&lt;p&gt;Both licensing and instance size play into pricing on AWS. We are running SQL Server SE which costs $575/month for an m1.medium. If we ran SQL Server Web instead that would cost $195/month. If we used SQL Server Web on an  m3.medium we would it would cost $150/month.&lt;/p&gt;

&lt;p&gt;There are two pricing models in Azure. One is a Single Database pricing, the other is Elastic Database. With Elastic Database pricing the DTUs can be shared between multiple databases. This is similar to having multiple databases on one instance in AWS.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Cloud&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Tier/Pricing Level&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;$/month&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;Notes&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;AWS&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;m1.small SQL Server Express&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;67&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Our dev/test environment&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;AWS&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;m1.medium SQL Server SE&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;575&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Our prod environment&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;AWS&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;m4.medium SQL Server Web&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;196&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;What we should be running our prod environment on&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;AWS&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;m4.large SQL Server Web&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;229&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;What we’d need to run our prod environment to use SQL Server 2016&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Azure&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Standard S2 (50 DTUs)&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;75&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Azure&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Standard S3 (100 DTUs)&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;150&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Azure&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Elastic (50 DTUs)&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;112&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Azure&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;Elastic (100 DTUs)&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;225&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt; &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;As you can see the cost of AWS RDS varies greatly based on the licensing. If you’re running a publicly available website with a single database the cost is the same at both AWS and Azure. If your DB is for an internal application Azure is much cheaper. If you have multiple databases AWS might be cheaper, would be cheaper than the same power in Azure Elastic DB, but if you can split those database into two S2s or 10 S0s the cost is the same.&lt;/p&gt;

&lt;p&gt;I’m not sure how we’ll manage our database in Azure. We may be able to run our dev\test database on the Basic tier (5DTU $5/month) or the Standard S0 tier (10DTU $15/month), or maybe it would make more sense to put them all in a 50DTU elastic pool ($112/month). For production we’ll probably start out with a Standard S3 for our main DB and a Standard S0 or S1 for our auditing DB. Then depending on the loads scale them back or possibly put them in an Elastic Pool together.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;The people I spoke with who dodged the question and told me I needed to do my own testing were right. In the end there are too many variables on the AWS side to make a comparison. If you’re considering moving from one cloud to the other you’re going to have to get a benchmark tool and benchmark where you are coming from and where you think you might end up. I’m thinking of a follow up post to cover the actual steps I took in benchmarking.&lt;/p&gt;

&lt;h3 id=&quot;this-aint-science&quot;&gt;This ain’t science&lt;/h3&gt;
&lt;p&gt;I can see that I’m not comparing apples and oranges on a few levels here. AzureSQL isn’t running SQL Server SE 2008R2, it’s running something closer to but not exactly SQL Server 2016. Maybe upgrading RDS to SQL Server 2014 would have provided better results. I also compared SQL Server Express on an m1.small to SQL Server SE on the m1.medium again not ideal.&lt;/p&gt;

&lt;p&gt;In the end I just compared what I was currently using in AWS to see where it would fit in Azure.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Azure</category>
      
      <category>AWS</category>
      
      
      <category>CodeProject</category>
      

      <title>Azure Blobs vs AWS S3</title>
      <link>https://hutchcodes.net/2017/03/azure-blobs-vs-aws-s3/</link>
      <pubDate>Tue, 28 Mar 2017 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2017/03/azure-blobs-vs-aws-s3/</guid>
      <description>&lt;p&gt;Part of my ongoing series comparing AWS and Azure for the services where I’ve used both in production. In this post I’ll be looking at the differences between Azure Blob Storage and Amazon S3 for storing and retrieving files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Azure’s logical structure allows you to manage multiple &lt;em&gt;containers&lt;/em&gt; at the same time.&lt;/li&gt;
  &lt;li&gt;AWS allows default documents and with that you can host a static site for pennies per month in S3.&lt;/li&gt;
  &lt;li&gt;Azure Blob can integrate Azure Search to allow searching the content of some documents&lt;/li&gt;
&lt;/ul&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;management&quot;&gt;Management&lt;/h3&gt;
&lt;p&gt;In Azure Blob you have a &lt;em&gt;Storage Account&lt;/em&gt;, within that storage account you can store Blobs, Files (think shared drive), Tables and Queues.  Within the Blobs you have logical groupings called &lt;em&gt;Containers&lt;/em&gt;.  &lt;em&gt;Containers&lt;/em&gt; are roughly equivalent to AWS S3 &lt;em&gt;Buckets&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In both AWS and Azure you can exposes these &lt;em&gt;Containers&lt;/em&gt;\&lt;em&gt;Buckets&lt;/em&gt; publicly or require a key to access them. The urls look like this:&lt;/p&gt;

&lt;p&gt;s3.amazonaws.com/[&lt;em&gt;BucketName&lt;/em&gt;]/[&lt;em&gt;FileName&lt;/em&gt;]&lt;/p&gt;

&lt;p&gt;[&lt;em&gt;StorageAccount&lt;/em&gt;].blob.core.windows.net/[&lt;em&gt;Container&lt;/em&gt;]/[&lt;em&gt;FileName&lt;/em&gt;]&lt;/p&gt;

&lt;p&gt;Notice that &lt;em&gt;StorageAccount&lt;/em&gt; becomes the sub-domain while all &lt;em&gt;buckets&lt;/em&gt; are under the same S3 domain. This means that bucket names must be unique in AWS, while in Azure it is the Storage Account Name that must be unique.&lt;/p&gt;

&lt;p&gt;This means with Azure you can create dev/test/prod Storage Accounts and keep the Container names consistent. So if you have multiple buckets that is less you need to manage when switching environments.&lt;/p&gt;

&lt;p&gt;AWS S3 manages everything at the &lt;em&gt;Bucket&lt;/em&gt; level. So if you have 3 buckets that all have the same access rules, you need to manage those rules 3 times. In Azure Blob you could put all those &lt;em&gt;Containers&lt;/em&gt; in the same &lt;em&gt;Storage Account&lt;/em&gt;, and manage them once. Multiply those 3 &lt;em&gt;Buckets&lt;/em&gt; by 3 environments (dev/test/prod) and you’re starting to save quite a bit of time managing permissions with Azure Blob.&lt;/p&gt;

&lt;h3 id=&quot;uploadingdownloading-documents&quot;&gt;Uploading/Downloading Documents&lt;/h3&gt;

&lt;p&gt;In previous comparisons I’ve gotten into the differences in working with the services through the SDKs. In this case they are both very similar, and straight forward. Azure does require an extra step because you need to get a reference to the &lt;em&gt;Storage Account&lt;/em&gt; before getting the reference to the &lt;em&gt;Container&lt;/em&gt;, but it’s a single line of code.&lt;/p&gt;

&lt;h3 id=&quot;static-website-hosting&quot;&gt;Static Website Hosting&lt;/h3&gt;

&lt;p&gt;AWS S3 lets you host a static website in an S3 Bucket. To do this you set a default document, and if a request is made to the root of the bucket or to a “folder” it will try to return the default document.&lt;/p&gt;

&lt;p&gt;This is something that Azure does not have. It was request 3 years ago and they now have it on their backlog. You can vote it up or check the status &lt;a href=&quot;https://feedback.azure.com/forums/217298-storage/suggestions/6417741-static-website-hosting-in-azure-blob-storage&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;document-searching&quot;&gt;Document Searching&lt;/h3&gt;

&lt;p&gt;Azure Blob Storage can be integrated with Azure Search allowing you to search the contents of stored documents including PDF, Word, PowerPoint and Excel documents. Doing this in AWS required a 3rd party services that cost $36k for the first year. This feature was the driving force in our move from AWS to Azure.&lt;/p&gt;

&lt;p&gt;The documentation for &lt;a href=&quot;/2016/10/aws-cloudsearch-to-azure-search/&quot;&gt;Searching Azure Blob Storage&lt;/a&gt; is execellent.&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;AWS S3’s main advantage is that you can host a static site very cheaply, but that advantage looks like it is going to have a short shelf life.&lt;/p&gt;

&lt;p&gt;If hosting a static site isn’t your goal Azure Blob Storage’s streamlining of management and it’s ability to search the contents of it’s documents are big advantages.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Azure</category>
      
      <category>Jekyll</category>
      
      
      <category>CodeProject</category>
      

      <title>Azure Search for Jekyll</title>
      <link>https://hutchcodes.net/2016/12/azure-search-for-jekyll/</link>
      <pubDate>Mon, 05 Dec 2016 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2016/12/azure-search-for-jekyll/</guid>
      <description>&lt;p&gt;I added Azure Search to my static site built with Jekyll through the use of Azure Functions. Best part, &lt;strong&gt;it’s free&lt;/strong&gt;*.&lt;/p&gt;

&lt;p&gt;This example is for &lt;a href=&quot;http://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;, it will work with any static site. The only thing Jekyll specific is the JSON representation of the site, and any static site generator should be able to build that file. I’ve used (&lt;a href=&quot;https://github.com/Code52/pretzel&quot;&gt;Pretzel&lt;/a&gt; and &lt;a href=&quot;https://bolt80.com/piecrust/&quot;&gt;PieCrust&lt;/a&gt; as well, they are both nice tools, but hosting on GitHub pages has it’s advantages).&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;creating-a-json-of-all-posts-and-pages&quot;&gt;Creating a JSON of All Posts and Pages&lt;/h3&gt;

&lt;p&gt;The first thing I did was create a page in Jekyll to produce a JSON representation of all the Posts and Pages from my site. I added a new piece of meta-data to the front matter to indicate whether each page should be indexed for search. This way I can be sure that pages like my RSS feed, SiteMap and my search.json don’t get indexed.&lt;/p&gt;

&lt;div class=&quot;language-liquid highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
---
layout: nil
includeInSearch: false
---
&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;includeInSearch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;true&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;
[
	&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;site.posts&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;
	{
	&quot;type&quot;: &quot;post&quot;,
	&quot;title&quot;: &quot;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&quot;,
	&quot;publishDate&quot;: &lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;jsonify&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;,
	&quot;categories&quot;: [&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p.categories&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;&quot;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&quot;&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;unless&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;forloop.last&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;,&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;endunless&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;endfor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;],
	&quot;tags&quot;: [&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p.tags&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;&quot;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&quot;&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;unless&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;forloop.last&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;,&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;endunless&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;endfor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;],
	&quot;url&quot;: &quot;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&quot;,
	&quot;content&quot;:&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;strip_html&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json_escape&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;jsonify&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;,
	&quot;excerpt&quot;: &lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;excerpt&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json_escape&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;jsonify&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;\n&apos;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;
	}&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;unless&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;forloop.last&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;,&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;endunless&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;endfor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;

	&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;,
	{
	&quot;type&quot;: &quot;page&quot;,
	&quot;title&quot;: &quot;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&quot;,
	&quot;categories&quot;: [&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p.categories&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;&quot;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&quot;&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;unless&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;forloop.last&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;,&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;endunless&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;endfor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;],	
	&quot;tags&quot;: [&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p.tags&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;&quot;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&quot;&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;unless&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;forloop.last&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;,&lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;endunless&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;endfor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;],
	&quot;url&quot;: &quot;&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&quot;,
	&quot;content&quot;:&lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;strip_html&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json_escape&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;jsonify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;,
	&quot;excerpt&quot;: &lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;excerpt&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;rstrip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json_escape&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;jsonify&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;,
	&quot;description&quot;: &lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;json_escape&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;jsonify&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;
    }
    &lt;span class=&quot;p&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;endfor&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%}&lt;/span&gt;
]

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s simple enough. I had actually created that over a year ago when I first started to think about using Azure Search. I abandoned that attempt partly because it was going to be a manual process and I was worried I might forget the step to populate the index.&lt;/p&gt;

&lt;p&gt;You can see the resulting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search.json&lt;/code&gt; &lt;a href=&quot;/search.json&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;function-triggered-by-a-github-webhook&quot;&gt;Function Triggered by a GitHub Webhook&lt;/h3&gt;

&lt;p&gt;The next thing I needed to do was get that into Azure Search in some automated fasion. For this I used an Azure Function with GitHub Webhook for a trigger. I’m going to assume you’ll be able to figure out how to setup a Function App and create the GitHub Webhook function from the Templates available.&lt;/p&gt;

&lt;p&gt;The new function should look something like this:
&lt;img src=&quot;/img/2016/GitHubWebHookFunction.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Note that the &lt;em&gt;GitHub Secret&lt;/em&gt; that is listed is action the &lt;em&gt;_master&lt;/em&gt; admin key, and what you really need is the &lt;em&gt;default&lt;/em&gt; function key (&lt;a href=&quot;http://stackoverflow.com/questions/40615743/invalid-webhook-signature&quot;&gt;more info&lt;/a&gt;). Also, that Function App will be gone before I post this, so don’t worry about me sharing that key :)&lt;/p&gt;

&lt;h3 id=&quot;setting-up-the-github-webhook&quot;&gt;Setting Up the GitHub Webhook&lt;/h3&gt;

&lt;p&gt;Next step is to go over to GitHub and create the WebHook:
&lt;img src=&quot;/img/2016/CreateGitHubWebhook.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then scroll down a bit more and choose &lt;strong&gt;Let me select individual events&lt;/strong&gt;
That opens up of the list of events that will trigger the WebHook. Uncheck &lt;strong&gt;Push&lt;/strong&gt; and check &lt;strong&gt;Page Build&lt;/strong&gt;. That will trigger the WebHook to index the blog whenever the Jekyll site gets built. For debug purposes I also put a check in Watch. That way when I wanted to test everything I could just UnStar/Star my repo.&lt;/p&gt;

&lt;p&gt;At this point we can test everything to ensure that the Webhook is working properly and our function is running. Once you confirm that is working you it’s time use the function to populate our index.&lt;/p&gt;

&lt;h3 id=&quot;loading-the-json-into-azure-search&quot;&gt;Loading the JSON into Azure Search&lt;/h3&gt;

&lt;p&gt;First thing we need to do is bring in a reference to the Azure Search SDK. To do this you need to create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.json&lt;/code&gt; file in the BlogIndexer folder.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;frameworks&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;net46&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;dependencies&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Microsoft.Azure.Search&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1.1.3&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After that it’s just a matter of creating and populating the index.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Newtonsoft.Json&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.Net&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Newtonsoft.Json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Microsoft.Azure.Search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Microsoft.Azure.Search.Models&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpResponseMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpRequestMessage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TraceWriter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;WebClient&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;WebClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Encoding&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UTF8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;DownloadString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://hutchcodes.net/search.json&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchTopics&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;JsonConvert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DeserializeObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indexClient&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RecreateIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IndexBatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Upload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchTopics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;indexClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Documents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;    
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SearchIndexClient&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RecreateIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;queryApiKey&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[Your API Key]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchServiceName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[You Search Service Name]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchIndexName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[Your Index Name]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchServiceClient&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SearchServiceClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchServiceName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SearchCredentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;queryApiKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchServiceClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Indexes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchIndexName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;searchServiceClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Indexes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchIndexName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;definition&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchIndexName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Fields&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsFilterable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsKey&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Url&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsRetrievable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsFilterable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsRetrievable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsFacetable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsSearchable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsRetrievable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Analyzer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AnalyzerName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EnMicrosoft&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Categories&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsFilterable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsRetrievable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsFacetable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Tags&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsFilterable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsRetrievable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsFacetable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Content&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsSearchable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Analyzer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AnalyzerName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EnMicrosoft&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Excerpt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsSearchable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsRetrievable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Analyzer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AnalyzerName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EnMicrosoft&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;PublishDate&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsRetrievable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;searchServiceClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Indexes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;definition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indexClient&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchServiceClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Indexes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchIndexName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indexClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Page&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetHashCode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PublishDate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Content&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Excerpt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Categories&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tags&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Starting from the bottom, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Page&lt;/code&gt; class represents the JSON objects that are output in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search.json&lt;/code&gt;, and the properties need to match 1 for 1 with the fields in the Index.&lt;/p&gt;

&lt;p&gt;Each time we update the index we delete and recreate the index. We  do this because if we delete a post or a page it gets removed from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search.json&lt;/code&gt;, but there is no way to trigger it’s removal from the Index. This could produce a result to be shown to the user that results in a 404.&lt;/p&gt;

&lt;p&gt;Lastly (or firstly), the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Run&lt;/code&gt; method gets the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search.json&lt;/code&gt; from the blog, deserializes it into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List&amp;lt;Page&amp;gt;&lt;/code&gt; and uploads that list to the Search Index. Last I looked there was a limit of 1000 items per batch. I handle that potential problem in my GitHub example, but left that out here for simplicity.&lt;/p&gt;

&lt;h3 id=&quot;search-function&quot;&gt;Search Function&lt;/h3&gt;

&lt;p&gt;Finally, we’re able to start searching. First thing to do is create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Search&lt;/code&gt; function. To do this create an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Http Trigger&lt;/code&gt; function and change the Authorization level from Function to Anonymous. By default the Url for this function will be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/api/search&lt;/code&gt;. We’ll need to include a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.json&lt;/code&gt; with the same reference to the Azure Search SDK as we had in the BlogIndexer function. We’re also going to have a bit of duplicate code for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Page&lt;/code&gt; class and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IndexClient&lt;/code&gt; (there’s ways to &lt;a href=&quot;2016/11/sharing-code-between-azure-functions/&quot;&gt;share code&lt;/a&gt;, but again trying to keep it simple for this post).&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Newtonsoft.Json&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Microsoft.Azure.Search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Microsoft.Azure.Search.Models&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Newtonsoft.Json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpResponseMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpRequestMessage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TraceWriter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// parse query parameter&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;search&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetQueryNameValuePairs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FirstOrDefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Compare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;search&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetQueryNameValuePairs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FirstOrDefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Compare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cat&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;        

    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 
 
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpStatusCode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;facet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;queryApiKey&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[Your API Key]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchServiceName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[You Search Service Name]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchIndexName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;[Your Index Name]&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indexClient&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SearchIndexClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchServiceName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchIndexName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SearchCredentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;queryApiKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;facetFilter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;facet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;facetFilter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;Categories/any(c: c eq &apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;facet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchParams&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SearchParameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;searchParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IncludeTotalResultCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;searchParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;QueryType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QueryType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Full&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;searchParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SearchMode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SearchMode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;searchParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Top&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;searchParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Url&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Excerpt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Categories&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;PublishDate&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;searchParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Filter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;facetFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;searchParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Facets&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Categories&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchResults&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;indexClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Documents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pages&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchResults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Page&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetHashCode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PublishDate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Content&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Excerpt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Categories&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tags&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once that’s in place you can go to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[Your function app URL]/api/search?search=foo&amp;amp;facet=bar&lt;/code&gt; and you should see some results. Don’t be shocked if it comes back as Xml, when you make the request from javascript on your page you can specify that you want JSON.&lt;/p&gt;

&lt;p&gt;Before going on to setup search on the client side you need to update the CORS settings for the Function App. To do that through the portal you can click on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Function app settings&lt;/code&gt; click on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Configure CORS&lt;/code&gt; then add your blog’s domain and localhost:4000 to the list.&lt;/p&gt;

&lt;h3 id=&quot;searching&quot;&gt;Searching&lt;/h3&gt;

&lt;p&gt;To do the search from my Jekyll based site I created a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search.md&lt;/code&gt; page that looked for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat&lt;/code&gt; query string and made a call to the API. Anywhere I started a search (clicking on a category or hitting enter in the search box), I forwarded the user to this search page with the appropriate query string.&lt;/p&gt;

&lt;p&gt;On that page, I make a request to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Search&lt;/code&gt; function which returns a JSON of the results. I then loop through the results to build up some HTML as a string and stick it in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;innerHtml&lt;/code&gt; of the appropriate element on the page.&lt;/p&gt;

&lt;p&gt;My search page looks like this&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;---
title: Searching...
layout: search
includeInSearch: false
permalink: /search/
published: true
---

&lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getParameterByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getParameterByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getParameterByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;searchText&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;getSearchResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The JavaScript to actually perform the search and display the results.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchUrl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;[URL of the Azure Function that performs the search]&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchKeyPress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;keyCode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchText&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;searchText&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getParameterByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getParameterByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;catFilter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tagFilter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;searchText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;searchText&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;encodeURIComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;searchText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;catFilter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;amp;cat=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tagFilter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;amp;tag=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;href&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/search?search=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchText&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;catFilter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tagFilter&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getSearchResults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;searchText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;nx&quot;&gt;appInsights&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;trackEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Search&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tag&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;searchText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchText&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;searchUrl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;?search=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchText&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;amp;cat=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;amp;tag=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;XMLHttpRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;onreadystatechange&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchCallback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;readyState&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Search failed! &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;responseText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
            &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchResults&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;xhr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;responseText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;searchResults&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchResults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;displaySearchResults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;searchResults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;displaySearchResults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;searchResults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;

	&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;	
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementsByTagName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;section&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchResults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    	&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;searchResults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;categories&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Categories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            	&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Categories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;categories&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;a href=&apos;/search/?search&amp;amp;cat=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos;&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/a&amp;gt;&amp;amp;nbsp;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;categories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;categories&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; in &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;categories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;article class=&apos;post&apos;&amp;gt; &amp;lt;header class=&apos;jumbotron&apos;&amp;gt; &amp;lt;h2 class=&apos;postTitle&apos;&amp;gt;&amp;lt;a href=&apos;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos;&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/h2&amp;gt; &amp;lt;abbr class=&apos;postDate&apos; title=&apos;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PublishDate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos;&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PublishDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toLocaleDateString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;en-us&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;numeric&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;month&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;numeric&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/abbr&amp;gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;categories&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/header&amp;gt; &amp;lt;div class=&apos;articleBody&apos;&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Excerpt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;a href=&apos;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos;&amp;gt;Continue Reading&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/article&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;article class=&apos;post&apos;&amp;gt; &amp;lt;header class=&apos;jumbotron&apos;&amp;gt; &amp;lt;h2 class=&apos;postTitle&apos;&amp;gt;&amp;lt;a href=&apos;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos;&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/a&amp;gt;&amp;lt;/h2&amp;gt;&amp;lt;/header&amp;gt; &amp;lt;div class=&apos;articleBody&apos;&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Excerpt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;lt;/div&amp;gt;&amp;lt;div&amp;gt;&amp;lt;a href=&apos;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos;&amp;gt;Continue Reading&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/article&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;section&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;innerHTML&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;searchMessage&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;innerHTML&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;No results found.&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getParameterByName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;[\[\]]&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;$&amp;amp;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;regex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;RegExp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[?&amp;amp;]&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;(=([^&amp;amp;#]*)|&amp;amp;|#|$)&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;regex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;decodeURIComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\+&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;its-not-quite-free&quot;&gt;*It’s not quite free&lt;/h3&gt;

&lt;p&gt;I’m using the free tier of Azure Search, and Azure Functions allows 1 million function calls and 400k Gbs of execution for free. In theory, there is no charge unless it gets a lot of use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But&lt;/strong&gt; it’s still not quite free. I have been charged $.03. Looking at this, it turns out that some of that is from a couple of days when my function wasn’t compiling but was getting called by one of my Application Insights Web Tests. That caused the function to be reloaded from the Function App’s Storage Account racking up $.02.&lt;/p&gt;

&lt;p&gt;The other $.01 has come from the App Service behind my Function App, but I can’t see where. There is no single day where there is a $.01 charge, so I’m guessing it’s the cummulation of fractions of a cent per day.&lt;/p&gt;

&lt;p&gt;I’d like this to be 100% free, but I’m not going to spend my time finding out why I’m being charge $.03/month.&lt;/p&gt;

&lt;h3 id=&quot;addition-resources&quot;&gt;Addition resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/hutchcodes/Jekyll-Search-With-Azure-Functions&quot;&gt;Source code&lt;/a&gt; for the Azure Functions that are handling search on this site, included is a Jekyll folder with most of what you’ll need to get it running on your site. The only things missing are the search box and the category displays that would like to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/search?cat=[category name]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you get stuck, I’d love to help. Feel free to contact me through any method available on my &lt;a href=&quot;/about&quot;&gt;about&lt;/a&gt; page.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Azure</category>
      
      
      <category>CodeProject</category>
      

      <title>Sharing Code Between Azure Functions</title>
      <link>https://hutchcodes.net/2016/11/sharing-code-between-azure-functions/</link>
      <pubDate>Mon, 07 Nov 2016 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2016/11/sharing-code-between-azure-functions/</guid>
      <description>&lt;p&gt;Once I had my &lt;a href=&quot;/2016/10/azure-function-search-indexer/&quot;&gt;Azure Search Indexer Failure Notifier&lt;/a&gt; working as an Azure Function I needed to make it run on all of our Indexers. I had 3 choices for sharing common code:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Copy/Paste&lt;/li&gt;
  &lt;li&gt;Have one big function that checked every indexer&lt;/li&gt;
  &lt;li&gt;Find some way to share code between functions&lt;/li&gt;
&lt;/ol&gt;

&lt;!--more--&gt;

&lt;p&gt;Option #1 was right out. I’ve seen that turn ugly in the past and have no desire to create such a mess for future me or anyone else.&lt;/p&gt;

&lt;p&gt;Option #2 is a pretty good option, and would have been the simplest path to done. I went with option #3 mostly to learn how to share code. I know that knowledge will come in handy some day.&lt;/p&gt;

&lt;p&gt;Looking at the Samples of the &lt;a href=&quot;https://github.com/Azure/azure-webjobs-sdk-script&quot;&gt;azure-webjobs-sdk-script&lt;/a&gt; repository and noticed the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Shared&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;First thing I moved was my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetEnvironmentVariable&lt;/code&gt; method. I created a file called Settings.csx in the Shared folder and created a public static class to hold the method.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Settings&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settingName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Environment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settingName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EnvironmentVariableTarget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then at the top of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run.csx&lt;/code&gt; just put &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#load &quot;../shared/settings.csx&quot;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I can then replace my calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetEnvironmentVariable(&quot;settingName&quot;)&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Settings.GetSetting(&quot;settingName&quot;)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That worked great, so I continued to try to move the meat of the index watcher code. I created a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SearchIndexerWatcher&lt;/code&gt; folder under in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Shared&lt;/code&gt; folder and created an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IndexerWatcher.csx&lt;/code&gt; there and moved all of the code for checking the index status to that file.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;../Settings.csx&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;SendGrid.Helpers.Mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Microsoft.Azure.Search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IndexerWatcher&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Mail&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetFailureNotification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchIndexer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TraceWriter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apiKey&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetSetting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;SearchApiKey&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SearchServiceClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SearchCredentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apiKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Indexers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetStatus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchIndexer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ExecutionHistory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EndTime&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UtcNow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddMinutes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ErrorMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Environment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NewLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Mail&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;Content&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Content&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;text/plain&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice that this code references the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Settings.csx&lt;/code&gt; from the Shared folder.&lt;/p&gt;

&lt;p&gt;Now my main function is just setting specifying the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SearchService&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SearchIndexer&lt;/code&gt;, then calling this function.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;SendGrid&quot;&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;..\Shared\SearchIndexerWatcher\IndexerWatcher.csx&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;SendGrid.Helpers.Mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;IndexWatcher_Prod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SearchIndexer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TraceWriter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Mail&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchService&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;mySearchService&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchIndexer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;myBlobIndexer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IndexerWatcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetFailureNotification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchIndexer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;    
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So this mostly works as expected. The Run.csx has the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#r&lt;/code&gt; to pull in the SendGrid reference and the #load to pull in IndexerWatcher.csx. IndexerWatcher.csx then pulls in Settings.csx.&lt;/p&gt;

&lt;p&gt;Except when I created a new function for another one of our indexers it failed to compile because I forgot the project.json. And that’s where things get tricky. That project.json pulls the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Microsoft.Azure.Search&lt;/code&gt; reference down from Nuget. We have no references to Microsoft.Azure.Search in the run.csx, so logically I’d like to put that in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Shared/SearchIndexerWatcher&lt;/code&gt; folder. But it doesn’t work from there, it has to be in the root of the function’s folder.&lt;/p&gt;

&lt;p&gt;That’s not ideal because when I reuse the IndexWatch.csx later, I may not realize what dependencies need to be added to the project.json. I decided to leave the project.json in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Shared/SearchIndexerWatcher&lt;/code&gt; folder as a reference for what would need to be added to the function’s project.json.&lt;/p&gt;

&lt;p&gt;Things I’m thinking about going forward:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Add a readme.md to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Shared/SearchIndexerWatcher&lt;/code&gt; folder to document how to use that file and what needs to be added to the project.json. Then remove the project.json.&lt;/li&gt;
  &lt;li&gt;Split the IndexerWatcher from the SendGrid Mail generation so that code can be shared more broadly.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      
      <category>Azure</category>
      
      

      <title>Using Azure Functions to Detect Search Indexer Errors</title>
      <link>https://hutchcodes.net/2016/10/azure-function-search-indexer/</link>
      <pubDate>Fri, 28 Oct 2016 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2016/10/azure-function-search-indexer/</guid>
      <description>&lt;p&gt;Azure Functions are a light weight way to deploy code. It’s part of the “serverless” craze. While I admit I was suspect of serverless,  after just this tiny foray, I can definitely see it’s usefulness.&lt;/p&gt;

&lt;p&gt;So here’s my real world example of something simple you can do with Azure Functions. It’s just the tip of the iceberg, but it’s better than a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hello Word&lt;/code&gt;.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;The problem I was trying to solve was that Azure Search Indexers don’t alert you when they fail to index a document. Depending on how you have your indexer configured it either ignores the document or it keeps retrying and gets stuck. In my case it got stuck. Luckily it was in our Test environment.&lt;/p&gt;

&lt;p&gt;The goal of this was to create a watcher to periodically check the status of the indexer and send me an email if there were any errors.&lt;/p&gt;

&lt;h3 id=&quot;creating-the-function-app&quot;&gt;Creating the Function App&lt;/h3&gt;
&lt;p&gt;The first step is of course to create the Function App through the Azure Portal. The setup is similar to setting up an Azure Web App right down to the [yoursite].azurewebsites.net. The Function App also creates a Storage Account that is used to store the code files.&lt;/p&gt;

&lt;h3 id=&quot;creating-the-function&quot;&gt;Creating the Function&lt;/h3&gt;
&lt;p&gt;Whether you create your function through the portal or build it locally and deploy through continuous integration the file layout is the same, but not immediately obvious for some things.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[root]
| - host.json
| / IndexerWatcher 
| | - run.csx 
| | - function.json
| | - project.json (I had to add this file manually)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;host.json&lt;/strong&gt; allows you to control some settings at the Function App level (could contain multiple functions). By default it is an empty JSON. I’d prefer a file populated with the defaults, but you can see what settings are available and their defaults &lt;a href=&quot;https://github.com/Azure/azure-webjobs-sdk-script/wiki/host.json&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;function.json&lt;/strong&gt; contains settings for the function include bindings which you can use to add inputs and outputs to the function. In this case we have a binding the timer trigger that runs the job at the top of every hour, and SendGrid send emails.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;bindings&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;myTimer&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;timerTrigger&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;direction&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;schedule&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0 0 * * * *&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;sendGrid&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;default@SendToEmailAddress&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;send@FromEmailAddress&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Default Subject&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;direction&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;disabled&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;project.json&lt;/strong&gt; allows you to reference Nuget packages. In this case I’m referencing the Azure Search SDK so that I can get the status of the indexer. We could also do this through the Rest API, but I’m a big fan of strong typing and intellisense…&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;frameworks&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;net46&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;
      &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;dependencies&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Microsoft.Azure.Search&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1.1.3&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;run.csx&lt;/strong&gt; is the main script file. In this case it is C#, but it can be F#, Javascript, Powershell, Python etc. In C# it contains a function with the signature &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public static void Run()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We have additional parameters for the TimerInfo, TraceWriter and a SendGridMessage. We don’t need to configure any bindings for TraceWriter, it is always available to be passed into your function. The other two are configured in the function.json.&lt;/p&gt;

&lt;p&gt;Because we’re using SendGrid and SendGrid is not automatically referenced, we need to tell the host to add the reference. We do that with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#r &quot;SendGridMail&quot;&lt;/code&gt; at the top. There’s a handful of external assemblies you can this way &lt;a href=&quot;https://azure.microsoft.com/en-us/documentation/articles/functions-reference-csharp/#referencing-external-assemblies&quot;&gt;reference&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After that we just call the Search Service, request the Indexer Status and generate an email if needed. If I don’t need to send an email I just pass a null SendGridMessage back. That throws an error in the console, but I didn’t see any other way to not send the email. If there is a better way please let me know.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;SendGridMail&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;SendGrid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Microsoft.Azure.Search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TimerInfo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myTimer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TraceWriter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Mail&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apiKey&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;SearchApiKey&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//log.Info(apiKey);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchService&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;mySearchService&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;searchIndexer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;myBlobIndexer&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SearchServiceClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SearchCredentials&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apiKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Indexers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetStatus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchIndexer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ExecutionHistory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EndTime&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UtcNow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddMinutes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ErrorMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ErrorMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Environment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NewLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Content&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;text/plain&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Environment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EnvironmentVariableTarget&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;app-settings&quot;&gt;App Settings&lt;/h3&gt;

&lt;p&gt;From the Function App blade in the portal under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Function App Settings&lt;/code&gt; there is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Configure App Settings&lt;/code&gt; button. Click that and you can set your app settings just like you would for a Web App.&lt;/p&gt;

&lt;p&gt;There are two app settings that you’ll need to configure to make this work.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SendGridApiKey - This is the SendGrid API Key and the setting name has to match or you get an error.&lt;/li&gt;
  &lt;li&gt;SearchApiKey - This is API Key for your Azure Search service. You can name this setting anything you like, but make sure you update the call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetEnvironmentVariable&lt;/code&gt; in the run.csx.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;todo&quot;&gt;TODO&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;As it is I’ll need to create a seperate function for each indexer I have (Prod, Test, Dev) which would mean duplicate code, which we all know is going to bite me in the ass. There is a way to share code between functions, but I haven’t explored it yet.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It wasn’t until after I had my first working Azure Function that I found the &lt;a href=&quot;https://www.npmjs.com/package/azure-functions-cli&quot;&gt;Azure-Functions-CLI&lt;/a&gt;. This should allow you to test the functions locally before deploying them to Azure.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;gotchas&quot;&gt;Gotchas&lt;/h3&gt;
&lt;p&gt;I started developing this in a console app, and I needed to install the SendGrid v6.3.4 package to get it working there. Neither the 7.* nor the 8.* packages had the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SendGridMessage&lt;/code&gt; class that was in the function’s method signature.&lt;/p&gt;

&lt;h3 id=&quot;update-11302016&quot;&gt;Update (11/30/2016)&lt;/h3&gt;
&lt;p&gt;With the general release of Azure Functions SendGrid was upgraded. I assume it was to the latest, but it was far enough that it broke my function until I changed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SendGridMessage&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mail&lt;/code&gt;. This also required a change to how the mail was built. I’ve updated the code to reflect that.&lt;/p&gt;

&lt;p&gt;Also, the application setting AzureWebJobsSendGridApiKey was changed to SendGridApiKey.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>AWS</category>
      
      <category>Azure</category>
      
      

      <title>AWS Cloudsearch vs Azure Search</title>
      <link>https://hutchcodes.net/2016/10/aws-cloudsearch-to-azure-search/</link>
      <pubDate>Wed, 12 Oct 2016 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2016/10/aws-cloudsearch-to-azure-search/</guid>
      <description>&lt;p&gt;We recently started moving some of our bits from AWS to Azure. One of the first bits to go was the Search. Below is my comparison of the two.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Azure has the ability to automatically index data stored in SQL, DocumentDB, and Azure Table Storage as well as documents stored in Azure Blob Storage. Azure’s API is strongly typed and much more expressive than AWS’s.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;document-searching&quot;&gt;Document Searching&lt;/h3&gt;
&lt;p&gt;This is a huge gap that AWS Cloudsearch currently has and is the whole reason we started moving to Azure. We needed to be able to search the contents of PDFs and Word Documents. In order to do this with AWS, we had 2 choices:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Buy a 3rd party library to allow us to read the contents out of the documents.&lt;/li&gt;
  &lt;li&gt;Pay for a service to watch our S3 storage and update a CloudSearch index for us.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first option was prohibitively expensive both in time and money (not to mention added complexity). When I read the cost of the second option I almost fell out of my chair (ask me about it if you want a giggle).&lt;/p&gt;

&lt;p&gt;Azure’s document search was still in preview, but I took a spike to see if was feasible and had a working prototype in less than a day.&lt;/p&gt;

&lt;p&gt;So, document searching is real, decently well documented and was fairly painless to implement. It’s also totally automatic through Indexers.&lt;/p&gt;

&lt;h3 id=&quot;indexers&quot;&gt;Indexers&lt;/h3&gt;
&lt;p&gt;This is another feature only available in Azure. Indexers watch a datasource for new or changed data and update the search index as needed. It currently supports Azure SQL, SQL Server on Azure VMs, DocumentDB, Azure Blob Storage and Azure Table Storage.&lt;/p&gt;

&lt;p&gt;Because our database still lives over on AWS we haven’t used this for our other search content, but if we did we could delete quite a bit of code that manages keeping the search index in sync with the source data.&lt;/p&gt;

&lt;p&gt;The only downside is that (at least for Blob Storage) when you delete a document you need to mark it as deleted, wait for the indexer to run, then delete the document (or not, storage is cheap $.06/GB/month).&lt;/p&gt;

&lt;h3 id=&quot;creating-the-index&quot;&gt;Creating the index&lt;/h3&gt;
&lt;p&gt;We did not script our index creation in AWS. We just created them through the AWS website. Really with our indexes, it’s hardly worth the effort to script them.&lt;/p&gt;

&lt;p&gt;With Azure I started off the same way, but once I realized the only way to setup an Indexer for a Blob Datasource was through the REST API, I scripted everything. It took a little longer to get everything running the first time, but when in the process of development I realized I made a mistake in the config it was nice to just be able to delete it all, make one change and have all my environments updated.&lt;/p&gt;

&lt;h3 id=&quot;populating-the-index&quot;&gt;Populating the index&lt;/h3&gt;
&lt;p&gt;With AWS Cloudsearch you need to create a JSON representation of the object you’re adding to the index. You can either upload that directly through their REST API or you can use their .Net API.&lt;/p&gt;

&lt;p&gt;With Azure you can upload a strongly typed object to be indexed. Or you could build an indexer to handle all that for you.&lt;/p&gt;

&lt;h3 id=&quot;searching&quot;&gt;Searching&lt;/h3&gt;
&lt;p&gt;This is where I really noticed a difference (We used the REST API for AWS so it might be a better experience with the .Net API). With AWS we needed to assemble a Lucene query in a URL query string. That means we’re doing a lot of string concatenation and managing when parentheses close.&lt;/p&gt;

&lt;p&gt;With Azure the .Net API has properties for Skip, Top, Select,  OrderBy and others that we were including in URL for AWS. That means instead of having to mange this:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;amp;start=0&amp;amp;size=50&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We just had to manage this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;searchParams.Skip = (int)search.StartRecord-1;
searchParams.Top = (int)search.EndRecord;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;But the biggest boon was the seperation of Search and Filters. With AWS, everything was search. With Azure you have the concept of Filters. All of our filter fields are controlled by us, and they are just concatenated together using Azure’s ‘simple query syntax’ and added to the searchParams object. The search string the user enters is converted to a Lucene query (I open sourced my converter &lt;a href=&quot;https://github.com/hutchcodes/SearchParser&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This little bit of seperation has made a big difference and making the code easier to reason about.&lt;/p&gt;

&lt;h3 id=&quot;results&quot;&gt;Results&lt;/h3&gt;
&lt;p&gt;Again AWS is not strongly typed and just sends back a JSON document. We’re treating it as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dynamic&lt;/code&gt; and mapping it to something useful. You could also build a class to match the JSON and deserialize it.&lt;/p&gt;

&lt;p&gt;With Azure the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Search&lt;/code&gt; method is generic. Each search result contains a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Document&lt;/code&gt; property that is the type you specified. Simple use the same type as the object that was uploaded and Bobs your uncle.&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;We really had no choice but to move to Azure because of its ability to index office documents. But the addition of automatic indexers and the strongly typed and well thought out API make me glad we made the move. The move from AWS Cloudsearch to Azure Search took a couple of days work (excluding moving document storage from S3 to Azure Blob).&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>AWS</category>
      
      <category>Azure</category>
      
      

      <title>Moving from AWS to Azure</title>
      <link>https://hutchcodes.net/2016/10/moving-from-aws-to-azure/</link>
      <pubDate>Mon, 03 Oct 2016 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2016/10/moving-from-aws-to-azure/</guid>
      <description>&lt;p&gt;We recently started moving from AWS to Azure. It’s something I had been pushing for, but the reason we finally started was because of the ability to index and search documents stored in Azure Blob storage, so the first things to move have been document storage and search. We expect to move our website, API and SQL database next, but we haven’t scheduled anything.&lt;/p&gt;

&lt;p&gt;Below are some of the differences and lessons I found/learned in the process. I’ll also try to post some specifics about each service we move for comparison sake.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;documentation&quot;&gt;Documentation&lt;/h3&gt;

&lt;p&gt;The first thing I noticed when moving from AWS to Azure is the documentation gap. Finding documentation and examples for AWS seems exceedingly difficult. Both at &lt;a href=&quot;http://docs.aws.amazon.com&quot;&gt;docs.aws.amazon.com&lt;/a&gt; as well as on &lt;a href=&quot;https://stackoverflow.com&quot;&gt;StackOverflow&lt;/a&gt; and through Google searches.&lt;/p&gt;

&lt;p&gt;In contrast both Google and StackOverflow both bring up the examples I need when searching for questions about Azure, but even better is the Azure documentation. When you create a new resource in Azure the first blade that opens in the portal has QuickStart icon &lt;img src=&quot;/img/2016/QuickStart.png&quot; alt=&quot;QuickStart Icon&quot; /&gt; that will take you to the documentation including example code for how to create and interact with the services.&lt;/p&gt;

&lt;h3 id=&quot;api&quot;&gt;API&lt;/h3&gt;
&lt;p&gt;The next thing I noticed is that with AWS almost everything we’re doing is going through their REST API, with almost nothing happening through their SDK. I suspect that at least some of this has to do with how the original developer implemented it in our product. But some of the blame goes to AWS because the examples of how to interact with their services are by default through their REST API, and it takes some digging to find any documentation on how to do the same through their .NET SDK.&lt;/p&gt;

&lt;p&gt;Also, the AWS .NET SDK is really just a wrapper around their REST API to the point that when uploading a document to Cloudsearch you upload an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UploadDocumentRequest&lt;/code&gt; object which has 3 properties:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;- ContentType (JSON or XML)
- Documents (System.IO.Stream of JSON or HTML representation of documents)
- FilePath (Path to a JSON or HTML representation of documents)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So they basically have an SDK that takes some strings.&lt;/p&gt;

&lt;p&gt;In contrast, Azure’s SDK allows you to upload an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IndexAction&amp;lt;T&amp;gt;&lt;/code&gt;. You create a strongly typed object, pass it to the SDK and it maps itself to your search index.&lt;/p&gt;

&lt;h3 id=&quot;organization&quot;&gt;Organization&lt;/h3&gt;
&lt;p&gt;Both Azure and AWS have something called Resource Groups, but they aren’t really the same thing. In Azure Resource Groups are required when creating a service. I created Dev, Test and Prod Resource Groups in Azure to keep our services organized. Each service can only be in one Resource Group, so even though we have all our environments piggy backing on our Production search instance (separate indexes), that Search service can only live in one Resource Group. I put it in Prod so no one does anything stupid.&lt;/p&gt;

&lt;p&gt;In AWS Resource Groups are optional. We haven’t been using them, but they look pretty neat. It’s all based on Tags, so one resource could be in multiple groups. You can also require multiple tags when selecting the items in a resource group. Again, we’re not using this feature but I assume that if I add a new service with a tag that is already part of a group that service will just appear in that group.&lt;/p&gt;

&lt;p&gt;The one thing Azure Resource Groups has been invaluable for is experimenting. Want to play around or build a demo? Create a resource group for that, when you’re done, delete the Resource Group and all of your services are automatically deleted for you.&lt;/p&gt;

&lt;p&gt;Azure also has the concept of Tags, but I couldn’t find a way to view the intersection of 2 tags.&lt;/p&gt;

&lt;h3 id=&quot;correct-me-if-im-wrong&quot;&gt;Correct Me If I’m Wrong&lt;/h3&gt;
&lt;p&gt;Did I get something wrong here? Did something change? Let me know and I’ll get this updated.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>AWS</category>
      
      

      <title>Connecting AWS VPC to Classic RDS</title>
      <link>https://hutchcodes.net/2016/09/aws-vpc-to-classic-rds/</link>
      <pubDate>Wed, 28 Sep 2016 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2016/09/aws-vpc-to-classic-rds/</guid>
      <description>&lt;p&gt;A while back we did an audit of what we were spending through Amazon Web Services to see if there was any way we could reduce our spending without having a negative impact on our users.&lt;/p&gt;

&lt;p&gt;One of the big things we found we would be able to do was upgrade some of our production EC2 instances from for AWS’s older m1.medium to an m3.medium, and our dev/test instances could downgrade from m1.small to t2.small.&lt;/p&gt;

&lt;p&gt;The catch was we needed to create those instances in AWS’s Virtual Private Network (VPC), and there is no documentation for how to connect that VPC to things running “Classic Mode”. Our database was running on a RDS instance that was in Classic Mode and we didn’t want to incur the downtime to move that to a VPC.&lt;/p&gt;

&lt;p&gt;Here’s how we eventually were able to get our VPC instance to talk to our classic mode RDS.&lt;/p&gt;

&lt;!--more--&gt;

&lt;ol&gt;
  &lt;li&gt;Create the VPC with a CIDR of 10.0.0.0/16. This also creates a single Route Table name that one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Through NAT&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Create second Route Table and call it &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Through IGW&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Public&lt;/code&gt; Subnet with a CIDR of 10.0.0.0/24&lt;/li&gt;
  &lt;li&gt;From the Route Table tab of the Subnet click edit and select the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Through IGW&lt;/code&gt; Route Table from the dropdown&lt;/li&gt;
  &lt;li&gt;Create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Private&lt;/code&gt; Subnet with a CIDR of 10.0.1.0/24&lt;/li&gt;
  &lt;li&gt;From the Route Table tab of the Subnet click edit and select the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Through NAT&lt;/code&gt; Route Table from the dropdown&lt;/li&gt;
  &lt;li&gt;From the Subnet Association tab of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Through IGW&lt;/code&gt; Route Table click edit and select the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Public&lt;/code&gt; Subnet.&lt;/li&gt;
  &lt;li&gt;From the Subnet Association tab of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Through NAT&lt;/code&gt; Route Table click edit and select the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Private&lt;/code&gt; Subnet.&lt;/li&gt;
  &lt;li&gt;Create an Internet Gateway and make a note of it’s ID&lt;/li&gt;
  &lt;li&gt;Select the Internet Gateway and click Attach to VPC to attach to your VPC&lt;/li&gt;
  &lt;li&gt;Edit the Routes of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Through IGW&lt;/code&gt; Route Table to add a route with 0.0.0.0/0 as the destination and the ID of the Internet Gateway as the target&lt;/li&gt;
  &lt;li&gt;Create a NAT Gateway, select the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Private&lt;/code&gt; Subnet and create a new EIP&lt;/li&gt;
  &lt;li&gt;Edit the Routes of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Through NAT&lt;/code&gt; Route Table to add a route with 0.0.0.0/0 as the destination and the ID of the NAT Gateway as the target&lt;/li&gt;
  &lt;li&gt;Add the Elastic IP associated with the NAT Gateway to the allowed IP addresses in the Securit Groups section of the RDS dashboard&lt;/li&gt;
  &lt;li&gt;Cross your fingers&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Connecting their two different styles of networks is something that I think should be built in to AWS’s tools. Not only is it not worked in, but when I  contacted support about this they said it was impossible. I would have taken their word for it if we hadn’t already had this running to allow a webserver in one datacenter to talk to RDS in another.&lt;/p&gt;

&lt;p&gt;If this doesn’t work, I’d be happy to try to help you figure it out and more importantly I’d like to update the steps so others don’t strugle.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      <category>IIS</category>
      
      

      <title>Debugging IIS App Pool Crashes</title>
      <link>https://hutchcodes.net/2016/05/debugging-iis-app-pool-crashes/</link>
      <pubDate>Fri, 27 May 2016 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2016/05/debugging-iis-app-pool-crashes/</guid>
      <description>&lt;p&gt;We had a problem where a stack overflow error was crashing our App Pool in IIS. Other than that we didn’t have any information about what was cause was, what code was causing the crash or even what request.&lt;/p&gt;

&lt;p&gt;This was my first time taking a crash dump and using it to debug and I was surprised at how painless it was. I’ll definitely be using this technique again.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;enable-crash-dumps-in-windows-error-reporting&quot;&gt;Enable Crash Dumps in Windows Error Reporting&lt;/h3&gt;
&lt;p&gt;The first thing you need to do is change some registry settings to tell Windows Error Reporting to save a crash dump.&lt;/p&gt;

&lt;p&gt;Open RegEdit and Create this key&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Windows Error Reporting]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then set the following values:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;DumpFolder&lt;/td&gt;
      &lt;td&gt;Expandable String&lt;/td&gt;
      &lt;td&gt;c:\temp&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;DumpCount&lt;/td&gt;
      &lt;td&gt;DWORD&lt;/td&gt;
      &lt;td&gt;10&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;DumpType&lt;/td&gt;
      &lt;td&gt;DWORD&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;I found the DumpType setting to be the critical. The default is 1, which is Minidump, but that didn’t seem to be enough information to get me to the offending code. For reference my minidump was 48MB, my full dump was 800MB&lt;/p&gt;

&lt;h3 id=&quot;crash&quot;&gt;Crash&lt;/h3&gt;
&lt;p&gt;At this point you can just sit back and wait for the next crash or you can cause it if you know how. When a file shows up, copy it to your dev machine and rename the key to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LocalDumps_NO&lt;/code&gt; to prevent further dumps from accumulating while you work.&lt;/p&gt;

&lt;h3 id=&quot;debug&quot;&gt;Debug&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;Open your solution in Visual Studio and checkout the same code that is running on the server. Build with your production configuration.&lt;/li&gt;
  &lt;li&gt;Drag the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.dmp&lt;/code&gt; file into Visual Studio to open it.&lt;/li&gt;
  &lt;li&gt;Click &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Set symbol paths&lt;/code&gt; and add your project’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/bin&lt;/code&gt; folder&lt;/li&gt;
  &lt;li&gt;Click &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Debug with Managed Only&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this point you should be brought to the line that threw the exception. You can’t step though the code at this point, but you can see the values of your variables, and you can see how you got to that point with the call stack window (Debug-&amp;gt;Windows-&amp;gt;Call Stack or ctrl+D,C).&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Angular</category>
      
      <category>T4</category>
      
      

      <title>T4 Angular Template Cache</title>
      <link>https://hutchcodes.net/2015/07/t4-angular-template-cache/</link>
      <pubDate>Fri, 31 Jul 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/07/t4-angular-template-cache/</guid>
      <description>&lt;p&gt;There’s a few ways to handle you’re angular directives and they all suck for different reasons.&lt;/p&gt;

&lt;h3 id=&quot;store-them-inline-in-your-directives&quot;&gt;Store them inline in your directives&lt;/h3&gt;
&lt;p&gt;The advantage to this method is you don’t have to make a separate web request, and it’s the simplest way to approach templates. This is where I started putting my templates, and I continue to put some templates here if they are very small and more important, simple.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;The downside is that your HTML is stored as strings, so you lose any syntax highlighting and checking your IDE might provide. It can also result in some duplication if by chance you have two directives that would have the same HTML, but different logic, but that’s probably an edge case.&lt;/p&gt;

&lt;h3 id=&quot;store-each-in-its-own-html-file&quot;&gt;Store each in it’s own HTML file&lt;/h3&gt;
&lt;p&gt;This basically the exact opposite side of the coin from storing them inline.  You have to make a separate request, but you pick up the syntax highlighting and checking from the IDE.&lt;/p&gt;

&lt;p&gt;This is what I used for larger templates when they become too big or complex to keep inline.&lt;/p&gt;

&lt;h3 id=&quot;add-them-to-the-template-cache&quot;&gt;Add them to the template cache&lt;/h3&gt;
&lt;p&gt;This option can avoid the extra HTTP request assuming you either put all your templates in one file, or bundle all the template JS files. But again, your templates are strings, so you lose all IDE support.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;$templateCache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;templates/search&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
    &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;lt;input type=&quot;text&quot; ng-model=&quot;searchText&quot; ng-enter=&quot;search()&quot;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;best-of-both-worlds-through-the-magic-of-t4&quot;&gt;Best of Both Worlds Through the Magic of T4&lt;/h2&gt;
&lt;p&gt;With a fairly simple T4 script we can store our templates in their own separate HTML files the way we want to work while developing. Then on build we can process those files to generate a single script file with all of the templates in it the way we want to deploy.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#@&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;=&quot;&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;System.Diagnostics&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; #&amp;gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#@&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;=&quot;&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;System.Linq&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; #&amp;gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#@&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;=&quot;&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;System.Collections&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; #&amp;gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#@&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;=&quot;&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;System.Collections.Generic&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; #&amp;gt; 
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;appModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;templateCache&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;templateCache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectPath&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetCurrentDirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;projectPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;EndsWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;\bin&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;projectPath&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Substring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;projectPath&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ResolvePath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;projectPath&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Substring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;templateDirectory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DirectoryInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;projectPath&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;@&quot;templates&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;files&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;templateDirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetFiles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;*.html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;	
	&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		
		&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;OpenText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
		&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EndOfStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ReadLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;@&quot;\&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;templateCache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;templates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;a-couple-of-things-worth-noting-in-this-script&quot;&gt;A Couple of Things Worth Noting in This Script&lt;/h3&gt;
&lt;ol&gt;
  &lt;li&gt;The line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (projectPath.EndsWith(@&quot;\bin&quot;))&lt;/code&gt; is checking where we are running. If the path doesn’t ends in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\bin&lt;/code&gt;, we know we’re building from inside Visual Studio and can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Host.ResolvePath(&quot;&quot;)&lt;/code&gt; to get the directory the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.tt&lt;/code&gt; file is running and walk back from there &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;substring&lt;/code&gt; isn’t ideal, but the traditional &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;..&lt;/code&gt; didn’t work so…).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If we’re running from outside Visual Studio we get the bin directory and just need to back up from there.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;After that we just get the list of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*.html&lt;/code&gt; files, read then into strings and add those strings to the cache.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Notice that I include the whole file name as my template name. This means that if my directive already had &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;templateURL: &apos;templates\search.html&apos;&lt;/code&gt; it will find that template in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;templateCache&lt;/code&gt; and not make a request to the server.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;running-the-template-on-build&quot;&gt;Running the Template on Build&lt;/h3&gt;

&lt;p&gt;I added a Pre-Build Event to do the transform. I did this so that the template.js that is checked into source control matches what is in production. And to make sure any changes made to the HTML files are automatcially included.&lt;/p&gt;

&lt;div class=&quot;language-common_lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;&quot;%PROGRAMFILES(x86)%\Common Files\microsoft shared\TextTemplating\11.0\TextTransform.exe&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ProjectDir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Scripts\App\Templates.tt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;for-easier-debugging&quot;&gt;For Easier Debugging&lt;/h3&gt;
&lt;p&gt;Lastly, for easier debugging I added a compiler directive in my bundle config  around the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;templates.js&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;n&quot;&gt;bundles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ScriptBundle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;~/bundles/app.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;~/Scripts/app/app.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#if !DEBUG
&lt;/span&gt;        &lt;span class=&quot;s&quot;&gt;&quot;~/Scripts/app/Templates.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This means that when I’m working locally in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DEBUG&lt;/code&gt; mode I can load the template straight from the HTML and not have to worry about re-running the T4 Transform after every change. That keeps my loop short during development and keeps the number of requests down during production.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>XPath</category>
      
      

      <title>XPath to Select Node Based on Child Node&apos;s Attribute</title>
      <link>https://hutchcodes.net/2015/06/xpath-select-node-based-on-child-nodes-attribute/</link>
      <pubDate>Thu, 25 Jun 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/06/xpath-select-node-based-on-child-nodes-attribute/</guid>
      <description>&lt;p&gt;Thankfully I don’t use XPath frequently, but every time I do I end up having to google something.  Today was no different except that my googling turned up nothing on my problem.&lt;/p&gt;

&lt;p&gt;I needed to select a node based on the attribute of one of it’s child nodes. Simple right?
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;In this case I’m trying to find all the topics where a certain image is used.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Topics&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;Topic&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Title&amp;gt;&amp;lt;/Title&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Description&amp;gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Content&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;Image&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;123&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;ContentPart&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;ContentPart&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Content&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Topic&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;Topic&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Title&amp;gt;&amp;lt;/Title&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Description&amp;gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Content&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;ContentPart&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Content&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Topic&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Topics&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s simple as long as you know how deep to look for the attribute&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/Topics/Topic[Content/Image[@Id=&apos;123&apos;]]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But in my situation those images could be anywhere in the topic. I couldn’t specify the path to take through the tree to search for the image element.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Topics&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;Topic&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Title&amp;gt;&amp;lt;/Title&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Description&amp;gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Content&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;Image&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;123&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;ContentPart&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;ContentPart&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Content&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Topic&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;Topic&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Title&amp;gt;&amp;lt;/Title&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Description&amp;gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;Content&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;ContentPart&amp;gt;&lt;/span&gt;
				&lt;span class=&quot;nt&quot;&gt;&amp;lt;Image&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;123&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
			&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ContentPart&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Content&amp;gt;&lt;/span&gt;
	&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Topic&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Topics&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The answer was elusive for longer than I’d care to admit. I’d either get all the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Topic&lt;/code&gt; elements or none. Here’s one of the ways I got all the elements.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/Topics/Topic[//Image[@Id=&apos;123&apos;]]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In hindsight I can see the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[//Image[@Id=&apos;123&apos;]]&lt;/code&gt; was going to search the whole document for Image elements with Id of 123.&lt;/p&gt;

&lt;p&gt;There are a seemingly infinite number of ways to get no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Topic&lt;/code&gt; elements returned. Including many ways that are just invalid XPath.&lt;/p&gt;

&lt;p&gt;What finally did work was the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.&lt;/code&gt; operator. It selects the current element&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/Topics/Topic[.//Image[@Id=&apos;123&apos;]]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the end it was simple, but I couldn’t google up an answer, so we get a blog post. Hopefully this will help the next person struggling with the same issue, and hopefully I’ll never write another XPath query after this project ;)&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>Prematurely Optimizing My Blog</title>
      <link>https://hutchcodes.net/2015/06/prematurely-optimizing-my-blog/</link>
      <pubDate>Thu, 04 Jun 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/06/prematurely-optimizing-my-blog/</guid>
      <description>&lt;p&gt;This blog isn’t what you’d call ‘high traffic’. My big problem wasn’t load, it was keeping the site ‘warm’, so each user didn’t have to wait for WordPress to spin up and before serving the first page. Of course once I started looking at performance I went fully down the rabbit hole &lt;!--more--&gt; and came out on a different &lt;a href=&quot;/2015/06/blog-engines-compared/&quot;&gt;blogging platform&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have an MSDN subscription and some unused Azure credits, so the first thing I did was move my WordPress site to Azure.  It was as simple as spinning up an WordPress site on Azure through the wizard, exporting from my old site and importing at the new one. I used the azure credits to host it in an ‘Always On’, Small, Basic, Web Application paid for by Azure credits. I quickly learned that the free MySql DB provided needed to be upgraded to a paid level costing $10/month.&lt;/p&gt;

&lt;p&gt;I actually perceived this to be slower, especially in the admin screens which frequently took 7+ seconds to load. The main site was a little faster.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/WordPressPreOpt.png&quot; alt=&quot;Wordpress non-optimized performance on Azure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I wasn’t worried about the slow admin screens (though it was driving me crazy), but I did want to improve speed for users.&lt;/p&gt;

&lt;p&gt;I added a &lt;a href=&quot;https://wordpress.org/plugins/w3-total-cache/&quot;&gt;W3 Total Cache&lt;/a&gt; which was supposed to be able to handle bundling, minifying CSS and JavaScript, moving script tags to the end of the page, and caching the site to static pages. It failed both on bundlig, minifying and moving the tags (I also tried other caching plugins which failed similarly.&lt;/p&gt;

&lt;p&gt;I added &lt;a href=&quot;https://wordpress.org/plugins/autoptimize/&quot;&gt;Autoptimize&lt;/a&gt; which bundled and minified the CSS and JavaScript. And I added &lt;a href=&quot;https://wordpress.org/plugins/speed-booster-pack/&quot;&gt;Speed Booster Pack&lt;/a&gt; which moved my script files to the end of the page.&lt;/p&gt;

&lt;p&gt;At the end of all this I had decent performance.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/WordPressOptCold.png&quot; alt=&quot;Wordpress non-optimized performance on Azure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I was still getting things flagged by Google’s &lt;a href=&quot;https://developers.google.com/speed/pagespeed/insights/&quot;&gt;PageSpeed&lt;/a&gt; as well as in &lt;a href=&quot;http://yslow.org/&quot;&gt;YSlow&lt;/a&gt;.  There were things that I just couldn’t easily control that I really wanted to fix. And it started to bother me that I had increased my hosting costs when I was expecting them to decrease.&lt;/p&gt;

&lt;p&gt;I looked at a bunch of &lt;a href=&quot;/2015/06/blog-engines-compared/&quot;&gt;blogging platforms&lt;/a&gt; and ended up settling on &lt;a href=&quot;http://bolt80.com/piecrust&quot;&gt;PieCrust CMS&lt;/a&gt; which is a static site generator.&lt;/p&gt;

&lt;p&gt;A static site generator creates you’re site in plain HTML on your machine and you upload that to your webhost. You can serve it out of any web host, or some interesting alternatives like Amazon S3, DropBox, or the one I eventually settled on &lt;a href=&quot;https://pages.github.com/&quot;&gt;GitHub Pages&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once I went to a static site, performance went through the roof. First I tried hosting it in Azure in a a Small, Basic, Web Application.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/AzureWeb.png&quot; alt=&quot;Static Site n Azure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is where I started to get a little obsessive. I tried putting a CDN in front of my static site in Azure.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/AzureCDN.png&quot; alt=&quot;Static Site on Azure with CDN&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then just for giggles I tried GitHub Pages. And was shocked to see it was faster still&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/GitHub.png&quot; alt=&quot;Static Site on GitHub&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Your website is &lt;strong&gt;faster than 99%&lt;/strong&gt; of all tested websites&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I should have stopped there, but I felt there was still a lot I could do. I removed all the fancy web fonts. I returned excerpts instead of full posts. I removed FontAwesome and instead hunted down jpegs for the few social icons. I stripped out any unused CSS.&lt;/p&gt;

&lt;p&gt;I brought the total pageweight down 297k to 39k and reduced the number of requests by 18. In the end my results were almost everything I hoped for.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/Final.png&quot; alt=&quot;Static Site optimized on GitHub&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You’ll notice my score is still &lt;strong&gt;88/100&lt;/strong&gt;. This is because GitHub pages doesn’t let you set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expires headers&lt;/code&gt;, so assets you should only have to request once (my picture, social icons, css and js) get requested every time and every the response is &lt;a href=&quot;http://httpcats.herokuapp.com/304&quot;&gt;304&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’d love to see that fixed, but I think it’s time to leave well enough alone, besides I have this to hang my hat on&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Your website is &lt;strong&gt;faster than 100%&lt;/strong&gt; of all tested websites&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;The look and feel of my new website is essentially the same as it was when on WordPress. It’s based on the &lt;a href=&quot;https://wordpress.org/themes/author/&quot;&gt;Author&lt;/a&gt; theme.&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>Blog Engines Compared</title>
      <link>https://hutchcodes.net/2015/06/blog-engines-compared/</link>
      <pubDate>Mon, 01 Jun 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/06/blog-engines-compared/</guid>
      <description>&lt;p&gt;I loved WordPress in so many ways. There were hundreds of styles to choose from, a huge library of plugins, analytics, and performance problems. I’m not saying that WordPress can’t be configured to give adequate (or even excellent) performance, but I either didn’t have the knowledge or the money to do so. 
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tl;dr:&lt;/strong&gt; I went with PieCrust CMS which is a static site generator. It’s easy and it is fast as hell. The downside is no built in search, but we always have Google.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I’m a .Net Developer and currently have some credits laying around in Azure so I was really looking to take advantage of that and so that probably limited my options.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, I went looking for other blog engines, and here’s what I found.&lt;/p&gt;

&lt;p&gt;I’m just going to list the blog engines I tried and why I didn’t use them. This is roughly the order that I tried them and I might have landed somewhere else if I had gone in a different order.&lt;/p&gt;

&lt;h3 id=&quot;wordpress&quot;&gt;&lt;a href=&quot;https://wordpress.org/&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;This is where I started. WordPress is ubiquitous for a reason. It’s really easy to get running and easy to operate. There’s an enormous number of plugins and themes to choose from, and it can really run just about anything. I started on WordPress years ago exactly because it was easy.&lt;/p&gt;

&lt;p&gt;The problem for me was performance. I was seeing page load times between 4-5 seconds, sometimes longer. I did put a lot of effort into optimizing WordPress. And I had some great success. I cut my page weight and number of requests by 75%, and my page load time dropped by more than half down to a hair less than 2 seconds. In the process I got really focused on performance and more importantly realized WordPress was much more than I needed.&lt;/p&gt;

&lt;h3 id=&quot;umbraco&quot;&gt;&lt;a href=&quot;https://umbraco.com/&quot; target=&quot;_blank&quot;&gt;Umbraco&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;I actually played a key role in choosing this as the CMS system for a previous employer. It replace Dot Net Nuke, and the developers really liked it (I actually didn’t develop with it). One of the things I was trying to get away from was the cost of a database. If a few years down the road I no longer have Azure credits, this option gets really expensive. I didn’t even stand up an instance, but it might be worth investigating yourself.&lt;/p&gt;

&lt;h3 id=&quot;dasblog&quot;&gt;&lt;a href=&quot;https://dasblog.codeplex.com/&quot; target=&quot;_blank&quot;&gt;DasBlog&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;If it’s good enough for Scott Hanselman it’s good enough for me right? Nope. I found the admin UI fairly impenetrable, or maybe I just didn’t want to try to penetrate it. It just looked old and clunky. And it is old. A quick look at CodePlex shows it was last updated in 2012. I didn’t give it a fair shake, I just moved on.&lt;/p&gt;

&lt;h3 id=&quot;ghost&quot;&gt;&lt;a href=&quot;https://ghost.org/&quot; target=&quot;_blank&quot;&gt;Ghost&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;This felt like a nice fast blog. And this is where I started to really start measuring. But I couldn’t see how to setup a theme or modify the CSS. Did I need to FTP in, and make changes there? Again I just kind of moved on without giving it a fair shake. But I will say this, it was fast.&lt;/p&gt;

&lt;h3 id=&quot;blogenginenet&quot;&gt;&lt;a href=&quot;http://dotnetblogengine.net/&quot; target=&quot;_blank&quot;&gt;BlogEngine.net&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;I was strongly considering going with BlogEngine.net. Aside from WordPress, it was the only one that had search built in. That struck me as a bit odd because I probably search my own blog 5-6 times per year. And use search on other people’s blogs more frequently than that. It had some free themes, but nothing I really liked. While looking at building my own theme I stumbled on MiniBlog and since they are both built by Mads Kristensen (yes, of Web Essentials fame) and both use the same format for storing their posts I figured I’d use the newer MiniBlog and I could easily switch back if I decided I really wanted built in search.&lt;/p&gt;

&lt;h3 id=&quot;miniblog&quot;&gt;&lt;a href=&quot;https://github.com/madskristensen/MiniBlog&quot; target=&quot;_blank&quot;&gt;MiniBlog&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;I really liked MiniBlog. It was really stripped down and really fast. I went as far as building out my whole theme (based on the theme I was using with WordPress). This is a big deal for me. I usually just hand anything CSS related off to a front end guy. I had chosen MiniBlog. I even had a few pull requests merged to fix some bugs I found (my first open source contributions!)&lt;/p&gt;

&lt;p&gt;One of the things I really liked was Windows Live Writer integration. This was one of the biggest selling points. It also turned out to be the reason I ditched MiniBlog.&lt;/p&gt;

&lt;p&gt;The nice thing about Windows Live Writer is that you can write locally then click the publish button and whoosh, your post is live. But the post was just stored on disk in the cloud. There wasn’t any backup mechanism like I had with WordPress. And to make matters worse, I was modifying the source, so there was a chance that during one of my deploys I could wipe out my history.&lt;/p&gt;

&lt;p&gt;The best I could come up with was to run locally, publish to the local instance from Windows Live Writer then push the whole thing live.&lt;/p&gt;

&lt;h3 id=&quot;pretzel&quot;&gt;&lt;a href=&quot;http://code52.org/pretzel.html&quot; target=&quot;_blank&quot;&gt;Pretzel&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;This was my first look at static site generation. The idea is that instead of rendering the blog post when the user comes to your site you render it locally then push the rendered page up. The blogging is done in MarkDown.  It’s pretty nice, and it’s supposed to be a Jekyll clone, but there’s not a lot of documentation or examples and some things from Jekyll that I tried didn’t work.&lt;/p&gt;

&lt;h3 id=&quot;jekyll&quot;&gt;&lt;a href=&quot;http://jekyllrb.com/&quot; target=&quot;_blank&quot;&gt;Jekyll&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;“Pretzel seemed to be missing some features, maybe I should try going right to Jekyll.” - Me 45 minutes before giving up.&lt;/p&gt;

&lt;p&gt;As I said at the start, I’m a .Net Developer. And though I think I could figure out how to get Ruby installed, and Jekyll and it’s dependencies. After 45 minutes I gave up. If it’s that hard to get to “Hello World”, I’m not sure I want to go further.&lt;/p&gt;

&lt;p&gt;Also, since posts are written in MarkDown, if I used another MarkDown based static site generator I’d have little trouble switching.&lt;/p&gt;

&lt;h3 id=&quot;piecrust&quot;&gt;&lt;a href=&quot;http://bolt80.com/piecrust/&quot; target=&quot;_blank&quot;&gt;PieCrust&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Like Pretzel and Jekyll, PieCrust is a static site generator. And it mostly “Just worked”. I ran into a few problems, but when I reached out to it’s author, &lt;a href=&quot;http://ludovic.chabant.com/&quot; target=&quot;_blank&quot;&gt;Ludovic&lt;/a&gt;, on twitter he responded with fixes and workarounds within an hour or two.&lt;/p&gt;

&lt;p&gt;Again, it’s a static site, so to create a post you create a MarkDown file in a specif folder (or tell PieCrust to create it for you).  Write your post in that file, then tell PieCrust to build the site for you. Then you upload the whole site.&lt;/p&gt;

&lt;p&gt;And of course, since it’s a static site, it’s as fast as file transfer.  My home page is 36k and takes about a half second to load. I’m hoping you noticed ;)&lt;/p&gt;

&lt;p&gt;The only downside is there is no built in search. Because it’s static. I’ve seen some interesting workarounds doing a string matching search in clientside JS, but I went with Google. I think the only problem there would be recent posts might not be indexed. Trade-offs, there are always trade-offs.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>NoSql</category>
      
      

      <title>My First NoSQL Table</title>
      <link>https://hutchcodes.net/2015/05/my-first-nosql-table/</link>
      <pubDate>Tue, 19 May 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/05/my-first-nosql-table/</guid>
      <description>&lt;p&gt;I come from a relational database background. Specifically I’ve been using Microsoft SQL for 18 years. At this point data modeling for a relational database is second nature.  Data modeling in NoSQL on the other hand has been somewhat mysterious to me. I’ve read up on some of the strategies for where to break NoSQL data into separate tables, but have had little real world experience.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;The lack of real world experience has been two-fold. First I haven’t seen a NoSQL database designed by someone who &lt;em&gt;really&lt;/em&gt; knew their NoSQL data modeling, and I haven’t done much NoSQL data modeling which might allow me to see where things become problematic from being too normalized or too denormalized.&lt;/p&gt;

&lt;p&gt;At my job we are using some NoSQL (AWS DynamoDB). The main application uses an MSSQL database and we mostly use DynamoDB for it’s ability to replicate some performance critical data across regions so that our European customers don’t have the latency of crossing the Atlantic for everything.&lt;/p&gt;

&lt;p&gt;But, recently I had a bit of an epiphany when I was adding a rule builder to our project. Each rule could have multiple conditions and groups of conditions., and the groups could also contain other groups. By default I put the data into a Rules, Groups, and Conditions tables in the database.  That was working fine initially, but the recursion started to become a problem.&lt;/p&gt;

&lt;p&gt;Recursive data structures can be problematic in SQL. You need do a series of left joins for each level of recursion, and you need to decide in advance how many levels of recursion you’re going to allow.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Rules&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Conditions&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RuleId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RuleId&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;--Level 1 Conditions&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Groups&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RuleId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RuleId&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;--Level 1 Group&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Conditions&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GroupId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GroupId&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;--Level 1 Group Conditions&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Groups&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GroupId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ParentGroupId&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;--Level 2 Group&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Conditions&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c3&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GroupId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GroupId&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;--Level 2 Group Conditions&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To do this with Entity Framework you need to do something like&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rules&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Rules&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Conditions, Groups.Conditions, Groups.Groups.Conditions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You could of course lazy load the groups and conditions, but that’s a recipe for performance disaster. This is going to be the classic &lt;a href=&quot;http://www.davepaquette.com/archive/2013/02/05/writing-efficient-queries-with-entity-framework-code-first-part-1.aspx&quot; target=&quot;_blank&quot;&gt;N+1 problem&lt;/a&gt;, only since it’s recursive it’s the N1+N2+N3+1.&lt;/p&gt;

&lt;p&gt;After a night of chewing on the problem I decided that the answer was to store the Rules in DynamoDB. I simply created a Rules collection and plopped the whole Rule right in. Each rule is now one object in the a NoSQL table. No joins necessary and no worry about N+1 performance issues.&lt;/p&gt;

&lt;p&gt;It’s so blindingly obvious in hindsight that I’m surprised I never thought of it before, and I almost certainly won’t attempt to store a recursive data structure in a relational database again.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>The Perfect Job</title>
      <link>https://hutchcodes.net/2015/05/the-perfect-job/</link>
      <pubDate>Thu, 14 May 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/05/the-perfect-job/</guid>
      <description>&lt;p&gt;Occasionally after telling a recruiter that I’m not interested in a position (yes, I try to respond to the ones that are not obviously spam) they’ll ask what I am looking for, which is an odd question since I’m usually not looking.  I usually list a couple of things, but from this day forward I will refer them to this post.  Also, my boss asked me if there was anything the company could do to make things “better for you and the rest of the team”.  So here it is, a description of my ideal job, with the full knowledge that it almost certainly doesn’t exist, and tradeoffs will be made.&lt;/p&gt;

&lt;p&gt;The list is somewhat of a priority order.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;team&quot;&gt;Team&lt;/h2&gt;

&lt;p&gt;The team, more than any other aspect, can make or break a job. I want a team of really smart people. And not just smart developers, but smart managers, product owners, QA, design etc.  And not just smart, they should be open to sharing their knowledge as well as learning from others. Smart enough to have strong opinions, but humble enough to let others run with their ideas even when they disagree.&lt;/p&gt;

&lt;h2 id=&quot;the-work&quot;&gt;The Work&lt;/h2&gt;

&lt;p&gt;It isn’t about what I’m building, it’s about how we build it. I don’t want to build a mediocre anything. I want to work on a project where the goal is to create the best X. I want to have time to make sure it’s being built well, that’s it’s well tested, that it scales as needed, and most importantly that it’s maintainable.&lt;/p&gt;

&lt;p&gt;That doesn’t mean I want perfection from the outset. I understand tradeoffs will be made, but we should be striving towards excellence, not mediocrity.&lt;/p&gt;

&lt;h2 id=&quot;work-environment&quot;&gt;Work Environment&lt;/h2&gt;

&lt;p&gt;The key to work environment for me is quiet. Ideally that would mean an office with a door, maybe one officemate. If it’s a team room or open plan, there should be an expectation of near silence. That means whenever possible people take their phone and other conversations in a different room.&lt;/p&gt;

&lt;p&gt;I already have my perfect office in my house and really prefer working on remote teams. The key here is that the team needs a remote mindset, not an office based team with an office based mindset with 1-2 remote developers. Meetings can be very difficult if it’s a room full of people talking and I’m the only one on Teams/Zoom.&lt;/p&gt;

&lt;h2 id=&quot;compensation&quot;&gt;Compensation&lt;/h2&gt;

&lt;p&gt;I’d still write software if I were independently wealthy, but I just wouldn’t have a “job”. So yes, the job needs to pay. I never want money to be the deciding factor in taking a job. It can easily be the deciding factor if the salary is too low but is unlikely to be the deciding factor otherwise.&lt;/p&gt;

&lt;h2 id=&quot;bonuses&quot;&gt;Bonuses&lt;/h2&gt;

&lt;p&gt;This is the section where companies can really differentiate themselves. Some of these perks are worth more than others, but I didn’t make any attempt to put them in any kind of order.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Work from home (full time or even part time)&lt;/li&gt;
  &lt;li&gt;Send the team to a conference&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://pluralsight.com&quot;&gt;Pluralsight&lt;/a&gt; or other similar subscription&lt;/li&gt;
  &lt;li&gt;Flexible schedule&lt;/li&gt;
  &lt;li&gt;Latest software (should be on the latest version of Visual Studio)&lt;/li&gt;
  &lt;li&gt;Excellent hardware&lt;/li&gt;
  &lt;li&gt;Budget for tools like &lt;a href=&quot;https://www.jetbrains.com/resharper/&quot;&gt;Resharper&lt;/a&gt;, &lt;a href=&quot;https://www.semanticmerge.com/&quot;&gt;Semantic Merge&lt;/a&gt;, etc&lt;/li&gt;
  &lt;li&gt;MSDN Subscription&lt;/li&gt;
  &lt;li&gt;Time and/or encouragement for blogging&lt;/li&gt;
  &lt;li&gt;Help with speaking at conferences (time off and/or travel covered)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;whats-not-listed&quot;&gt;What’s not Listed&lt;/h2&gt;

&lt;p&gt;I didn’t list the typical trappings of ‘startup culture’ like free massages, gym memberships, lunches, soda, beer, or whatever. Those are nice, I’ve had some of them before, but they are just not something that would sway me. Some of them are even red flags.&lt;/p&gt;

&lt;p&gt;Recruiters, please include the word “tradeoffs” in the first line of your email so I know you read this.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Azure</category>
      
      

      <title>Scheduled Jobs in Azure</title>
      <link>https://hutchcodes.net/2015/04/scheduled-jobs-in-azure/</link>
      <pubDate>Sat, 25 Apr 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/04/scheduled-jobs-in-azure/</guid>
      <description>&lt;p&gt;Have a process you need to run periodically on your Azure hosted application? It’s simple to do with Azure Scheduler.&lt;/p&gt;

&lt;p&gt;From the Azure Management screen (not currently available in the new portal) click New-&amp;gt;App Services-&amp;gt;Scheduler-&amp;gt;Custom Create
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/Scheduler.png&quot; alt=&quot;create schedule&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This will open up the job creation wizard.  First you need to create a Job Collection.  You can choose your region, you probably want it to be located in the same Region as your Web Site, but you may have a reason you want it hosted somewhere else.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/Schedule11.png&quot; alt=&quot;Create job&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Give your job a name, select the type of job HTTP, HTTPS, or Storage Queue.  For this example I’ve just chosen an HTTP Get call to a URL that doesn’t actually exist on my blog.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/Schedule2.png&quot; alt=&quot;Job Action&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then select the schedule.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/Schedule3.png&quot; alt=&quot;Define Schedule&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So in this example the Azure Schedule is going send a Get request to /jobs/dostuff every minute.  All I need to do is implement what I need done in that controller action.&lt;/p&gt;

&lt;p&gt;A couple things to note:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;By default it puts you on the Standard plan which is $13.99/month.  You can use the free tier if you have 5 or less jobs and they don’t need to run more frequently than hourly. You need to edit the job after you create it to switch to the Free tier.&lt;/li&gt;
	&lt;li&gt;When you’re editing a job you have the option to add headers and/or basic auth.&lt;/li&gt;
	&lt;li&gt;You can call any public URL, so you&apos;re not limited to only calling URLs that are hosted on Azure.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      

      <title>C#6 String Interpolation</title>
      <link>https://hutchcodes.net/2015/03/c6-string-interpolation/</link>
      <pubDate>Tue, 31 Mar 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/03/c6-string-interpolation/</guid>
      <description>&lt;p&gt;Another feature I’m looking forward to in C#6 is string interpolation.  We’ve all had to create string messages to show the user that include data from the application, or maybe we’re just writing some debug information to the console.  We can build these messages a few ways right now.
&lt;!--more--&gt;&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//string concatenation&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;User &apos;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&apos; logged in at &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loginDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//string.Format&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;User &apos;{0}&apos; logged in at {1}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loginDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;C#6 gives us a third method – String Interpolation.  This allows us to include expressions directly in our string literals.  Just place the value between 2 curly braces.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;logMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;User &apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos; logged in at &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loginDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//User &apos;jrhutch&apos; logged in at 3/31/2015 2:03:31 PM&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can also apply formatting to the values&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;myString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;User &apos;I spent &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;54.235&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos; at &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;someDate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//I spent $54.24 at 14:04&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or if you really want to get crazy (and I’m not sure I’d take it this far), you can use a conditional expression to decide the content of your string&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unreadCnt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; unread &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unreadCnt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;message&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;messages&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//1 unread message&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//2 unread messages&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I wouldn’t say I’ll be doing all my string generation with interpolation, but it sure is nice to have another tool in the box.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Community</category>
      
      

      <title>Why You Should Give a Lightning Talk</title>
      <link>https://hutchcodes.net/2015/03/you-should-give-a-lightning-talk/</link>
      <pubDate>Mon, 02 Mar 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/03/you-should-give-a-lightning-talk/</guid>
      <description>&lt;p&gt;I previously posted that I had appointed myself &lt;a href=&quot;/2015/02/community-booster/&quot;&gt;Community-Booster&lt;/a&gt;, and so I now see it as my job to convince you to give a lightning talk at your local user group.  I could start by listing the benefits to you, or to the benefits to the user group, but I don’t think the for most people the fear of things going poorly outweigh the potential benefits.  So let’s focus on your fears.
&lt;!--more--&gt;&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;“I have nothing interesting to present”&lt;/strong&gt; – This is very unlikely to be true. You spend every day working with code, there is at least one concept that with a bit of preparation you talk about for 15 minutes.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;“I have nothing original to present”&lt;/strong&gt; – This one is very likely to be true, but it doesn’t matter. You don’t need an original idea, you just need your take on an idea. I didn’t discover the techniques I used in my Cross Platform Development talk, I collected a bunch of different techniques that others have shared through documentation, blog posts and even other presentations and compiled them into a larger talk. I presented the Repository Pattern in a lightning talk and I sure didn’t come up with on my own.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;“I’m not a good public speaker”&lt;/strong&gt; – This could be true, but it doesn’t mean you can’t become a decent or good public speaker and the only way to improve is to get out there an speak.  What better place to do that than in a room filled with people who tend to not be great public speakers, they’ll will be a forgiving bunch.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The positives break down into two categories&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Makes you more hirable&lt;/strong&gt; – If you submit a resume and somewhere on there it says that you spoke about X technology at your local user group that should pique the hiring manager’s interest even if they don’t use that technology. It shows that you take an interest in improving yourself. It shows that you know or researched a topic enough to be able to present it.  It also shows that you can communicate, which is something that can be hard to show on a resume. Most importantly it shows that you’re willing to share your knowledge, that you’re willing to spend your time and energy to help others become better developers.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Improves your developer Community&lt;/strong&gt; – Every lightning talk I’ve ever heard helped me in some way. It’s not that I’ve been able to apply the knowledge immediately, but I’ve taken what I’ve learned and filed it away for future use. Even the design patterns talks were helpful, I’ve read books on design patterns and have implemented a fair number of them, but having someone step through one is still educational.  Most importantly, you might inspire someone else to speak.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’m not going to lie, becoming more hirable was my primary motive for blogging and speaking when I started.  Now I’m focused more on improving the community. I learn so much from other people’s contributions through blog posts, answering questions on forums and speaking at user groups that I feel obligated to give back to that community. The more of us who give back, the better we all become.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      

      <title>Null Conditional Operator</title>
      <link>https://hutchcodes.net/2015/02/null-conditional-operator/</link>
      <pubDate>Mon, 23 Feb 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/02/null-conditional-operator/</guid>
      <description>&lt;p&gt;There are a bunch of cool features coming in C#6, but the one I’m looking forward to the most is the Null Conditional Operator.&amp;nbsp; Developers write a lot of code to check if a value is null.&amp;nbsp; Sometimes it creates a deep and ugly nest of if statements.&amp;nbsp; Let’s say you are trying to find a customer’s primary contact’s city, it might look like this:&lt;/p&gt;
&lt;!--more--&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;primaryContactCity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryContact&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryContact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;primaryContactCity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryContact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or maybe you prefer less nesting and instead use a longer if statement:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;primaryContactCity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryContact&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryContact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;primaryContactCity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryContact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With the new Null Conditional Operator you can just put &lt;strong&gt;?.&lt;/strong&gt; in place of the &lt;strong&gt;.&lt;/strong&gt;.  If the value to the left of the &lt;strong&gt;?.&lt;/strong&gt; is null it returns null otherwise it returns the property to the right.  These two bits of code return the same thing:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;primaryContactAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryContact&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;primaryContactAddress&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;primaryContactAddress&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryContact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;primaryContactAddress&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;primaryContact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So the deep nest from above can be re-written as:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;primaryContact&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;primaryContact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It starts to get some real power when you use it in combination with the Null Coalescing Operator &lt;strong&gt;??&lt;/strong&gt;  In the following code we return the City as ‘Unknown’ if the PrimaryContact is null, or if the Address is null, or the City is null.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;primaryContactCity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;customer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;primaryContact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;City&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Unknown&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      
      <category>Community</category>
      
      

      <title>Community-Booster</title>
      <link>https://hutchcodes.net/2015/02/community-booster/</link>
      <pubDate>Tue, 17 Feb 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/02/community-booster/</guid>
      <description>&lt;p&gt;A little over a year ago our local .Net User Group shut down (Maine Bytes).  The guy who had been running it for 10+ years decided he didn’t want to continue the work, and rather than find someone to fill his shoes he just shut it down (if you want to hear a rant ask me what I think about that decision).&lt;/p&gt;

&lt;p&gt;Maine Bytes seemed to encourage passive attendance, not participation.  I’m not sure if was intentional or if it was the space (rows of tables facing the speaker) or just a vibe the group developed, but I frequently went and rarely talked with anyone. &lt;!--more--&gt; They usually had a seasoned speaker come in from out of the area and the group (myself included) began to expect that. The one time the group held a “member lightning talk” night, I think it came as a surprise, and I’m ashamed to admit I was a little put off, that we had inexperienced speakers.&lt;/p&gt;

&lt;p&gt;When &lt;a href=&quot;http://www.cbnug.com&quot; target=&quot;_blank&quot;&gt;Casco Bay .Net User Group&lt;/a&gt; filled the gap, their second meeting was a “member lightning talk” night.  At my co-worker’s urging (he is one of the organizers) I presented a gave a quick talk on Automated UI Testing with Selenium.  I really enjoyed speaking, but I also really enjoyed the other lightning talks.  They were compact and informative.&lt;/p&gt;

&lt;p&gt;That night was enough to encourage me to speak at &lt;a href=&quot;http://bostoncodecamp.com&quot; target=&quot;_blank&quot;&gt;Boston Code Camp&lt;/a&gt;, then &lt;a href=&quot;http://vtcodecamp.org&quot; target=&quot;_blank&quot;&gt;Vermont Code Camp&lt;/a&gt; as well as a few more CBNUG lightning talk nights. I’ve really enjoyed each of these events for their own reasons, but Vermont Code Camp really stirred something in me.&lt;/p&gt;

&lt;p&gt;Two things happened the week of Vermont Code Camp that changed the way I look at our user group.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Russ Fustino spoke to our group about Xamarin Forms, which was a great, but at the end he said “Where are we all going to get a beer?” The question wasn’t “does anyone want to get a beer?”, the assumption was that we were all going to the bar and he wanted to know where. This was the first time we went for drinks after any user group meeting I’d ever been to, and it really broke the ice for the group.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;I went to Vermont Code Camp. At first I was excited to see how many names I recognized as seasoned speakers I’d seen at bigger conferences or recognized from Twitter. But what really impressed me was the quantity and quality of speaker from Vermont.  It made me realize that these speakers probably got their starts at their local user group (&lt;a href=&quot;http://www.meetup.com/VTCode/&quot; target=&quot;_blank&quot;&gt;VTdotNet&lt;/a&gt;).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those two things made me realize we had a lot of work to do in Portland around building a better user group and more importantly a better community.  I realized I (and the group as a whole) needed to look forward to lightning talk nights. It’s on these nights when a first time speaker gets up and fumbles through a rushed presentation of a small idea that our user group truly grows. And it’s after the “official” meeting when we reconvene at the local pub that our community grows in other equally important ways.&lt;/p&gt;

&lt;p&gt;Because of that revelation I have decided to appoint myself Community Booster.  I am going to do my best to encourage involvement at every level.  I’m going to encourage people to attend the user group meetings, to come out with us after, to speak at the lightning talks, to submit talks to both CBNUG and code camps. This isn’t an area I have much experience in, and I’m sure I’ll make some mistakes along the way, but I feel like the community I want to have in my local area needs someone (or multiple people) to really embrace this role.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Productivity</category>
      
      <category>Random</category>
      
      

      <title>Don&apos;t Be Late for Scrum</title>
      <link>https://hutchcodes.net/2015/02/dont-be-late-for-scrum/</link>
      <pubDate>Tue, 03 Feb 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/02/dont-be-late-for-scrum/</guid>
      <description>&lt;p&gt;We all know the importance of being on time for meetings, and since scrum is designed to be a short meeting, if you’re 5 minutes late for scrum you can miss a third to half of it.&lt;/p&gt;

&lt;p&gt;I’m a morning person, so I find myself most focused and most productive before lunch.  That often means that when scrum rolls around at 9:30 I can be totally lost in thought with no concept of time. &lt;!--more--&gt; In other words I have a tendency towards running late.
The obvious thing to do is to set a reminder, but I usually run my sound through my headphones so if I’m not wearing them there’s a good chance that reminder is just going to pop up and not be seen.  When I worked in an office I’d see the other developers moving out of the corner of my eye and realize what time it was, no problem.&lt;/p&gt;

&lt;p&gt;Since I’ve been working from home we’ve been having scrum over Skype.  Our leader starts a group call and thanks to Skype’s ability to ring through the speakers while using my headset for communication I was never late.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/image.png&quot; alt=&quot;skype settings image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That worked great, but we recently moved our scrums to a Google Hangout.  On the plus side, we’re all doing video (not sure why we didn’t with Skype) and having a blast with Google Effects.  The downside of course is that we need to “dial-in” to every day.&lt;/p&gt;

&lt;p&gt;I realized immediately that this left me with the potential to be late or even miss scrum, here’s the solution I came up with.  I’m using Task Schedule that is built into Windows to launch Chrome and navigate to our Scrum hangout.  Just create a &lt;em&gt;Basic Task&lt;/em&gt;, set the schedule, choose &lt;em&gt;Launch a Program&lt;/em&gt; for &lt;em&gt;Action&lt;/em&gt;.  Select the path to your favorite browser for the &lt;em&gt;Program&lt;/em&gt;, and put the URL in the &lt;em&gt;Add arguments &lt;/em&gt;field&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/image_3.png&quot; alt=&quot;create task wizard&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now every morning when scrum starts Chrome opens a new tab and brings up the Scrum hangout.  All I need to do is click the “Join” button.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>New Years Resolutions 2015</title>
      <link>https://hutchcodes.net/2015/01/new-years-resolutions-2015/</link>
      <pubDate>Tue, 13 Jan 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/01/new-years-resolutions-2015/</guid>
      <description>&lt;p&gt;This is my annual post where I publicly declare a few goals for the coming year.  Next year around this time I will take a look back to see &lt;a title=&quot;New Years Resolutions 2014 – Retrospective&quot; href=&quot;/2015/01/new-years-resolutions-2014-retrospective/&quot;&gt;how I did&lt;/a&gt;.  Looking back at last year I noticed that some of my resolutions didn’t have objective measurements, so I’m trying to include those this year.&lt;!--more--&gt;&lt;/p&gt;

&lt;h2&gt;Speak More&lt;/h2&gt;
&lt;p&gt;They say you &lt;em&gt;really&lt;/em&gt; learn something when teaching it, and I can speaking forced me to deeply learn the topics I was presenting.  I really enjoyed speaking at my local &lt;a href=&quot;http://www.cbnug.net&quot;&gt;.Net user’s group&lt;/a&gt; as well as &lt;a href=&quot;http://www.bostoncodecamp.com/&quot;&gt;Boston Code Camp&lt;/a&gt; and &lt;a href=&quot;vtcodecamp.org&quot;&gt;Vermont Code Camp&lt;/a&gt;.  I’m going to submit sessions to all both code camps, my local user group and at least 2 larger conferences.  All I can do is submit, the decision about whether I speak is out of my hands.&lt;/p&gt;
&lt;h2&gt;Blog More Consistently&lt;/h2&gt;
&lt;p&gt;Last year I resolved to blog more, which I did, but I had long stretches without any new posts.  This year I’ve been receiving &lt;a href=&quot;http://simpleprogrammer.com&quot;&gt;John Sonmez&lt;/a&gt;’s email course on &lt;a href=&quot;http://devcareerboost.com/blog-course/&quot;&gt;building a blog&lt;/a&gt;.  It’s been an excellent course, and I would highly recommend signing up.    One of the steps in the course is to commit to a blogging schedule.  I’m committing to 2 posts per month.  A much more objective goal than I had last year.  Don’t be surprised if you see 2 posts on the last day of every month :)&lt;/p&gt;
&lt;h2&gt;Finish My Side Project&lt;/h2&gt;
&lt;p&gt;A friend and I have been working on a &lt;a href=&quot;http://measurent.com/&quot;&gt;rental property management&lt;/a&gt; web application for a while now.  We both started new jobs in the middle of it and we’re both burnt out to the point that we were close to ditching it.  We are down to a handful of tough bugs and a few minor features we want to implement before releasing.  We’ve been on a hiatus for a month now, I’m thinking I’ll take another month hiatus before picking it back up, but I will release it by May 1, 2015 with bugs and missing features if I have to.&lt;/p&gt;
&lt;h2&gt;Personal Goals&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Lose Weight - &lt;/strong&gt;As I said last year, this one is a bit cliche for a New Year’s resolution, and last year wasn’t a grand success.  I only lost 5 of the 40 I figured I needed to lose.  This year I’m going to target losing 20 of the remaining 35.  I’ll tackle the rest in 2016.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finish House Projects&lt;/strong&gt; - I have projects that I started basically as soon as I bought this house 5+ years ago that still haven’t been completed.  These are things I can do myself and I have been loath to hire them out.  I’m either going to do them myself or hire them out this year:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Fix the hole in the kitchen ceiling&lt;/li&gt;
	&lt;li&gt;Sheetrock the attic&lt;/li&gt;
	&lt;li&gt;Finish the trim on the second floor&lt;/li&gt;
	&lt;li&gt;Remove the unused oil tank in the basement&lt;/li&gt;
	&lt;li&gt;Paint the house&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>New Years Resolutions 2014 - Retrospective</title>
      <link>https://hutchcodes.net/2015/01/new-years-resolutions-2014-retrospective/</link>
      <pubDate>Mon, 12 Jan 2015 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2015/01/new-years-resolutions-2014-retrospective/</guid>
      <description>&lt;p&gt;It’s time for my annual resolutions blog post, but first I wanted to do a little retrospective to see how I did on &lt;a title=&quot;New Year’s Resolutions 2014&quot; href=&quot;/2014/01/new-years-resolutions-2014/&quot;&gt;last year’s resolutions&lt;/a&gt;.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: #339966;&quot;&gt;✓&lt;/span&gt; Blog More&lt;/strong&gt; - I did blogged &lt;em&gt;more&lt;/em&gt;, but not as much as I had hoped.  Posts were still less than once per month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: #339966;&quot;&gt;✓&lt;/span&gt; Find more ways to share knowledge&lt;/strong&gt; - My talk at my local user group went well enough that I submitted and gave talks at the June Boston Code Camp, the Vermont Code Camp, and November Boston Code Camp.  I really enjoyed it, and I’m definitely going to continue.  I tried submitting talks to some bigger conferences but was not accepted.  I’ll keep trying.&lt;/p&gt;

&lt;p&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&lt;strong&gt;X&lt;/strong&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;strong&gt;Networking&lt;/strong&gt; - I got off to a good start, checking in with some people I hadn’t spoken to in a while to see what they were up to, but I didn’t continue it and I didn’t really do anything to expand my network aside from chatting with some people at the code camps.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: #339966;&quot;&gt;✓&lt;/span&gt;&lt;/strong&gt; &lt;strong&gt;Going to Bed Earlier&lt;/strong&gt; - I mostly nailed this one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;X&lt;/span&gt;&lt;/strong&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;strong&gt;Lose weight&lt;/strong&gt; - I did shed 5 pounds, and if I didn’t change anything I think I’d lose another 5 this next year.&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;So I was 3 for 5 last year.  I would list the year as a success overall.  I made progress, and I’m still heading in the right direction.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      <category>Mobile</category>
      
      <category>XPlat</category>
      
      

      <title>Sharing Code with Dependency Injection</title>
      <link>https://hutchcodes.net/2014/10/sharing-code-with-dependency-injection/</link>
      <pubDate>Tue, 28 Oct 2014 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2014/10/sharing-code-with-dependency-injection/</guid>
      <description>&lt;p&gt;This is a multipart series on how to share code between .Net platforms.  All the examples will be showing how to share between Windows 8 Store applications and Windows Phone 8 application, but the techniques are useful for sharing code between any .Net/Xamarin platforms.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/08/linked-files/&quot;&gt;Linked Files&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/08/conditional-compilation/&quot;&gt;Conditional Compilation&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/partial-classes/&quot;&gt;Partial Classes&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/sharing-code-with-inheritance/&quot;&gt;Inheritance&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/sharing-code-with-dependency-injection/&quot;&gt;Dependency Injection&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;What is Dependency Injection?&lt;/h3&gt;
&lt;p&gt;Dependency Injection is a form of inversion of control where the consumer of a service passes some of the objects on which that service is dependent to the service, rather than having the service create them.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;How do I do it?&lt;/h3&gt;
&lt;p&gt;In this case we’re not going to use a Dependency Injection framework, we’re going to use what I call “the poor mans dependency injection”.  I’m doing it this way to keep it simple and this could still work well with a framework.&lt;/p&gt;

&lt;p&gt;First we’re going to create a Portable Class Library and in that library we’re going to define an interface for our data storage methods&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IMyStorage&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The we’re going to move our MainePageViewModel class to that library.  We need to modify that class to accept an IMyStorage in it’s constructor, then use that object to get and save it’s data.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MainPageViewModel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INotifyPropertyChanged&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMyStorage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_myStorage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MainPageViewModel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IMyStorage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myStorage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_myStorage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myStorage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_helloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HelloMessage&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_helloMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_helloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_helloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;RaisePropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;HelloMessage&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;RaisePropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SaveAction&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RelayCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoadAction&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RelayCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_myStorage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;HelloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Load &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_myStorage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;HelloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Save &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RaisePropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PropertyChanged&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;PropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PropertyChangedEventArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChangedEventHandler&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the platform specific projects we need to add a reference to the PCL and create a class that implements IMyStorage. Windows Phone specific code below&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyStorage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMyStorage&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then in the MainPage.xaml.cs where we are setting the page’s datacontext to the MainPageViewModel, we need to make sure we’re passing a new instance of the MyStorage class (this is the actual Dependency Injection, poor man’s style)&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PhoneApplicationPage_Loaded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RoutedEventArgs&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MainPageViewModel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyStorage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      <category>Mobile</category>
      
      <category>XPlat</category>
      
      

      <title>Sharing Code with Inheritance</title>
      <link>https://hutchcodes.net/2014/10/sharing-code-with-inheritance/</link>
      <pubDate>Tue, 14 Oct 2014 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2014/10/sharing-code-with-inheritance/</guid>
      <description>&lt;p&gt;This is a multipart series on how to share code between .Net platforms.  All the examples will be showing how to share between Windows 8 Store applications and Windows Phone 8 application, but the techniques are useful for sharing code between any .Net/Xamarin platforms.&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;a href=&quot;/2014/08/linked-files/&quot;&gt;Linked Files&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/08/conditional-compilation/&quot;&gt;Conditional Compilation&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/partial-classes/&quot;&gt;Partial Classes&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/sharing-code-with-inheritance/&quot;&gt;Inheritance&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/sharing-code-with-dependency-injection/&quot;&gt;Dependency Injection&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;What is Inheritance?&lt;/h3&gt;
&lt;p&gt;I’m just going to go ahead and assume you understand inheritance, but I’m keeping this section to stay with the theme from the other posts in this series.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;How do I do it?&lt;/h3&gt;
&lt;p&gt;To share code in this way we’re going to create an abstract class MainViewModelBase with an abstract method defined for the place where we’re going to do our platform specific coding.  We can share that class between projects either through file linking or creating a Portable Class Library&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MainPageViewModelBase&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INotifyPropertyChanged&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;//The rest of the common code would go here&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_helloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HelloMessage&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_helloMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_helloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_helloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;RaisePropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;HelloMessage&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;RaisePropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SaveAction&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RelayCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LoadAction&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RelayCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RaisePropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PropertyChanged&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;PropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PropertyChangedEventArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChangedEventHandler&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;        
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then we’re going to inherit from that class in each of our projects.  Here’s what the code for the Windows Phone project looks like&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MainPageViewModel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MainPageViewModelBase&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;HelloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;HelloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      <category>Mobile</category>
      
      <category>XPlat</category>
      
      

      <title>Sharing Code with Partial Classes</title>
      <link>https://hutchcodes.net/2014/10/partial-classes/</link>
      <pubDate>Wed, 01 Oct 2014 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2014/10/partial-classes/</guid>
      <description>&lt;p&gt;This is a multipart series on how to share code between .Net platforms.  All the examples will be showing how to share between Windows 8 Store applications and Windows Phone 8 application, but the techniques are useful for sharing code between any .Net/Xamarin platforms.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/08/linked-files/&quot;&gt;Linked Files&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/08/conditional-compilation/&quot;&gt;Conditional Compilation&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/partial-classes/&quot;&gt;Partial Classes&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/sharing-code-with-inheritance/&quot;&gt;Inheritance&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/sharing-code-with-dependency-injection/&quot;&gt;Dependency Injection&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;What are Partial Classes?&lt;/h3&gt;
&lt;p&gt;Partial Classes are a way to split a class up into multiple files. It is frequently used when one part of your class is generated code and another part is written by hand.  In this case we’ll use partial classes to separate code that is shared between platforms and code that is platform specific.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;How do I do it?&lt;/h3&gt;
&lt;p&gt;First you would need to use &lt;a href=&quot;/2014/08/linked-files/&quot;&gt;linked files&lt;/a&gt; to share the code between your projects. Then you need to change the class declaration to include the keyword partial.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MainPageViewModel&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then you create a new files in each of your projects.  In this example we’ll create MainPageViewModel.WP8.cs and MainPageViewModel.W8.cs.  The WP8 file would be created in the Windows Phone project and the W8 file would be created in the Window 8 project.  We then need to include that same class declaration in those files.&lt;/p&gt;

&lt;p&gt;Then we just move the methods with platform specific code into those platform specific partial classes.&lt;/p&gt;

&lt;p&gt;The WP8 file would look like this:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MainPageViewModel&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsolatedStorageSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;HelloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Load &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The W8 file would look like this:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MainPageViewModel&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LocalSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ContainsKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ApplicationData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LocalSettings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;HelloMessage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      <category>Mobile</category>
      
      <category>XPlat</category>
      
      

      <title>Sharing Code with Conditional Compilation</title>
      <link>https://hutchcodes.net/2014/08/conditional-compilation/</link>
      <pubDate>Wed, 27 Aug 2014 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2014/08/conditional-compilation/</guid>
      <description>&lt;p&gt;This is a multipart series on how to share code between .Net platforms.  All the examples will be showing how to share between Windows 8 Store applications and Windows Phone 8 application, but the techniques are useful for sharing code between any .Net/Xamarin platforms.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/08/linked-files/&quot;&gt;Linked Files&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/08/conditional-compilation/&quot;&gt;Conditional Compilation&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/partial-classes/&quot;&gt;Partial Classes&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/sharing-code-with-inheritance/&quot;&gt;Inheritance&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/sharing-code-with-dependency-injection/&quot;&gt;Dependency Injection&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;What is Conditional Compilation?&lt;/h3&gt;
&lt;p&gt;Conditional Compilation tells the compiler to selectively compile code.  Many developers use these to run certain code only while in debug that they don’t want to run in production.
&lt;!--more--&gt;&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#if DEBUG
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;//do some stuff&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3&gt;How do I do it?&lt;/h3&gt;
&lt;p&gt;The first step would be to link a file between two projects.  Then you can either use an existing Conditional Compilation Symbol or create your own.  For example Windows Phone 8 defines SILVERLIGHT and WINDOWS_PHONE as Conditional Compilation Symbols.  You see see what symbols have been defined by your project and even add your own by going to the Build tab in Project Properties.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/CompilerDirective.png&quot; alt=&quot;Build Options Dialog&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To use the Conditional Compilation Symbols you just use the #if statement.  For example if you are using a namespace exists in Windows Phone, but doesn’t exist in Windows 8 you could do this:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#if WINDOWS_PHONE
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System.IO.IsolatedStorage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#else
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Windows.Storage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The System.IO.IsolatedStorage using statement will only be compiled in the Windows Phone projects.  The Windows.Storage using statement will be compiled in all other projects.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      <category>Mobile</category>
      
      <category>XPlat</category>
      
      

      <title>Sharing Code with Linked Files</title>
      <link>https://hutchcodes.net/2014/08/linked-files/</link>
      <pubDate>Fri, 15 Aug 2014 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2014/08/linked-files/</guid>
      <description>&lt;p&gt;This is a multipart series on how to share code between .Net platforms.  All the examples will be showing how to share between Windows 8 Store applications and Windows Phone 8 application, but the techniques are useful for sharing code between any .Net/Xamarin platforms.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/08/linked-files/&quot;&gt;Linked Files&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/08/conditional-compilation/&quot;&gt;Conditional Compilation&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/partial-classes/&quot;&gt;Partial Classes&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/sharing-code-with-inheritance/&quot;&gt;Inheritance&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/2014/10/sharing-code-with-dependency-injection/&quot;&gt;Dependency Injection&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt; What are Linked Files?&lt;/h3&gt;
&lt;p&gt;Linked files are a way for two or more projects to both reference the same file.  One project generally keeps that file under it’s file structure, other projects reference the file there.  You can open the file from any of the projects as you normally would and edit it.  All changes are saved to the one file.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h3&gt;Be Aware&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;You need to manually link the files.  If you have 50 code files you want to share between project, you need to add those 50 files as links individually.&lt;/li&gt;
	&lt;li&gt;If you rename a file that has been shared, you need to delete the old link and add the new link.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How do I do it?&lt;/h3&gt;
&lt;p&gt;Go through the regular process for adding an existing file, but after you’ve selected the file you need to select “Add as Link” from the dropdown at the bottom.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/linkfiles.png&quot; alt=&quot;add existing item dialog&quot; /&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Sql</category>
      
      

      <title>Automating the compare of 2 rows in a trigger</title>
      <link>https://hutchcodes.net/2014/05/automating-the-compare-of-2-rows-in-a-trigger/</link>
      <pubDate>Tue, 06 May 2014 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2014/05/automating-the-compare-of-2-rows-in-a-trigger/</guid>
      <description>&lt;p&gt;I just answered this &lt;a href=&quot;http://stackoverflow.com/questions/23500284/generic-solution-to-compare-2-rows/23500897#23500897&quot; target=&quot;_blank&quot;&gt;question&lt;/a&gt; on StackOverflow about how to generically compare an inserted row to a deleted row within a trigger. I started by just commenting that it would be a good place to do a little code generation, but something about the problem wouldn’t let me put it down. Here’s what I came up with.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;First I created a function that would return the query that would actually do the comparison. Notice that I’m comparing &lt;em&gt;#inserted&lt;/em&gt; and &lt;em&gt;#deleted&lt;/em&gt; rather than &lt;em&gt;inserted&lt;/em&gt; and &lt;em&gt;deleted&lt;/em&gt;.  This is because we don’t have access to the &lt;em&gt;inserted&lt;/em&gt; and &lt;em&gt;deleted&lt;/em&gt; tables when we’re running the comparison query in an &lt;em&gt;exec()&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TableName&lt;/span&gt;				&lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
	&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryKeyColumnName&lt;/span&gt;	&lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RowVersionColumnName&lt;/span&gt;	&lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;as&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
	
    &lt;span class=&quot;k&quot;&gt;declare&lt;/span&gt; 
	&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnName&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
           &lt;span class=&quot;s1&quot;&gt;&apos;select isnull(a.&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryKeyColumnName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;, b.&apos;&lt;/span&gt; 
           &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryKeyColumnName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;) 
      from #inserted a
      full join #deleted b 
        on a.&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryKeyColumnName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos; 
           = b.&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryKeyColumnName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;
     where &apos;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ColumnCursor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;cursor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Read_Only&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Object_Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Member&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ColumnCursor&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fetch&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ColumnCursor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnName&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FETCH_STATUS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryKeyColumnName&lt;/span&gt; 
            &lt;span class=&quot;k&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RowVersionColumnName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	  &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt; 
                &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;((a.&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos; != b.&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnName&lt;/span&gt; 
                &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos; or a.&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos; is null 
                    or b.&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos; is null) 
                and (a.&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos; is not null 
                     or b.&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos; is not null))&apos;&lt;/span&gt; 
                &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;      or &apos;&lt;/span&gt; 
          &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;fetch&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ColumnCursor&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ColumnName&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;close&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ColumnCursor&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;deallocate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ColumnCursor&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt; 
           &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Next, I created a trigger.  It creates the &lt;em&gt;#inserted&lt;/em&gt; and &lt;em&gt;#deleted&lt;/em&gt; temp tables, get’s the query from the function, creates a temp table to hold the results.  Then it inserts the result into the temp table.  I’m just selecting the &lt;em&gt;top 10&lt;/em&gt; changed rows, but you could do whatever you needed to do with the changed rows at this point.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trigger&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TestTrigger&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Member&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Delete&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;as&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
	
    &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Inserted&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Inserted&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Deleted&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Deleted&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt; 
            &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;MemberTrash&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;MemberId&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Temp&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryKey&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Temp&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PrimaryKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetChangedRowsQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 

    &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Temp&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;drop&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Temp&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;drop&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Inserted&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;drop&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Deleted&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
    </item>
    
    <item>
      
      <category>Productivity</category>
      
      

      <title>Unsubscribe from everything</title>
      <link>https://hutchcodes.net/2014/05/unsubscribe-from-everything/</link>
      <pubDate>Fri, 02 May 2014 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2014/05/unsubscribe-from-everything/</guid>
      <description>&lt;p&gt;I recently moved my email from Gmail to Outlook.com.  It’s not a small deal.  I needed to get all my friends and family to update their contact info for me, and I’ve had to update my contact info on countless sites.  As part this move I also started unsubscribing to pretty much anything that came into my Gmail account, but not signing up to receive those emails in my Outlook.com account.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2015/unsub.jpg&quot; alt=&quot;Unsubscribe all the things&quot; /&gt;
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;The results have been wonderful.  After about 2 weeks, I now only receive 1-2 emails a day, mostly from people I want to get emails from.  I don’t really know how many emails I was receiving before, but I can tell you it’s really refreshing to be receiving so few.&lt;/p&gt;

&lt;p&gt;I’ve added a reminder to my calendar for next year to spend a week or two unsubscribing from all the junk that builds up as I try out various new services.  You should do the same.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Angular</category>
      
      <category>JavaScript</category>
      
      

      <title>AngularJS URLs missing trailing slash</title>
      <link>https://hutchcodes.net/2014/03/angularjs-urls-missing-trailing-slash/</link>
      <pubDate>Fri, 14 Mar 2014 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2014/03/angularjs-urls-missing-trailing-slash/</guid>
      <description>&lt;p&gt;I ran across this problem trying to deploy an Asp.Net MVC website with an AngularJS front end.  Everything worked fine as long as the site was deployed as it’s own website within IIS, but when we deployed to an Application folder within an existing site things started going wrong.&lt;/p&gt;

&lt;p&gt;The problem was that the URLs were not getting their trailing slashes properly.  IIS adds a trailing slash to URLs when the last segment of the address refers to a folder rather than a file.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://somesite.com/AngularApp&quot;&gt;http://somesite.com/AngularApp&lt;/a&gt; should have been converted to &lt;a href=&quot;http://somesite.com/AngularApp/&quot;&gt;http://somesite.com/AngularApp/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since it wasn’t getting converted I was getting &lt;a href=&quot;http://somesite.com/AngularApp#/&quot;&gt;http://somesite.com/AngularApp#/&lt;/a&gt; rather than &lt;a href=&quot;http://somesite.com/AngularApp/#/&quot;&gt;http://somesite.com/AngularApp/#/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The fix I settled on was to check the URL of the request when it came in and if it matched the root url, but didn’t have the trailing slash, add the trailing slash.  I just added the following code to the Global.asax&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Application_BeginRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationPath&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/&quot;&lt;/span&gt; 
            &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Equals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StringComparison&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CurrentCultureIgnoreCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redirectUrl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;VirtualPathUtility&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AppendTrailingSlash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RedirectPermanent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redirectUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>Show File Extension in Sharepoint Document Library</title>
      <link>https://hutchcodes.net/2014/01/show-file-extension-in-sharepoint-document-library/</link>
      <pubDate>Tue, 21 Jan 2014 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2014/01/show-file-extension-in-sharepoint-document-library/</guid>
      <description>&lt;p&gt;I was recently tasked with changing the view in our TFS Project Portal’s document library to show the file extension so you knew whether you were opening a PDF, Word Document, PowerPoint or something else for which you might not have the software installed.  There is an easy way and a hard way, and the guidance I received from a few Google searches skipped a few steps on the hard way.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2&gt;Easy Way&lt;/h2&gt;
&lt;ol&gt;
	&lt;li&gt;Open the Document Library&lt;/li&gt;
	&lt;li&gt;Click on the Library Tools -&amp;gt; Library tab at the top&lt;/li&gt;
	&lt;li&gt;Scroll to the bottom and click the view you wish to change&lt;/li&gt;
	&lt;li&gt;Check &quot;Name used in forms&quot; column&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This adds a new column with the full file name and extension, but it’s not clickable to view the document, so you end up with two columns for document name, the name and the name with extension.  This is why I ended up going down the hard way.&lt;/p&gt;
&lt;h2&gt;Hard Way&lt;/h2&gt;
&lt;ol&gt;
	&lt;li&gt;Open the site in SharePoint Designer&lt;/li&gt;
	&lt;li&gt;Click Lists and Libraries and open the Document Library you want to modify&lt;/li&gt;
	&lt;li&gt;Open the View you want to modify&lt;/li&gt;
	&lt;li&gt;Right click on the first row in the Name column and select Insert Formula&lt;/li&gt;
	&lt;li&gt;In the Edit XPath expression box enter something that is easily searchable ie. xxxxxxxx&lt;/li&gt;
	&lt;li&gt;Click OK&lt;/li&gt;
	&lt;li&gt;Switch to the Code View&lt;/li&gt;
	&lt;li&gt;Search for your xxxxxxx and delete the element it created&lt;/li&gt;
	&lt;li&gt;Right above or below that should be an element like so &lt;em&gt;&amp;lt;xsl:value-of select=&quot;$thisNode/@FileLeafRef.Name&quot; /&amp;gt;&lt;/em&gt;&lt;/li&gt;
	&lt;li&gt;Replace that with &lt;em&gt;&amp;lt;xsl:value-of select=&quot;$thisNode/@FileLeafRef.Name&quot; /&amp;gt;&amp;lt;xsl:if test=&quot;$thisNode/@FileLeafRef.Suffix!=&apos;&apos;&quot;&amp;gt;.&amp;lt;xsl:value-of select=&quot;$thisNode/@FileLeafRef.Suffix&quot; /&amp;gt;&amp;lt;/xsl:if&amp;gt;&lt;/em&gt;&lt;/li&gt;
	&lt;li&gt;Save, exit and you&apos;re done&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The examples I found online left out steps 4-8, and until I did those the &amp;lt;xsl:value-of select=”$thisNode/@FileLeafRef.Name” /&amp;gt; element didn’t exist.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>New Year&apos;s Resolutions 2014</title>
      <link>https://hutchcodes.net/2014/01/new-years-resolutions-2014/</link>
      <pubDate>Mon, 06 Jan 2014 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2014/01/new-years-resolutions-2014/</guid>
      <description>&lt;p&gt;Here’s my list of New Year’s Resolutions for 2014:&lt;/p&gt;
&lt;h2&gt;&lt;span style=&quot;font-size: 1em; line-height: 1.5em;&quot;&gt;Blog More&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;Historically, I only wrote technical posts whenever I came across something really novel and wasn’t so specific that I didn’t think anyone else can use it.  This year I’m going to loosen my standards for a technical blog posts.  That means there should be more posts, but some of them might just be a different spin on things that others have covered, or things that are really specific and may not be as useful to a broad audience.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2&gt;Find more ways to share knowledge&lt;/h2&gt;
&lt;p&gt;For most of last year I shared an office with a very green developer.  Helping him learn the ropes has also been a great learning experience for myself.  Having to explain some concepts I take for granted to a beginner stretched me in ways I didn’t know I needed to be stretched.  I’d like to explore other ways to share what I have learned.  I have already volunteered to do a short talk on T4 at my local users group (after the main talk), hopefully I’ll be invited back after that.  I’m also going to keep a lookout local volunteer opportunities for things like &lt;a href=&quot;http://code.org/hourofcode&quot;&gt;Hour of Code&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Networking&lt;/h2&gt;
&lt;p&gt;I’ve worked with and met a lot of great people, but many of them I haven’t spoken with in years.  My goal is to reach out to someone twice  a week either through email or phone.&lt;/p&gt;
&lt;h2&gt;Personal Stuff&lt;/h2&gt;
&lt;p&gt;I also have a few resolutions on a more personal level:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go to bed earlier&lt;/strong&gt; - I’m an early riser by nature, and every thing in life is easier when I’m well rested&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lose weight&lt;/strong&gt; - It’s the cliche New Year’s resolution I know, but I lost a bunch of weight before my youngest son was born last April and have packed on the pounds since then.  I make bad food related decision when I’m tired and a new baby isn’t anything if it isn’t tiring.  I’d like to lose 40 pounds and keep it off for good.  No crazy diet here, more of a lifestyle change.  Just eating a little less and working out a little more.  I should be able to lose all of that weight by the end of 2014.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>JavaScript</category>
      
      

      <title>Error: The Key is Already Attached from Breeze.js</title>
      <link>https://hutchcodes.net/2013/11/error-the-key-is-already-attached-from-breeze-js/</link>
      <pubDate>Sat, 30 Nov 2013 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2013/11/error-the-key-is-already-attached-from-breeze-js/</guid>
      <description>&lt;p&gt;First let me say if you’re reading this and you haven’t checked out &lt;a href=&quot;http://www.breezejs.com/&quot; target=&quot;_blank&quot;&gt; Breeze.js&lt;/a&gt;, you should.  It’s a nice little library.  I’m using it in an &lt;a href=&quot;http://angularjs.org/&quot; target=&quot;_blank&quot;&gt;Angular.js&lt;/a&gt; based application and it has greatly simplified data access.  Now on to the show.&lt;/p&gt;

&lt;p&gt;I’m using Breeze.js for data access and as part of that I am registering some constructors like so.
&lt;!--more--&gt;&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AddressCtor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CompanyId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;CompanyId&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;NoteCtor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CompanyId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;CompanyId&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;metadataStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerEntityTypeCtor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AddressCtor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;metadataStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerEntityTypeCtor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Note&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;NoteCtor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Everything was working fine then I tried to do a little code cleanup.  The constructors for Note and Address were identical.   So, of course I, re-factored them into a single generically named function.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CompanyEntity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CompanyId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;CompanyId&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;metadataStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerEntityTypeCtor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CompanyEntity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;metadataStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerEntityTypeCtor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Note&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CompanyEntity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Well, it appears that you cannot register 2 constructors that call the same function like that.  If you do you the error “The Key is Already Attached: Note:Webapplication1”, and no data loaded in the Angular app.&lt;/p&gt;

&lt;p&gt;When I finally found the cause, I couldn’t believe it.  The fix that I came up with was to pass null as the constructor parameter and move that CompanyId assignment into a function that is passed as the init parameter.  This has the added bonus that entities that need to do a series of things AND set the CompanyId can just call the companyEntityInit function from inside their initializers.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;companyEntityInit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CompanyId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;CompanyId&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;metadataStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerEntityTypeCtor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;companyEntityInit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;metadataStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;registerEntityTypeCtor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Note&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;companyEntityInit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      

      <title>Burned by Ternary Operators</title>
      <link>https://hutchcodes.net/2013/09/burned-by-ternary-operators/</link>
      <pubDate>Mon, 16 Sep 2013 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2013/09/burned-by-ternary-operators/</guid>
      <description>&lt;p&gt;First let me say that I&amp;rsquo;m not a fan of ternary operators.&amp;nbsp; I try to avoid them because I feel that an explicit if/else is much more readable.&amp;nbsp; I do use them on occasion and this seemed like the perfect place for them.&lt;/p&gt;
&lt;p&gt;I ran into a interesting problem while trying to get a Linq where clause to work with ternary operators.&amp;nbsp; &lt;!--more--&gt; In hindsight the problem is pretty obvious, but it stumped me and one of my coworkers for a few minutes.&amp;nbsp; It wasn&amp;rsquo;t until we solved the problem in a different way that I realized what I had initially missed.&lt;/p&gt;
&lt;p&gt;First the setup:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;books&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Book&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Book&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;To Kill a Mockingbird&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Book&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Catcher in the Rye&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There where clause I was building was part of some basic search functionality.&amp;nbsp; It would take a passed in value and check to see if the Title or the Description contained that value:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToUpper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToUpper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Attempts to search for the letter T were returning no results.&amp;nbsp; Like I said, I struggled with it, called in a second set of eyes and they couldn&amp;rsquo;t see the problem.&amp;nbsp; We then re-wrote where clause like this:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToUpper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToUpper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This returned 2 results as expected.&amp;nbsp; After a bit of rumination I realized the problem was my lack of parentheses.&amp;nbsp; I thought I had written this:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToUpper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToUpper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When I had essentially written this:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; 
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToUpper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToUpper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;searchStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This was clearly just my misunderstanding of how ternary operators are interpreted, and I&amp;rsquo;m unlikely to ever forget this, but I&amp;rsquo;m also going to continue to avoid ternary operators wherever I can and encourage others to do the same.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      

      <title>Repository Pattern with Entity Framework</title>
      <link>https://hutchcodes.net/2013/09/repository-pattern-with-entity-framework/</link>
      <pubDate>Tue, 10 Sep 2013 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2013/09/repository-pattern-with-entity-framework/</guid>
      <description>&lt;p&gt;I’m currently working on a little side project using ASP.Net MVC and Entity Framework, so of course my urls looks something like &lt;a href=&quot;http://mysite.com/orders/14&quot;&gt;http://mysite.com/orders/14&lt;/a&gt; to pull up the order that has OrderId 14.  The problem of course is security, I need to ensure that users can only view their own orders.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;My first pass at managing this was to just add the UserId to the where clause of a LINQ query.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;dbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FirstOrDefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OrderId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UserId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This obviously works, but leaves me open making mistakes down the road by either forgetting to add that to the where clause, or on a more complex where clause having the UserId portion not working in one of the Or branches.  My first thought was of course to add some unit tests to the controller actions to account for this, but when I thought about doing that I realized I would essentially be writing the same test for every action.&lt;/p&gt;

&lt;p&gt;I decided I needed to move the responsibility for adding the UserId to the where clause to a central location that handled that for all calls to user specific entities.  I could then write unit tests that code once and rest assured that all my controller actions were covered for that case.&lt;/p&gt;

&lt;p&gt;My solution involved putting a generic repository layer on top of Entity Framework that was able to both.&lt;/p&gt;

&lt;p&gt;First I defined the repository interface:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;IQueryable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And an interface that all user specific entities must implement&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IUserEntity&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; 
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UserId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then the repository itself with methods for all CRUD operations.  You’ll notice that each operation checks to ensure that the UserId of the entity affected matches the UserId that was used to create the repository:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IUserEntity&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UserRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ArgumentNullException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dbContext&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DbSet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbSet&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IQueryable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UserId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FirstOrDefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UserId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UserId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DbEntityEntry&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbEntityEntry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbEntityEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EntityState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Detached&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;dbEntityEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EntityState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Added&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;DbSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UserId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;DbEntityEntry&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbEntityEntry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbEntityEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EntityState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Detached&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;DbSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Attach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dbEntityEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EntityState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Modified&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UserId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;DbEntityEntry&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbEntityEntry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dbEntityEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EntityState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Deleted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;dbEntityEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EntityState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Deleted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;DbSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Attach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;DbSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// not found; assume already deleted.&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UserId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next we wrap all of those repositories up in a Unit of Work pattern, (sample code only shows one repository, my production code has all my repositories in one UOW class).&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UoW&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDisposable&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyDbContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UoW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyDbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Orders&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_orders&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_orders&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UserRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now when we want all of the Order 14, we create an instance of the Unit Of Work class for the current user and request Order 14.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uow&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UoW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;uow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And if someone types &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://mysite.com/orders/14&lt;/code&gt; into the address bar, they won’t get back any data if their UserId doesn’t match the UserId for Order 14.&lt;/p&gt;

&lt;p&gt;It’s still not very testable, but all it takes is adding another constructor to allow us to pass in the DBContext:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UoW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyDbContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_userId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DbContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dbContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we can use any DBContext we like for testing.  I’m using &lt;a href=&quot;https://www.nuget.org/packages/Effort/&quot; target=&quot;_blank&quot;&gt;Effort - Entity Framework Unit Testing Tool&lt;/a&gt; to create an in memory database context for testing purposes.  It’s fast and simple to use.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>I&apos;m Back</title>
      <link>https://hutchcodes.net/2013/08/im-back/</link>
      <pubDate>Tue, 20 Aug 2013 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2013/08/im-back/</guid>
      <description>&lt;p&gt;After a long hiatus I&apos;m going to start blogging again.&lt;/p&gt;
&lt;p&gt;&quot;Where have you been?&quot; you might ask. &amp;nbsp;Well, I&apos;ve had a few big changes in my life this past year. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;First, I took a new job at &lt;a href=&quot;http://www.winxnet.com&quot; title=&quot;Winxnet&quot; target=&quot;_blank&quot;&gt;Winxnet&lt;/a&gt;, a software consulting and IT management company based in Portland, Maine. &amp;nbsp;It&apos;s been a big switch. &lt;!--more--&gt; &amp;nbsp;The first contract I was assigned to was an enormous&amp;nbsp;SharePoint&amp;nbsp;project. Being a WPF developer, the switch to web development really stretched me, and the Sharepoint part was just an extra wrench thrown in the works. &amp;nbsp;I was learning a lot of things that most web and/or SharePoint developers would probably consider pretty basic. &amp;nbsp;It&apos;s always fun getting stretched like that, but it left no time or energy for blogging.&lt;/p&gt;
&lt;p&gt;Second, in April my second child was born. &amp;nbsp;Anyone with kids knows that I get a free pass for a few months for that, no questions asked.&lt;/p&gt;
&lt;p&gt;Third, I&apos;ve started another side project (no public details yet). &amp;nbsp;This has eaten up a bunch of time the last couple of months, but it has also got my gears turning with ideas for blog posts.&lt;/p&gt;
&lt;p&gt;Oh, and one more thing. &amp;nbsp;My install of Wordpress died. &amp;nbsp;I can no longer log into the admin account. &amp;nbsp;Rather than spend the time trying to solve the underlying issue I thought I&apos;d check some other CMSs. &amp;nbsp;I&apos;ll be migrating my old posts over the next week, then I&apos;ll actually create a few new techy posts.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Productivity</category>
      
      

      <title>New Keyboard Layout Progress Update</title>
      <link>https://hutchcodes.net/2012/10/new-keyboard-layout-progress-update/</link>
      <pubDate>Thu, 18 Oct 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/10/new-keyboard-layout-progress-update/</guid>
      <description>&lt;p&gt;Back in June I decided to change my keyboard layout with the hopes of increasing my typing speed. I have touch typed for 20 years on a QWERTY keyboard and was getting about 54 words per minute. First I tries Dvorak layout, but had a tough time even learning the keyboard never mind typing with any speed. Then I switched to the Colemak layout which I was able to get some speed on very quickly.&lt;/p&gt;
&lt;!--more--&gt;

&lt;p&gt;I&amp;rsquo;m currently typing at 60 words a minute. That&amp;rsquo;s a 10% improvement, and I&amp;rsquo;m sure there is still some speed left to be gained, but I&amp;rsquo;m not sure I&amp;rsquo;ll ever make it to my original goal of doubling my typing speed. That would be 108 WPM, and at this point I&amp;rsquo;d be thrilled with 80 WPM.&lt;/p&gt;
&lt;p&gt;If I could go back, I&amp;rsquo;m not sure if I would switch again. More speed was my original goal, and I think I could have increased my speed faster if I had done as much practice with QWERTY as I have done with Colemak. But here I am, I have switched and I don&amp;rsquo;t think I&amp;rsquo;ll be going back.&lt;/p&gt;
&lt;p&gt;The Colemak layout is noticeably easier to type on. Much less reaching for common letters (I&amp;rsquo;m looking at you E, R and T). My typing hasn&amp;rsquo;t suffered too terribly on QWERTY keyboards, but I can no longer touch type, I have to watch the keyboard.&lt;/p&gt;
&lt;p&gt;Up next on my experiments with typing, mechanical keyboards. I have noticed in my practicing that there are times when I&amp;rsquo;m not sure whether I have typed a letter or not because of the mushy keys. I&amp;rsquo;ll monitor my WPM before and after that switch when I finally fork over the money for a &amp;gt;$100 keyboard.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>Career Goals</title>
      <link>https://hutchcodes.net/2012/09/career-goals/</link>
      <pubDate>Wed, 26 Sep 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/09/career-goals/</guid>
      <description>&lt;p&gt;I’ve had a few people ask me over the last few weeks what my long term career goals are. The first time someone asked me, it caught me a little off guard. It’s not a question I get asked a lot, and it’s not something I’ve really given any thought to in the last few years. My answer was that I didn’t have any career goals, that I was happy doing what I was doing.&lt;/p&gt;

&lt;p&gt;####So, do I really not have any career goals?
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;The more times I was asked about my career goals the more I became embarrassed by my answer. Why didn’t I have any career goals? Shouldn’t I have a goal? Without a goal aren’t I just drifting through life? Then it finally occurred to me, I do have a career goal. It just doesn’t involve moving up the corporate ladder. Or down, or across.&lt;/p&gt;

&lt;p&gt;My goals* are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Continue writing code&lt;/li&gt;
  &lt;li&gt;Continue learning and improving&lt;/li&gt;
  &lt;li&gt;Continue working with current technology&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If I stop with #2, then I’ve failed at #3 and should probably stop with #1 for the sake of anyone who might have to maintain my code.&lt;/p&gt;

&lt;p&gt;*I know these are not great goals as they are not measurable, but that’s as close as I can get to good goals for my career. If you have suggestions for how I might clarify them please leave a comment.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>Why I hate performing in front of friends and family*</title>
      <link>https://hutchcodes.net/2012/08/why-i-hate-performing-in-front-of-friends-and-family/</link>
      <pubDate>Tue, 28 Aug 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/08/why-i-hate-performing-in-front-of-friends-and-family/</guid>
      <description>&lt;p&gt;*Not a technical blog, you&amp;rsquo;ve been warned.&lt;/p&gt;
&lt;p&gt;Over this last weekend we had our neighborhood block party.&amp;nbsp; This year, my contribution was to plan the live music portion of the event.&amp;nbsp; For this I was able to get 2 solo acts and a 3 piece band to commit to playing for &quot;all the hot dogs they could eat.&quot;&amp;nbsp;&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;In the end one of the solo acts and the band couldn&amp;rsquo;t make it due to family emergencies.&amp;nbsp; To fill the gap I decided I&amp;rsquo;d play a few tunes even though I previously decided to leave myself out of the show.&amp;nbsp; I told myself it was because I hadn&amp;rsquo;t been practicing for a year of so, but there was more to it.&lt;/p&gt;
&lt;p&gt;I enjoy playing music.&amp;nbsp; I like going down to an open mic with some friends and belting out a couple of tunes, and I always had fun performing in the band I was in a few years back, but I was really dreading playing music for my neighbors.&amp;nbsp; It wasn&amp;rsquo;t the crowd, and it wasn&amp;rsquo;t my neighbors friends, it was my neighbors that I didn&amp;rsquo;t want to play in front of.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not that my neighbors are judgmental, mean, or anything like that.&amp;nbsp; Quite the opposite, they are all great people and&amp;nbsp; I knew the would be supportive even if I bombed.&amp;nbsp; I couldn&amp;rsquo;t ask for better neighbors.&lt;/p&gt;
&lt;p&gt;So why did I dread playing for them when I was perfectly comfortable going into a bar and playing for a bunch of strangers who always left an awkward silence where the polite applause are supposed to go?&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s 3 reasons I hate playing for friends and family:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I respect their opinions.&amp;nbsp; If I didn&amp;rsquo;t respect their opinions, they wouldn&amp;rsquo;t really be my friends would they.&lt;/li&gt;
&lt;li&gt;I don&amp;rsquo;t really trust their compliments.&amp;nbsp; I know that if I bomb they probably won&amp;rsquo;t tell me, they&amp;rsquo;ll focus on the positive unless I press them for an honest opinion.&amp;nbsp; I did that once, it confirmed what I already knew but it really sucked to hear it from someone I respected.&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;m going to see them again and again and again.&amp;nbsp; The nature of strangers is that you rarely, if ever, see them again.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So there it is, that&amp;rsquo;s why I hate performing for friends and family.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Productivity</category>
      
      

      <title>Keyboard Layout Comparison</title>
      <link>https://hutchcodes.net/2012/07/keyboard-layout-comparison/</link>
      <pubDate>Tue, 17 Jul 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/07/keyboard-layout-comparison/</guid>
      <description>&lt;p&gt;For the past few weeks I&amp;rsquo;ve experimented with alternate keyboard layouts with the long-term goal of increasing my typing speed.&lt;/p&gt;
&lt;p&gt;At first I tried Dvorak, which is the most popular alternative layout.&amp;nbsp; I found it cumbersome to learn.&amp;nbsp; Almost every key is in a new position.&amp;nbsp; After a couple of weeks of practice I had mostly memorized the layout, but was still only typing at 16 WPM.&lt;/p&gt;
&lt;p&gt;Then, while clearing out some bookmarks I found a link to the &lt;a href=&quot;http://colemak.com/&quot;&gt;Colemak&lt;/a&gt; layout.&lt;!--more--&gt; I&amp;rsquo;ve considered switching layouts for some time, so I wasn&amp;rsquo;t surprised to find the bookmark.&amp;nbsp; Like Dvorak, Colemak is designed for efficient and ergonomic touch typing in English.&amp;nbsp; Unlike Dvorak, it is based somewhat on the QWERTY keyboard.&amp;nbsp; Only 17 keys have moved.&amp;nbsp; The transition was easy.&amp;nbsp; I memorized the new layout in just a couple of days and was typing at 30+ WPM within a week.&amp;nbsp; I seem to have stalled, but I think the issue now is learning to type words (or letter combos) instead of typing letter by letter.&amp;nbsp; That&amp;rsquo;s something I expect will come with time.&lt;/p&gt;
&lt;p&gt;Here are my observation of the learning process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There is a noticeable difference in how much finger movement is required compared with QWERTY.&amp;nbsp; I hope this difference will result in more speed and comfort in the long run.&lt;/li&gt;
&lt;li&gt;I had no problems switching between layouts until I was above 25 WPM on Colemak, then I started to get confused when on QWERTY.&amp;nbsp; I switched to Colemak completely after I hit 30 WPM 2 days later.&lt;/li&gt;
&lt;li&gt;My speed at a typing test seemed slower than regular typing when I tested on QWERTY, but I definitely copy text faster in Colemak than I type my own thoughts.&amp;nbsp; This has improved since switching to Colemak full-time.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://play.typeracer.com/&quot;&gt;TypeRacer&lt;/a&gt; is a great place to practice.&amp;nbsp; You race others in short (&amp;lt;2 minute) races, and the quotes you type are at least somewhat interesting.&amp;nbsp; It also tracks and graphs your progress.&lt;/li&gt;
&lt;li&gt;Slow and accurate beats fast and inaccurate.&amp;nbsp; If you mistype, it takes 3 strokes to make a letter.&amp;nbsp; At 30 WPM you type 2.5 characters per second.&amp;nbsp; You are better off spending the time to type the right letter the first time.&lt;/li&gt;
&lt;li&gt;I don&amp;rsquo;t type as much as I thought.&amp;nbsp; With Visual Studio&amp;rsquo;s Intellisense I only type 1 or 2 letter then press Tab to complete for most things.&amp;nbsp; I honestly thought I typed more.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A really cool tool for &lt;a href=&quot;http://colemak.com/wiki/index.php?title=Compare&quot;&gt;comparing keyboard layouts&lt;/a&gt;.&amp;nbsp; It calculates the distance traveled, percentage home row and some other stats to help illuminate the differences between layouts.&lt;/p&gt;
&lt;p&gt;Stats for this post (except the grid):&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;QWERTY&lt;/td&gt;
&lt;td&gt;Colemak&lt;/td&gt;
&lt;td&gt;Dvorak&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distance&lt;/td&gt;
&lt;td bgcolor=&quot;#ff0000&quot;&gt;74.50m&lt;/td&gt;
&lt;td bgcolor=&quot;#00ff00&quot;&gt;38.16m&lt;/td&gt;
&lt;td bgcolor=&quot;#ffff00&quot;&gt;44.29m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same Hand&lt;/td&gt;
&lt;td bgcolor=&quot;#ff0000&quot;&gt;38.25%&lt;/td&gt;
&lt;td bgcolor=&quot;#ffff00&quot;&gt;32.45%&lt;/td&gt;
&lt;td bgcolor=&quot;#00ff00&quot;&gt;22.16%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same Finger&lt;/td&gt;
&lt;td bgcolor=&quot;#ff0000&quot;&gt;5.0%&lt;/td&gt;
&lt;td bgcolor=&quot;#00ff00&quot;&gt;1.333%&lt;/td&gt;
&lt;td bgcolor=&quot;#ffff00&quot;&gt;3.291%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top Row&lt;/td&gt;
&lt;td bgcolor=&quot;#ff0000&quot;&gt;52.70%&lt;/td&gt;
&lt;td bgcolor=&quot;#00ff00&quot;&gt;18.45%&lt;/td&gt;
&lt;td bgcolor=&quot;#ffff00&quot;&gt;24.95%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Home Row&lt;/td&gt;
&lt;td bgcolor=&quot;#ff0000&quot;&gt;28.86%&lt;/td&gt;
&lt;td bgcolor=&quot;#00ff00&quot;&gt;65.20%&lt;/td&gt;
&lt;td bgcolor=&quot;#ffff00&quot;&gt;61.07%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bottom Row&lt;/td&gt;
&lt;td bgcolor=&quot;#ff0000&quot;&gt;15.87%&lt;/td&gt;
&lt;td bgcolor=&quot;#ffff00&quot;&gt;11.91%&lt;/td&gt;
&lt;td bgcolor=&quot;#00ff00&quot;&gt;9.666%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;QWERTY is a clear loser here, its primary advantage is its monopoly.&amp;nbsp; The relative merits of Dvorak vs Colemak are debatable.&amp;nbsp; Are Colemak&amp;rsquo;s higher home row percentage and lower same finger percentage worth the trade for higher same hand and bottom row percentage?&amp;nbsp; Colemaks biggest advantage over Dvorak is the ease of learning if you are already proficient with QWERTY.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Productivity</category>
      
      

      <title>Changing Keyboard Layouts</title>
      <link>https://hutchcodes.net/2012/06/changing-keyboard-layouts/</link>
      <pubDate>Tue, 12 Jun 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/06/changing-keyboard-layouts/</guid>
      <description>&lt;p&gt;In my last &lt;a href=&quot;/2012/06/typing-speed/&quot;&gt;post&lt;/a&gt; I set a goal to switch to the Dvorak layout over the next few months and I&amp;rsquo;m looking to double my typing speed.&amp;nbsp; To do that, I am practicing typing on the Dvorak layout for a 10-15 minutes a day for a while and as my speed improves I&amp;rsquo;ll add time.&amp;nbsp; I&amp;rsquo;ve found that switching layouts is startlingly easy, so I thought I&amp;rsquo;d share how to do it (instructions are for Windows 7 and may vary for other versions).&lt;/p&gt;
&lt;!--more--&gt;

&lt;p&gt;Click Start and type &amp;ldquo;intl.cpl&amp;rdquo; into the search box.&amp;nbsp; This will bring up the Region and Language control panel.&amp;nbsp; Click on the Keyboards and Languages tab.&lt;/p&gt;
&lt;p&gt;&lt;img title=&quot;Capture1&quot; border=&quot;0&quot; alt=&quot;Capture1&quot; src=&quot;/wp-content/uploads/2012/06/Capture1_thumb.png&quot; width=&quot;330&quot; height=&quot;380&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Click Change Keyboards&lt;/p&gt;
&lt;p&gt;&lt;img title=&quot;Capture2&quot; border=&quot;0&quot; alt=&quot;Capture2&quot; src=&quot;/wp-content/uploads/2012/06/Capture2_thumb.png&quot; width=&quot;328&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Click Add and select the keyboards you want to add.&amp;nbsp; I just added United States-Dvorak.&lt;/p&gt;
&lt;p&gt;Go to the Advanced Key Settings&lt;/p&gt;
&lt;p&gt;&lt;img title=&quot;Capture3&quot; border=&quot;0&quot; alt=&quot;Capture3&quot; src=&quot;/wp-content/uploads/2012/06/Capture3_thumb.png&quot; width=&quot;328&quot; /&gt;&lt;/p&gt;
&lt;p&gt;From here you can assign Hot Keys to switch between layouts.&amp;nbsp; If you highlight the &amp;ldquo;Between input languages&amp;rdquo; and click the Change Key Sequence, you alter what key combinations cycle between languages and keyboard layouts.&amp;nbsp; I removed the cycle between languages because I only use US-English, and I assigned the Left Alt-Shift to cycle between keyboard layouts.&lt;/p&gt;
&lt;p&gt;&lt;img title=&quot;Capture4&quot; border=&quot;0&quot; alt=&quot;Capture4&quot; src=&quot;/wp-content/uploads/2012/06/Capture4_thumb.png&quot; width=&quot;320&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The last thing I did is back on the General tab, I went to the properties of the Dvorak keyboard and I changed the icon to a keyboard with a red border so that when my keyboard is in Dvorak mode the little Language Bar icon on the right side of the task bar is a read keyboard instead of the standard one.&lt;/p&gt;
&lt;p&gt;QWERTY&lt;/p&gt;
&lt;p&gt;&lt;img title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;/wp-content/uploads/2012/06/image_thumb.png&quot; width=&quot;43&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Dvorak&lt;/p&gt;
&lt;p&gt;&lt;img title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;/wp-content/uploads/2012/06/image_thumb1.png&quot; width=&quot;43&quot; /&gt;&lt;/p&gt;
&lt;p&gt;No for the best part, or worst part, I&amp;rsquo;m not entirely sure yet.&amp;nbsp; When you switch layouts, the switch only affects the app you were in when you switched layouts.&amp;nbsp; So, I can keep my browser in Dvorak for typing practice, but Outlook and Visual Studio stay in QWERTY.&amp;nbsp; I think this will come in handy in the long run as I can keep a say Outlook in Dvorak, and Visual Studio in QWERTY or vice versa depending on productivity.&amp;nbsp; Eventually I&amp;rsquo;ll switch the default&amp;hellip;&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Productivity</category>
      
      

      <title>Typing Speed</title>
      <link>https://hutchcodes.net/2012/06/typing-speed/</link>
      <pubDate>Thu, 07 Jun 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/06/typing-speed/</guid>
      <description>&lt;p&gt;So, I read one &lt;a href=&quot;http://steve-yegge.blogspot.de/2008/09/programmings-dirtiest-little-secret.html&quot;&gt;blog&lt;/a&gt; by Steve Yegge linked from &lt;a href=&quot;http://www.codeproject.com/&quot;&gt;CodePoject&lt;/a&gt; about typing speed (which is a great read if you have the time).&amp;nbsp; Then Steve Smith tweeted his blog &lt;a href=&quot;http://ardalis.com/Programming-is-Just-Typing#.T9CpRu3Pn6M.twitter&quot;&gt;post&lt;/a&gt; on the same subject, which was in response to Jeff Atwood&amp;rsquo;s &lt;a href=&quot;http://www.codinghorror.com/blog/2008/11/we-are-typists-first-programmers-second.html&quot;&gt;post&lt;/a&gt;.&amp;nbsp; Apparently all 3 articles are from 2008, but I read them like they were news today.&lt;/p&gt;
&lt;!--more--&gt;

&lt;p&gt;Was that enough name dropping?&lt;/p&gt;
&lt;p&gt;I read those 3 articles, and all 3 have the same premise.&amp;nbsp; You should be a fast efficient typist if you write code for a living.&amp;nbsp; They go almost as far as saying it&amp;rsquo;s the most important skill.&amp;nbsp; I don&amp;rsquo;t think that&amp;rsquo;s true, but being a better typist will most likely make you a better programmer.&amp;nbsp; If I code type as fast as I thought, I could either put out a bunch more code per day, or I could put out the same amount of code, just better thought out.&amp;nbsp; Or some combination in the middle &amp;ndash; a little more slightly better thought out code.&lt;/p&gt;
&lt;p&gt;They also linked to this &lt;a href=&quot;http://www.typeonline.co.uk/typingspeed.php&quot;&gt;typing speed test&lt;/a&gt;.&amp;nbsp; Steve Smith and Jeff Atwood were both in the mid 80&amp;prime;s and Steve Yegge claims 120 WPM.&amp;nbsp; I have no reason to doubt Mr. Yegge, but his measurement may be from typing his own thoughts whereas the rest of us used the typing speed test where you are copying text and I think there&amp;rsquo;s quite a difference.&amp;nbsp; I suspect Steve Smith and Jeff Atwood would easily put out 100+ WPM of their own thoughts.&lt;/p&gt;
&lt;p&gt;Of course I tested myself and came up ~55 WPM.&amp;nbsp; I did the test 3 times at 54, 56 and 54 WPM.&amp;nbsp; Each test had between 1 and 3 errors.&amp;nbsp; I was not impressed with my performance (partly why I took the test 3 times), so I&amp;rsquo;ve set a goal to double my speed on that test.&lt;/p&gt;
&lt;p&gt;My plan is this:&amp;nbsp; I&amp;rsquo;m going to switch to Dvorak layout for ~10-15 minutes a day and practice with some sort of online typing tutor.&amp;nbsp; Once I have the keyboard memorized and I&amp;rsquo;m typing &amp;gt;30 WPM, I&amp;rsquo;m going to add a few hours a day in Dvorak, the rest in Qwerty.&amp;nbsp; Once I hit &amp;gt;50 WPM, I&amp;rsquo;ll switch to full-time Dvorak, and continue with the typing tutors for the 10-15 minutes per day until I reach 110 WPM.&lt;/p&gt;
&lt;p&gt;Through this I&amp;rsquo;m going to try to update here every week or two to report progress.&lt;/p&gt;

&lt;p&gt;—excerpt—&lt;/p&gt;

&lt;p&gt;So, I read one &lt;a href=&quot;http://steve-yegge.blogspot.de/2008/09/programmings-dirtiest-little-secret.html&quot;&gt;blog&lt;/a&gt; by Steve Yegge linked from &lt;a href=&quot;http://www.codeproject.com/&quot;&gt;CodePoject&lt;/a&gt; about typing speed (which is a great read if you have the time).&amp;nbsp; Then Steve Smith tweeted his blog &lt;a href=&quot;http://ardalis.com/Programming-is-Just-Typing#.T9CpRu3Pn6M.twitter&quot;&gt;post&lt;/a&gt; on the same subject, which was in response to Jeff Atwood&amp;rsquo;s &lt;a href=&quot;http://www.codinghorror.com/blog/2008/11/we-are-typists-first-programmers-second.html&quot;&gt;post&lt;/a&gt;.&amp;nbsp; Apparently all 3 articles are from 2008, but I read them like they were news today.
&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>WPF Xaml</category>
      
      

      <title>Using a different DataTemplate when a WPF ComboBox is expanded</title>
      <link>https://hutchcodes.net/2012/06/using-a-different-datatemplate-when-a-wpf-combobox-is-expanded/</link>
      <pubDate>Tue, 05 Jun 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/06/using-a-different-datatemplate-when-a-wpf-combobox-is-expanded/</guid>
      <description>&lt;p&gt;A quick post showing how to create a combo box that shows a single line, shows multiple lines when expanded. Obviously you can extend this to show any two datatemplates for collapsed and expanded.&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;ComboBoxExample&quot; src=&quot;http://www.codeproject.com/KB/WPF/WPF_Combobox_Datatemplate/ComboExample.PNG&quot; /&gt;
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;The first thing I did was create the data templates that control how the address is going be displayed. When it’s collapsed, I just wanted to show the &lt;em&gt;AddressName&lt;/em&gt; and &lt;em&gt;AddressType&lt;/em&gt; on one line:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;DataTemplate&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;x:Key=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;AddressComboCollapsed&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;StackPanel&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Width=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;150&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;HorizontalAlignment=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Stretch&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;DockPanel&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;HorizontalAlignment=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Stretch&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Path=AddressName}&quot;&lt;/span&gt; 
                       &lt;span class=&quot;na&quot;&gt;DockPanel.Dock=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Left&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Path=AddressType}&quot;&lt;/span&gt; 
                       &lt;span class=&quot;na&quot;&gt;DockPanel.Dock=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Right&quot;&lt;/span&gt;
                       &lt;span class=&quot;na&quot;&gt;HorizontalAlignment=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Right&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/DockPanel&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/StackPanel&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/DataTemplate&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When it’s expanded, I want to show the whole address and suppress AddressLine2 if it’s blank:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;DataTemplatea&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;x:Key=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;AddressComboExpanded&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;GroupBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;BorderThickness =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;Margin =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;0,0,0,3&quot;&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;Width =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Auto &quot;&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;HorizontalAlignment =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Stretch&quot;&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;Header =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{Binding Path=AddressType}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;StackPanel&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Margin=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;3&quot;&lt;/span&gt; 
                    &lt;span class=&quot;na&quot;&gt;HorizontalAlignment=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Stretch&quot;&lt;/span&gt;
                    &lt;span class=&quot;na&quot;&gt;MinWidth=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;250&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{Binding Path=AddressName}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

            &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{Binding Path=AddressLine1}&quot;&lt;/span&gt;
                       &lt;span class=&quot;na&quot;&gt;Name =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tbAddr1&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{Binding Path=AddressLine2}&quot;&lt;/span&gt;
                       &lt;span class=&quot;na&quot;&gt;Name =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tbAddr2&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

            &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- City, State, and ZIP display --&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;StackPanel&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Orientation =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Horizontal&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{Binding Path=City}&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;,&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Padding=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0,0,5,0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Put a comma between city and state --&amp;gt;&lt;/span&gt;

                &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{Binding Path=State}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Padding=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0,0,5,0&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{Binding Path=PostalCode}&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/StackPanel&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/StackPanel&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/GroupBox&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;DataTemplate.Triggers&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;&amp;lt;!--If the &quot;AddressLine2&quot; portion of the address is blank, then
            HIDE it (no need to display an extra blank line)
            
            This only works is AddressLine2 = &quot;&quot;, not if it&apos;s null
        --&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;DataTrigger&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Binding =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{Binding Path=AddressLine2}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Value =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;TargetName =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;tbAddr2&quot;&lt;/span&gt; 
                    &lt;span class=&quot;na&quot;&gt;Property =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Visibility&quot;&lt;/span&gt; 
                    &lt;span class=&quot;na&quot;&gt;Value =&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Collapsed&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/DataTrigger&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/DataTemplate.Triggers&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/DataTemplate&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The next step was to create a &lt;em&gt;AddressTemplateSelector&lt;/em&gt; class that inherits from &lt;em&gt;System.Windows.Controls.DataTemplateSelector.DataTemplateSelector&lt;/em&gt;, and override the &lt;em&gt;SelectTemplate&lt;/em&gt; method.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AddressTemplateSelector&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Windows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Controls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataTemplateSelector&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataTemplate&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SelectTemplate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DependencyObject&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ContentPresenter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;presenter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ContentPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;presenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TemplatedParent&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ComboBox&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataTemplate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;presenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;AddressComboCollapsed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Templated parent is ComboBoxItem&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataTemplate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;presenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;AddressComboExpanded&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After that, it’s just a matter of importing the namespace of the &lt;code&gt;DataTemplateSelector&lt;/code&gt; into the Window, merging the Resource Dictionary that contains the DataTemplates, and setting the &lt;em&gt;ItemTemplateSelector&lt;/em&gt; of the &lt;em&gt;ComboBox&lt;/em&gt;.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ComboBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Height=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;30&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Width=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;200&quot;&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;ItemsSource=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Path=Addresses}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;ComboBox.ItemTemplateSelector&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;dt:AddressTemplateSelector/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/ComboBox.ItemTemplateSelector&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ComboBox&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4&gt;Point of Interest&lt;/h4&gt;
&lt;p&gt;If you look closely at the templates, you’ll notice that the expanded template is wider than both the combobox and the collapsed template. This allows you to have the list be wider than the original combobox. That’ll be a nice feature when I move on to the state selection combo (display only StateCode, but show StateCode + StateName when expanded).&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      <category>Mobile</category>
      
      

      <title>WP7 Application Capabilities</title>
      <link>https://hutchcodes.net/2012/06/wp7-application-capabilities/</link>
      <pubDate>Mon, 04 Jun 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/06/wp7-application-capabilities/</guid>
      <description>&lt;p&gt;&lt;a href=&quot;http://wmpoweruser.com/95-of-wp7-apps-can-access-the-internet-13-can-make-calls-and-16-can-track-you/&quot; target=&quot;_blank&quot;&gt;WMPoserUser&lt;/a&gt; posted some interesting stats on what capabilities applications are requesting.&amp;nbsp; Interesting stuff, but they clearly haven&amp;rsquo;t published an app, or at least not an ad supported app.&lt;/p&gt;
&lt;p&gt;First let me say that I have only published a single app so far, so I&amp;rsquo;m not some amazing expert.&amp;nbsp; My app, &lt;a href=&quot;http://www.windowsphone.com/en-US/apps/225f7d20-6067-49ee-9142-b4b89658b4b2?wa=wsignin1.0&quot;&gt;Chess Tactics&lt;/a&gt;, doesn&amp;rsquo;t actually need any capabilities by itself.&amp;nbsp; That being said I have quite a few capabilities listed.&amp;nbsp; Most of these capabilities are required by Microsoft&lt;!--more--&gt;&amp;rsquo;s ad control, with one additional capability required by &lt;a href=&quot;http://mtiks.com/&quot;&gt;MTIKS&lt;/a&gt; (a utility I&amp;rsquo;m using usage and error detail).&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s my capabilities list and why I include it and why I think it&amp;rsquo;s required:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Phone Dialer
&lt;ul&gt;
&lt;li&gt;MS Ad Control &amp;ndash; so you can dial a phone number direct from an advertisement&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Networking
&lt;ul&gt;
&lt;li&gt;MS Ad Control &amp;ndash; to download ads for display and report any clicks&lt;/li&gt;
&lt;li&gt;MTIKS &amp;ndash; Send data back for reporting&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Web Browser
&lt;ul&gt;
&lt;li&gt;MS Ad Control &amp;ndash; to display the ads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;User Identity
&lt;ul&gt;
&lt;li&gt;MS Ad Control &amp;ndash; to track what the users interests are across apps&lt;/li&gt;
&lt;li&gt;MTIKS &amp;ndash; Track user loyalty across app versions and user device upgrades&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Media Library
&lt;ul&gt;
&lt;li&gt;MS Ad Control &amp;ndash; No idea at all&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Device Identity
&lt;ul&gt;
&lt;li&gt;MTIKS &amp;ndash; To track what devices are using my app in case a particular one become problematic&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of these capabilities indicate an app is trying to do anything nefarious.&amp;nbsp; I would expect pretty much every app to need these capabilities.&amp;nbsp; Now if an app wants access to my microphone, it better have a damned good reason.&lt;/p&gt;
&lt;p&gt;Between collecting stats, serving ads, and apps that use network service to provide value, I think it&amp;rsquo;s out of line to say that 95% requesting network services is &amp;ldquo;larger than necessary&amp;rdquo;.&amp;nbsp; In fact, it makes me wonder what the 5% of apps that don&amp;rsquo;t require network access are.&lt;/p&gt;
&lt;p&gt;If you know why the MS ad control needs access to the Media Library please let me know in the comments.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>How I got started as a developer</title>
      <link>https://hutchcodes.net/2012/05/how-i-got-started-as-a-developer/</link>
      <pubDate>Wed, 30 May 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/05/how-i-got-started-as-a-developer/</guid>
      <description>&lt;p&gt;A response to a &lt;a href=&quot;http://www.hanselman.com/blog/SheLetMeTakeTheComputerHomeHowDidYouGetStartedInComputersAndProgramming.aspx&quot;&gt;request&lt;/a&gt; for everyone to share how they got started down the road to become software developer.&lt;/p&gt;
&lt;p&gt;I wrote my first code on a &lt;a href=&quot;http://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=2&amp;amp;ved=0CF4QFjAB&amp;amp;url=http%3A%2F%2Foldcomputers.net%2Fkayproii.html&amp;amp;ei=yQjGT-qXB4Sc8gTdo_WwBg&amp;amp;usg=AFQjCNEMyF_ZnxtbNnnW-XZqyMNydNtbYA&amp;amp;sig2=yQaiaF0Ohggcb2ZshkDElA&quot;&gt;Kaypro II&lt;/a&gt;.&amp;nbsp; My mother bought it around 1987, and there were 2 things you could do on it.&amp;nbsp; You could use the word processor (I think it was WordStar) or you could program in some variant of BASIC.&amp;nbsp; I did a little of both.&lt;/p&gt;
&lt;!--more--&gt;

&lt;p&gt;My mother had a handful of programming books left over from getting her Associates degree a few years earlier, and I would copy some of the sample applications, or try to do some of the problems in some of the chapters.&amp;nbsp; Between the things the books left out and the bugs I added while hunting and pecking the code into the computer I had plenty of debugging to do.&amp;nbsp; In some ways I wish I had some of that code, but mostly I&amp;rsquo;m glad the evidence has been destroyed.&lt;/p&gt;
&lt;p&gt;Next my mother bought an IBM pc running Windows.&amp;nbsp; My recollection was 3.1, but I&amp;rsquo;m almost certain I got it before 1992 so who knows?&amp;nbsp; I don&amp;rsquo;t remember how much ram it had, maybe a couple of MB?&amp;nbsp; I do remember the disk was 25mb.&lt;/p&gt;
&lt;p&gt;The first challenge with that was to try to get this one flight simulator running on it.&amp;nbsp; I spent weeks modifying the autoexec.bat and config.sys on a boot disk to loaded the absolute bare minimum into memory and get every configured just right to be able that flight sim.&amp;nbsp; Then I spent countless hours playing purchased and/or pirated games and playing in Q-Basic.&lt;/p&gt;
&lt;p&gt;Around that same time I got a programmable calculator for my high school math class.&amp;nbsp; I started writing programs to do the math problems for me.&amp;nbsp; I still had to show the work, but I could be certain the answer was correct.&amp;nbsp; I also created a simple black jack game and a two player howitzer game with random landscape and wind.&lt;/p&gt;
&lt;p&gt;All that and I chose sports medicine as my major in college?&amp;nbsp; Yup.&amp;nbsp; How I got from sport medicine back to software development would be a whole post in itself.&lt;/p&gt;
&lt;p&gt;So really, it was my Mom who got me started down this path.&amp;nbsp; She not only bought the computers, but she taught me how to debug.&amp;nbsp; How to work through the problems.&amp;nbsp; How to go step by step until you see where things where things go wrong.&amp;nbsp; Skills I still use every day.&lt;/p&gt;
&lt;p&gt;Thanks Mom.&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s your story?&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      <category>T4</category>
      
      

      <title>T4 Generated Wrapper for a WCF Client</title>
      <link>https://hutchcodes.net/2012/05/t4-generated-wrapper-for-a-wcf-client/</link>
      <pubDate>Thu, 24 May 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/05/t4-generated-wrapper-for-a-wcf-client/</guid>
      <description>&lt;h3&gt;Background&lt;/h3&gt;
&lt;p&gt;The idea for this article came from two places:&lt;/p&gt;

&lt;p&gt;I’m writing an application that gets all of its data from a WCF service. Each time I call the WCF service, I end up having to write a bunch of duplicate code and of course I don’t like to type, so I was trying to find a way to not have to write that code.&lt;/p&gt;

&lt;p&gt;The app I’m developing is an internal business application, and we release weekly. Each release to the WCF services could be incompatible with the previous client. That means that I need to do the release during off hours. I don’t like working nights, so I wanted to find a way to have multiple copies of the service running and have the client choose which service to access based on its version&lt;!--more--&gt;, but I didn’t want to have to keep changing the config file for the client with each release.
First I’ll solve those two problems, and then I’ll demonstrate how to use T4 to generate this wrapper from the WCF service reference.&lt;/p&gt;
&lt;h3&gt;Prerequisites&lt;/h3&gt;
&lt;p&gt;To run the code, you’ll need to download and install the &lt;a href=&quot;http://t4toolbox.codeplex.com/&quot; target=&quot;_blank&quot;&gt;T4Toolbox&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Problem #1&lt;/h4&gt;
&lt;p&gt;A typical WCF call looks like this:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WCFServiceWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WcfSvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Service1Client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;returnValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Abort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Proxy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To keep from having to write all that code every time I make a call to the WCF service, I created a &lt;em&gt;static class&lt;/em&gt; that has a &lt;em&gt;static&lt;/em&gt; method with the same signature as the WCF method I’m calling.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SvcWrapper&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;   
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetServiceClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returnValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returnValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Abort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that same call that took 12 lines of code is now just this one line:&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;returnValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SvcWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4&gt;Problem #2&lt;/h4&gt;
&lt;p&gt;To solve the second problem, I just added another method that creates an instance of the service client for me.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SvcWrapper&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_serviceAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_configName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_needsConfig&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WcfSvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Service1Client&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetServiceClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_needsConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//At this point I&apos;d do some hoopajoop to determine what the&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//current service address is for this version&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//something like:&lt;/span&gt;
  
            &lt;span class=&quot;c1&quot;&gt;//ServiceConfig config = SomeWCFService.GetServiceConfig(versionNo);&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//_serviceAddress = config.Address;&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//_configName = config.ClientEndPointName;&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//The address of the service endpoint&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_serviceAddress&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;http://localhost:50324/Service1.svc&quot;&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;//This string is the Name of the Client Endpoint&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;//as defined in the running EXE&apos;s app.config&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_configName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;WSHttpBinding_IService1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WCFServiceWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WcfSvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Service1Client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_configName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_serviceAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There’s nothing earth shattering about that code, and I haven’t even implemented the look of the address and config yet, but the shell is there for me to finish at a later date. But now if I want to add another endpoint configuration to the &lt;em&gt;app.config&lt;/em&gt; file for this service, I can do that and have only one place to change which endpoint the app uses.&lt;/p&gt;
&lt;h3&gt;Using T4 to Generate Wrapper Methods&lt;/h3&gt;
&lt;p&gt;Now, I’ve solved my original 2 problems, but I’ve created another one. I’m going to have to create and maintain a wrapper method for every method exposed by the WCF Service. This is the perfect opportunity to do a little code generation with T4.&lt;/p&gt;

&lt;p&gt;First thing you need to do is add references to the EnvDTE and T4ToolBox. Then add a new text file called &lt;em&gt;GenerateServiceWrapper.t4&lt;/em&gt;. This file holds the code that is not specific to the service we’re wrapping, and the t4 extension doesn’t create the child &lt;em&gt;.cs&lt;/em&gt; file that the .tt extension creates.&lt;/p&gt;

&lt;p&gt;This file has 5 methods:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;GetServiceInterface&lt;/em&gt; – takes the name of the service and searches the project for a file that matches. Then it calls &lt;em&gt;FindInterface&lt;/em&gt;.
&lt;em&gt;FindInterface&lt;/em&gt; – takes a project item and searches it for an interface. It returns the first one it finds, and nullif it doesn’t find one. It could maybe use some error handling but…
&lt;em&gt;GetMethodSignature&lt;/em&gt; – this takes one of the &lt;em&gt;public&lt;/em&gt; methods found on the interface and returns a string that will be the method signature of the wrapper method.
&lt;em&gt;GetMethodCall&lt;/em&gt; – this takes one of the &lt;em&gt;public&lt;/em&gt; methods found on the interface and returns a string that will be the call to that method on the WCF Service.
&lt;em&gt;GetServiceWrapper&lt;/em&gt; – is where the rubber meets the road. This calls &lt;em&gt;GetServiceInterface&lt;/em&gt; to get the interface, loops through the public methods and generates the wrapper methods.
Here’s the contents of that file, you’ll need to get a third-party plugin to get syntax highlighting in Visual Studio.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#@&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Template&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;C#&quot;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#@&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;=&quot;&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;EnvDTE&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; #&amp;gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#@&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;T4Toolbox.tt&quot;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;+&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetServiceWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LocalServiceName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;EnvDTE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodeInterface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svcInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;GetServiceInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LocalServiceName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;@&quot;reference.cs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ce&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svcInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Members&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;meth&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ce&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CodeFunction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meth&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Access&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vsCMAccess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vsCMAccessPublic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetMethodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;methodCall&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetMethodCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returnsVoid&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AsString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Equals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;void&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;returnsVoid&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetServiceClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;+&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;returnsVoid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                       &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;methodCall&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;;&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;+&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returnValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;methodCall&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returnValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;+&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Abort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
         
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;+&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EnvDTE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodeInterface&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetServiceInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interfaceFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ProjectItem&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectItem&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TransformationContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FindProjectItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interfaceFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FileCodeModel&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codeModel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;projectItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileCodeModel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FindInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codeModel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodeElements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CodeInterface&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FindInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodeElements&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodeElement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;CodeInterface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CodeInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;myInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FindInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myInterface&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetMethodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodeFunction&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;StringBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;public static &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AsString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;(&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isFirstParameter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prm&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;CodeParameter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prm&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CodeParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isFirstParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;, &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;isFirstParameter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AsString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;methodSignature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetMethodCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CodeFunction&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;methodCall&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;StringBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;methodCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;methodCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;(&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isFirstParameter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prm&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;CodeParameter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prm&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CodeParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isFirstParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;methodCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;, &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;isFirstParameter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;methodCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;methodCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;methodCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;      
&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Lastly create a text file named &lt;em&gt;ServiceWrapper.tt&lt;/em&gt;, or something less generic as this will define the actual wrapper for the WCF Service.&lt;/p&gt;

&lt;p&gt;It contains a link to our &lt;em&gt;GenerateServiceWrapper.t4&lt;/em&gt; file, the definition of our class, and a call to &lt;em&gt;GetServiceWrapper&lt;/em&gt; to which we pass the name of the WCF Service Reference.&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#@&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;template&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;C#v3.5&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hostspecific&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;True&quot;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#@&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;T4TemplatesGenerateServiceWrapper.t4&quot;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;WCFServiceWrapper&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SvcWrapper&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;   
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;      &lt;span class=&quot;nf&quot;&gt;GetServiceWrapper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;WcfSvc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once you save, it should generate a &lt;em&gt;SvcWrapper.cs&lt;/em&gt; file with &lt;em&gt;static&lt;/em&gt; methods to wrap all of your calls. Now if I want to do something like add logging to each WCF call, all I have to do is add that code to the &lt;em&gt;GetServiceWrapper&lt;/em&gt; method in the &lt;em&gt;GenerateService.t4&lt;/em&gt; file, poof all my methods WCF calls are logged.&lt;/p&gt;

&lt;p&gt;Notice that I created this class as a partial class, this allows us to put the &lt;em&gt;GetServiceClient&lt;/em&gt; method in the same class, but in a separate file. We could have either created that method in a completely separate class, or within the &lt;em&gt;ServiceWrapper.tt&lt;/em&gt; file. You never want to edit the generated file, as those edits will be overwritten.&lt;/p&gt;

&lt;h3&gt;Points of Interest&lt;/h3&gt;
&lt;p&gt;Syntax highlight for T4 requires a 3rd party plugin. I’ve tried a few, and they are all pretty weak.&lt;/p&gt;

&lt;p&gt;You can’t step through T4 code (or I haven’t figured out how), so it can take some serious guess and check to figure out what’s going wrong when something goes wrong. The output window is your friend.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>App Reviews</title>
      <link>https://hutchcodes.net/2012/05/app-reviews/</link>
      <pubDate>Tue, 22 May 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/05/app-reviews/</guid>
      <description>&lt;p&gt;A quick word about app reviews:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Most people don&amp;rsquo;t review. &amp;nbsp;I average about 1000 ad impressions a day. &amp;nbsp;In other words users are playing 1000 minutes a day. &amp;nbsp;So there are people who are using Chess Tactics but are not reviewing it. &amp;nbsp;There have been about 1500 downloads, and only 8 reviews in the US.&lt;/li&gt;
&lt;li&gt;Most reviews are not that helpful. &amp;nbsp;I have a handful of reviews that are on the low-end with no indication about what they don&amp;rsquo;t like. &amp;nbsp;Either they left it blank &lt;!--more--&gt;or just state they didn&amp;rsquo;t like it. &amp;nbsp;One Australian rated it a 1 star and commented that he wished he could give it zero stars.&lt;/li&gt;
&lt;li&gt;Fixing complaints doesn&amp;rsquo;t necessarily raise your rating. &amp;nbsp;There were a couple of reviews that complained about having time factored into the scoring. &amp;nbsp;I put out an update that allowed them the option to remove the time factor from the scoring. &amp;nbsp;One reviewer did re-rate the app, but they left the negative part of the review, and just added that it was fixed at the end. &amp;nbsp;The other reviewer hasn&amp;rsquo;t changed his rating yet.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s hard not to take it personally. &amp;nbsp;I worked hard on the app in my and the negative feedback is frustrating. &amp;nbsp;I just have to keep in mind that even wildly successful products have a handful of people who think it&amp;rsquo;s crap. &amp;nbsp;Just take a look at the review for any product on Amazon.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What I really wish was available through the review system was a way to reach out to those who did review the app, or respond to reviews. &amp;nbsp;How nice would it be to attach a comment to a low review that disliked the time factor is scoring to let them and the world know that I took their feedback and fixed their issue. &amp;nbsp;Or maybe it would be nice to email the user, but I understand that could open up an opportunity for abusing negative voters.&lt;/p&gt;
&lt;p&gt;I did include a feedback email address in my app, and I have received responses from 2 users. &amp;nbsp;One had a question about a particular problem, and the other suggested an option to keep the phone from sleeping (coming next release). &amp;nbsp;I really enjoyed those interactions, and I hope there are more.&lt;/p&gt;
&lt;p&gt;Finally, I hope this experience changes the way I review apps and give feedback. &amp;nbsp;If it&amp;rsquo;s at all possible I will give specific feedback in the review. &amp;nbsp;I&amp;rsquo;ll also try to follow-up with an email so they can let me know if they change what I didn&amp;rsquo;t like about an app, so that I can adjust my review.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>Minimum Requirements</title>
      <link>https://hutchcodes.net/2012/05/minimum-requirements/</link>
      <pubDate>Sun, 20 May 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/05/minimum-requirements/</guid>
      <description>&lt;p&gt;The Visual Studio team just &lt;a href=&quot;http://blogs.msdn.com/b/visualstudio/archive/2012/05/18/a-look-ahead-at-the-visual-studio-11-product-lineup-and-platform-support.aspx&quot; target=&quot;_blank&quot;&gt;announced&lt;/a&gt; that the Visual Studio 11 will have the same hardware requirements as Visual Studio 2010. &amp;nbsp;So, we&amp;rsquo;re getting more features, they&amp;rsquo;ve improved the performance throughout (yes, I am using it and the differences are obvious in places), and we could run it on yesterdays hardware, but we&amp;rsquo;re likely to have upgraded since then so faster still.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;This seems to be a trend at Microsoft, or at least I hope it is. &amp;nbsp;Earlier this year (or was it at Build last September) they announced that they had improved the performance and memory usage in Window 8 to the point where it was faster than Windows 7, used less memory and that the minimum requirements wouldn&amp;rsquo;t change from the Windows 7 minimums.&lt;/p&gt;
&lt;p&gt;For so many years improvements in hardware were negated by bloat in software. &amp;nbsp;If this trend continues we should be computing noticeably faster in a few years. &amp;nbsp;Combine that with Microsoft&amp;rsquo;s push around asynchronous programming and the user experience a few years from now could be vastly better than it is today.&lt;/p&gt;
&lt;p&gt;Of course Microsoft can only do so much, it&amp;rsquo;s now up to the world 3rd party and in-house developers to take up the challenge and write software that uses less memory, performs better and runs all long running processes asynchronously. &amp;nbsp;Microsoft targeted processes that take longer than 50 ms, I might raise my target a bit above that, but I am accepting the challenge.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Mobile</category>
      
      

      <title>Mobile Analytics</title>
      <link>https://hutchcodes.net/2012/05/mobile-analytics/</link>
      <pubDate>Sat, 12 May 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/05/mobile-analytics/</guid>
      <description>&lt;p&gt;In my previous &lt;a href=&quot;https://hutchcodes.net/2012/05/microsofts-app-reporting/&quot; target=&quot;_blank&quot;&gt;post&lt;/a&gt; I complained about the 6 day delay in getting download number from Microsoft. &amp;nbsp;Since then I have done a little bit of research into other ways of getting that information in a more timely manner. &amp;nbsp;I found two good options &lt;a href=&quot;http://mtiks.com/&quot; target=&quot;_blank&quot;&gt;MTIKS&lt;/a&gt; and &lt;a href=&quot;http://www.flurry.com/&quot; target=&quot;_blank&quot;&gt;Flurry&lt;/a&gt;. &amp;nbsp;They both provide much more information than I was looking for from Microsoft, and I will be using one or the other unless I find something better.&lt;/p&gt;
&lt;!--more--&gt;

&lt;p&gt;They are both very easy to use. &amp;nbsp;All you need to do is add a reference to their dll, then add one line of code to Application_Launching and Application_Activated to tell them to start a session, and another line to Application_Deactivated and Application_Closing to tell them to end the session.&lt;/p&gt;
&lt;p&gt;They both also allow you to report exceptions and events. &amp;nbsp;This would allow me to see how many problems users are playing, or what percentage of users turn off time based scoring in Chess Tactics.&lt;/p&gt;
&lt;p&gt;Of course each has their strength and weakness.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MTIKS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MTIKS biggest strength is that it can detect pirated apps so you can see how big of a problem pirated apps are for you. &amp;nbsp;My apps are all free at this point, so I&amp;rsquo;m not worried about pirates, and this feature isn&amp;rsquo;t a great selling point for me.&lt;/p&gt;
&lt;p&gt;The other thing I really like about MTIKS was that it was real time (or very close to it). &amp;nbsp;I could start up a session in the emulator, click refresh on their site and see the session.&lt;/p&gt;
&lt;p&gt;The one problem I did see with MTIKS is in their exception handling. &amp;nbsp;The stack trace gets overwritten if you log the error for Application_UnhandledException. &amp;nbsp;I contacted them about this and they responded quickly and are looking into the problem. &amp;nbsp;I&amp;rsquo;ll update this when they fix it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flurry&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Flurry looks like it does a great job on the reporting side. &amp;nbsp;They allow you to compare your app to the aggregate data of other apps collecting the same info. &amp;nbsp;It lets you segment your reporting based on your users age, gender, language, location and even custom events (user who clicked the review this app button for example). &amp;nbsp;If you&amp;rsquo;re not collecting this information, Flurry will make some estimates for you.&lt;/p&gt;
&lt;p&gt;The downside here is that Flurry runs on a about a 1 hour delay. &amp;nbsp;I of course would prefer instant gratification, but 1 hour isn&amp;rsquo;t too long to wait. &amp;nbsp;Right now I&amp;rsquo;m facing a 6 day delay in download numbers and a 3 day delay in exception reporting, so one hour seems totally resonable.&lt;/p&gt;
</description>
    </item>
    
    <item>
      
      <category>Mobile</category>
      
      

      <title>Microsoft’s App Reporting</title>
      <link>https://hutchcodes.net/2012/05/microsofts-app-reporting/</link>
      <pubDate>Thu, 10 May 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/05/microsofts-app-reporting/</guid>
      <description>&lt;p&gt;Warning, this is going to be a bit of a rant, but it’s been driving me crazy for a little while.&lt;/p&gt;

&lt;p&gt;If you’re following along (and chances are no one is) you know that I recently released my first &lt;a href=&quot;http://www.windowsphone.com/en-US/apps/225f7d20-6067-49ee-9142-b4b89658b4b2?wa=wsignin1.0&quot; title=&quot;Chess Tactics&quot; target=&quot;_blank&quot;&gt;app&lt;/a&gt; for Windows Phone.  Since then, I have been following the apps progress in downloads and ad revenue through Microsoft’s provided reporting tools on both PubCenter and AppHub.  The reports are pretty decent for the most part, and give me the data I’m looking for except for 1 things.  The lag in data.
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;The data for ad revenue is delayed by 3-6 hours (I’ve seen as much as 12 hours).  It drove me crazy when I first released the app because it was the only data I could get.   I’ve made my peace with this and I now only check the previous day’s total, and I don’t do that every day.&lt;/p&gt;

&lt;p&gt;The delay that really grinds my gears is the downloads number in the AppHub.  That number is &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/hh334582(v=vs.92).aspx&quot; target=&quot;_blank&quot;&gt;delayed 6 days&lt;/a&gt;.  There reasoning?  That’s how long it takes to process credit card transactions.&lt;/p&gt;

&lt;p&gt;Wait, I wasn’t reporting on number of sales, I was reporting on number of downloads.  People can download my app for free, other apps have a trial period.  Why are the download numbers for those being delayed?  If your app is trial/buy, the report doesn’t give you an accurate reflection of sales, nor does it give you an up to date number of downloads.&lt;/p&gt;

&lt;p&gt;I suggest this:  Allow us to view reports of downloads and trials in a much more up to date fashion.  A 1 day delay at most.  And have another option to view the number of sales which would be delayed by the 6 days it takes to process a credit card.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>C#</category>
      
      

      <title>401 Unauthorized error on MERGE operations IIS 7 with WCF Data Service</title>
      <link>https://hutchcodes.net/2012/04/401-unauthorized-error-on-merge-operations-iis-7-with-wcf-data-service/</link>
      <pubDate>Mon, 30 Apr 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/04/401-unauthorized-error-on-merge-operations-iis-7-with-wcf-data-service/</guid>
      <description>&lt;p&gt;I was getting this error when using WCF Data Services and trying to save an update to an object. &amp;nbsp;After quite a bit of googling, I found a work around that I didn&amp;rsquo;t like. &amp;nbsp;Allow the users write access to the .svc file.&lt;/p&gt;
&lt;p&gt;I have a hard time believing that anyone would accept &amp;ldquo;allow the user write access to the file&amp;rdquo; as an answer in web situation. &amp;nbsp;In my case I was able to use that as a temporary fix because the website in question was internal and behind a firewall, but I knew there had to be a better answer.&lt;/p&gt;
&lt;!--more--&gt;

&lt;p&gt;&lt;strong&gt;UsePostTunneling&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Post tunneling allows you to use your REST service with just the Post and Get verbs, and puts a little something extra in the header so that the service knows to treat the Post as a Merge, Put or Delete verb. &amp;nbsp;For WCF Data Services, all you need to do is set the UsePostTunneling property on the Context to true.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s sample code from anonymized from my dataservice factory:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;

&lt;div class=&quot;language-cs highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyDataSvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyDataEntities&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetDataSvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SvcUri&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://myserver.com/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;dataservice.svc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyDataSvc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MyDataEntities&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SvcUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UsePostTunneling&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>Why am I blogging? Because Scott asked me to</title>
      <link>https://hutchcodes.net/2012/04/why-am-i-blogging-because-scott-asked-me-to/</link>
      <pubDate>Mon, 23 Apr 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/04/why-am-i-blogging-because-scott-asked-me-to/</guid>
      <description>&lt;p&gt;Seriously, &lt;a href=&quot;http://www.hanselman.com/&quot; title=&quot;Scott&quot; target=&quot;_blank&quot;&gt;Scott&lt;/a&gt; Hanselman, one of the premier software development bloggers and all around dev guru, asked me to blog. &amp;nbsp;He wrote a whole &lt;a href=&quot;http://www.hanselman.com/blog/YourBlogIsTheEngineOfCommunity.aspx&quot; title=&quot;blog&quot; target=&quot;_blank&quot;&gt;blog&lt;/a&gt; post about how important he thought it was that I start blogging. &amp;nbsp;It seems he really thinks I have something to add to the conversation, and that someday he will find answers to some of his questions when a Google search turns up my blog.&lt;/p&gt;
&lt;p&gt;&lt;!--more--&gt;&lt;/p&gt;
&lt;p&gt;OK, so he wasn&amp;rsquo;t speaking specifically to me, but I had been thinking about starting to blog because I&amp;rsquo;m at a point where I do think I have something to add to the conversation, and I may actually be able to post about a coherent article on some problem I&amp;rsquo;ve overcome that took researching 3+ pages deep in Google results for a hint that pointed me in the right direction.&lt;/p&gt;
&lt;p&gt;Basically I was ready to start blogging, and Scott just pushed me over the edge. &amp;nbsp;And for that I say thanks.&lt;/p&gt;
&lt;p&gt;**I was watching a video of one of Scott&amp;rsquo;s presentations where he said that he wants to beat out Scotts toilet paper as the top result when searching for Scott. &amp;nbsp;To do that, he proposed that when linking to his site everyone link on the word Scott. &amp;nbsp;I&amp;rsquo;m not sure if he was joking, but I went with it anyway.&lt;/p&gt;

</description>
    </item>
    
    <item>
      
      <category>Random</category>
      
      

      <title>The greatest feature of all</title>
      <link>https://hutchcodes.net/2012/04/the-greatest-feature-of-all/</link>
      <pubDate>Sun, 22 Apr 2012 00:00:00 UTC</pubDate>
      <author>Jeremy Hutchinson</author>
      <guid>https://hutchcodes.net/2012/04/the-greatest-feature-of-all/</guid>
      <description>&lt;p class=&quot;first-para&quot; style=&quot;margin: 0px 0px 1.5em; padding: 0px; border: 0px; outline: 0px; font-size: 14px; font-family: Arial, Helvetica, sans-serif; line-height: 22.265625px;&quot;&gt;&lt;span face=&quot;Arial, Helvetica, sans-serif&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 22.265625px;&quot;&gt;Today was a big day in my life as a developer. &amp;nbsp;I added the most important feature to my application. &amp;nbsp;This is the first time I have ever added a feature of such magnitude to an application I wrote as a side project. &amp;nbsp;You might be wondering what this wonderful feature of which I speak?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;first-para&quot; style=&quot;margin: 0px 0px 1.5em; padding: 0px; border: 0px; outline: 0px; font-size: 14px; font-family: Arial, Helvetica, sans-serif; line-height: 22.265625px;&quot;&gt;&lt;strong&gt;&lt;span style=&quot;font-size: 14px; line-height: 22.265625px; font-family: Arial, Helvetica, sans-serif;&quot;&gt;SHIPPING!!!&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;!--more--&gt;

&lt;p class=&quot;first-para&quot; style=&quot;margin: 0px 0px 1.5em; padding: 0px; border: 0px; outline: 0px; font-size: 14px; font-family: Arial, Helvetica, sans-serif; line-height: 22.265625px;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 22.265625px; font-family: Arial, Helvetica, sans-serif;&quot;&gt;Did it really need to be in bold, with 3 exclamation points? &amp;nbsp;Yes, I think it did. &amp;nbsp;This is a huge accomplishment on a personal level. &amp;nbsp;I have started and not finished at least a dozen other projects in my life. &amp;nbsp;The all start out the same way. &amp;nbsp;I think &amp;ldquo;Hey, this technology is really cool, I should build something.&amp;rdquo; &amp;nbsp;I find an idea and after I&amp;rsquo;ve fully explored the technology, I never finish the last 20% of the project. &amp;nbsp;You know the 20% that takes 80% of the effort.&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;first-para&quot; style=&quot;margin: 0px 0px 1.5em; padding: 0px; border: 0px; outline: 0px; font-size: 14px; font-family: Arial, Helvetica, sans-serif; line-height: 22.265625px;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 22.265625px; font-family: Arial, Helvetica, sans-serif;&quot;&gt;I always learn a lot from these side projects, but this is the first time I&amp;rsquo;ll really have something to show for it. &amp;nbsp;Am I proud of the code? &amp;nbsp;Absolutely not. &amp;nbsp;I was working with an open source chess engine (from &lt;a href=&quot;ChessBin.com&quot; title=&quot;ChessBin.com&quot; target=&quot;_blank&quot;&gt;ChessBin.com&lt;/a&gt;) to setup the board and validate moves. &amp;nbsp;I had to do some things that made me cringe at times to get things working. &amp;nbsp;The alternative was to spend weeks refactoring the chess engine with the hope of not breaking it while converting it from something designed for WinForms to something designed for MVVM. &amp;nbsp;I chose the shortcut so that I could add other features, like shipping.&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;first-para&quot; style=&quot;margin: 0px 0px 1.5em; padding: 0px; border: 0px; outline: 0px; font-size: 14px; font-family: Arial, Helvetica, sans-serif; line-height: 22.265625px;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 22.265625px; font-family: Arial, Helvetica, sans-serif;&quot;&gt;Is my app going to change the world? &amp;nbsp;Is it going to make me rich? &amp;nbsp;Absolutely not. &amp;nbsp;I expect to get dozens of downloads per year, and hope to make back the $99 I paid to publish it over my lifetime.&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;first-para&quot; style=&quot;margin: 0px 0px 1.5em; padding: 0px; border: 0px; outline: 0px; font-size: 14px; font-family: Arial, Helvetica, sans-serif; line-height: 22.265625px;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 22.265625px; font-family: Arial, Helvetica, sans-serif;&quot;&gt;Will I try to publish another loss producing app in the future? &amp;nbsp;Yes. &amp;nbsp;This whole thing has been a great learning experience, both development and product management wise. &amp;nbsp;I&amp;rsquo;m sure I&amp;rsquo;ll learn a lot about marketing in the coming months as well.&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;first-para&quot; style=&quot;margin: 0px 0px 1.5em; padding: 0px; border: 0px; outline: 0px; font-size: 14px; font-family: Arial, Helvetica, sans-serif; line-height: 22.265625px;&quot;&gt;&lt;span style=&quot;font-size: 14px; line-height: 22.265625px; font-family: Arial, Helvetica, sans-serif;&quot;&gt;If you have a Windows Phone please &lt;a href=&quot;http://www.windowsphone.com/en-US/apps/225f7d20-6067-49ee-9142-b4b89658b4b2&quot; title=&quot;check it out&quot;&gt;check it out&lt;/a&gt;. &amp;nbsp;If like it give me a nice 5 star rating. &amp;nbsp;If you don&amp;rsquo;t like it send me an email and tell me what you&amp;rsquo;d do differently.&lt;/span&gt;&lt;/p&gt;

</description>
    </item>
    
  </channel> 
</rss>
