July 27

Simplifying Switches Using Dictionaries

Have you ever had to write a long series of if/then statements or a giant switch statement that extends for a page or two of your code? Want an easy way to increase the readability of your code, increase it's maintainability index, and decrease it's cyclomatic complexity? Let's see an example problem and then a possible solution.

Let's start off by considering the following array of anonymous types:

var items = new[]
{
    new {Operation = Operation.Add, Value1 = 1, Value2 = 2},
    new {Operation = Operation.Subtract, Value1 = 4, Value2 = 3},
    new {Operation = Operation.Multiply, Value1 = 5, Value2 = 6},
    new {Operation = Operation.Divide, Value1 = 8, Value2 = 4},
    new {Operation = Operation.Add, Value1 = 9, Value2 = 10},
    new {Operation = Operation.Subtract, Value1 = 12, Value2 = 11},
    new {Operation = Operation.Multiply, Value1 = 13, Value2 = 14},
    new {Operation = Operation.Divide, Value1 = 16, Value2 = 4},
    new {Operation = Operation.Add, Value1 = 17, Value2 = 18},
    new {Operation = Operation.Subtract, Value1 = 6, Value2 = 3},
    new {Operation = Operation.Multiply, Value1 = 8, Value2 = 8},
    new {Operation = Operation.Divide, Value1 = 10, Value2 = 2}
};

I need to iterate over this array and execute the given Operation on Value1 and Value2 properties to produce a list of results A brute force method of doing this is as follows:

var results = new List<int>();
 
foreach (var item in items)
{
    switch (item.Operation)
    {
        case Operation.Add:
            results.Add(item.Value1 + item.Value2);
            break;
        case Operation.Subtract:
            results.Add(item.Value1 - item.Value2);
            break;
        case Operation.Multiply:
            results.Add(item.Value1*item.Value2);
            break;
        case Operation.Divide:
            results.Add(item.Value1/item.Value2);
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }
}

The switch statement is pretty straightforward and simple to implement in this example. Visual Studio 2013 Code Analysis is giving the code a maintainability index of 54 and a cyclomatic complexity of 6. What if I needed more lines of code to handle each operation? This could turn into a mess to test, debug, and maintain.

A possible solution to this problem is to replace your switch with a dictionary. I realize that seems odd to replace a control statement with a data structure, but refactoring to this approach will simplify your code. In our example, each item in the array has an Operation to be performed on the Value1 and Value2 properties. I can setup my dictionary with the key value being the Operation enumeration, and the value being the Action, Func, or method group that performs the operation.

var operationMethods = new Dictionary<Operation, Func<int, int, int>>
{
    {Operation.Add, Add},
    {Operation.Subtract, Subtract},
    {Operation.Multiply, Multiply},
    {Operation.Divide, Divide}
};

In the example above, I'm using the following methods:

public int Add(int left, int right)
{
    return left + right;
}
 
public int Subtract(int left, int right)
{
    return left - right;
}
 
public int Multiply(int left, int right)
{
    return left*right;
}
 
public int Divide(int left, int right)
{
    return left/right;
}

With the dictionary approach, our code to iterate over the items and execute the individual operations looks like this:

var results = new List<int>();
 
foreach (var item in items)
{
    results.Add(operationMethods[item.Operation].Invoke(item.Value1, item.Value2));
}

VS2013 gives the refactored code a maintainability index of 63 and a cyclomatic complexity of 2. Our code is still doing the same thing as the switch was, but we have broken the code down to simpler pieces that are more readable and more easily to wrap unit tests around.

I find this to be a good approach to take when the "cases" of our switch statement are known up front (such as using an enumeration). If it is possible that you will not have all the cases or keys in the dictionary, you can still use this approach but you will want to handle things more gracefully with the Dictionary's TryGetValue method like so:

Func<int, int, int> operation;
 
if (operationMethods.TryGetValue(item.Operation, out operation))
{
    results.Add(operation(item.Value1, item.Value2));
}
else
{
// TODO: Handle case of the missing case/key
}

To tie it all together, here is a Gist with the code I discussed in this post.

I hope this helps. If you have any questions or comments, please use the comments form below. Thanks.

Category: C# | Comments Off on Simplifying Switches Using Dictionaries
December 28

How To Enable Windows Authentication When Using IISExpress

Back in early October, my employer temporarily assigned me to a project to replace an existing Access-based application. After initial meetings with the client, it was decided that an ASP.NET MVC 4 and SQL Server 2008 solution would be the best way to deliver what the client was looking for while also removing many of the rough edges from the legacy application. One thing I like about building intranet applications is that your client has standardized on a particular browser. In this case it is IE8+. Since the users of the web application will all be connected to the client’s Active Directory, we decided to use that for authentication. I would have liked to also manage roles/groups through AD as well, but that was shot down.

Fast forward to the end of December and my employer has hired a new resource to take over the work. The new resource downloads all the source code on to his freshly re-paved laptop, opens up Visual Studio 2012 and attempts to start the application. The code builds fine, the web browser pops up, and then an exception with the following message is thrown:

Trust relationship between the primary domain and trusted domain failed

By default, IISExpress has Windows Authentication turned off. To turn it on, we need to add the following code to the bottom of the “\My Documents\IISExpress\config\applicationhost.config” file.

   1:  <location path="MyWebsite">
   2:      <system.webServer>
   3:          <security>
   4:              <authentication>
   5:                  <anonymousAuthentication enabled="false" />
   6:                  <windowsAuthentication enabled="true" />
   7:              </authentication>
   8:          </security>
   9:      </system.webServer>
  10:  </location>

Now, you will need to change the path attribute on the location element to match the name of your website. In this case, my website’s URL is “http://localhost:5439/MyWebsite/”. Next you can tweak the authentication elements to work the way you need them to. In this case, I only want authenticated users to allowed access to the website.

Once these changes were made on the new resources laptop, he was up and running. This occupied some of my time the other day to figure out what was going on and this blog post is here to serve as a reminder to me and maybe other people who are having the same issue.

Category: Uncategorized | Comments Off on How To Enable Windows Authentication When Using IISExpress
June 19

Using C# extension methods with Microsoft StreamInsight

Many times when working with different APIs we find some functionality that is useful but often times tedious to get at. A couple examples that come to mind are accessing OSI PI data (it comes back in a series of jagged arrays forcing you to have to check for null, etc) and Microsoft StreamInsight diagnostic views. Since we don't have access to the original code to make the changes directly to the API, one of the best ways to extend it is to use extension methods. Sometimes we forget that we have this tool in the toolbox. I came across a good blog post from the DevBiker called A couple of helpful StreamInsight Query extension methods. There are a couple of extension methods in there that smooth out some of the rough edges when dealing with StreamInsight's Query object.

Category: Microsoft StreamInsight | Comments Off on Using C# extension methods with Microsoft StreamInsight
June 24

New job, new computer, stupid proxy settings

I just changed jobs within my current company. I basically went from doing dev work for a few oil and gas companies to doing work for one energy company. It's always weird starting a new job. You may have an interview or two before you start, but you never know exactly what you are going to get until you accept it and jump in. The office is playing a giant game of "musical offices & cubes" while they are remodeling the building. I hear it will be very nice when it's done. Office space is at a premium right now and myself and another co-worker have been put into a computer lab/server room to work for now. It's pretty cool. We've got a bunch of hardware, a door we can close, and a great A/C system. If you live in Houston during the 90+ degree summers, you know how important it is to have a good A/C system. The problem is that the A/C is always on. If we close the door, we freeze. If we leave the door open, we can hear everyone talking on the phone, to each other, and the constant traffic outside the room. The guys that are talking the loudest have cubes side by side and they are around the corner. Guys, you are at about 10, we need you at about a 4 or 5.

So here I sit in the icebox with a hoodie on to keep warm. Got a brand new laptop that I've been working to setup with all the tools and stuff that I'll need to do my job here. It's a pretty decent laptop. With the exception of a smaller screen and keyboard, I'm happy with it. One of the most annoying things about carrying around the laptop is changing the proxy settings every time you go from the office to the house. For the occasional changes it's no big deal to click through all the settings to make the changes. If you are doing it twice a day, it's annoying as hell. I did some snooping around and found a Microsoft TechNet "Scripting Guy" article that helped me out. I created a couple vb scripts to enable and disable the proxy server and it's so nice to just double click the file to make the change. The next step would be to find a way for the script to detect what environment it is in (home or office) and change it automatically.

Here's the link for anyone else who needs it: How Can I Switch Between Using a Proxy Server and Not Using a Proxy Server?

Category: Uncategorized | Comments Off on New job, new computer, stupid proxy settings
June 24

Hello World

Thanks for visiting my blog. This is my first shot at this kind of thing. If it's rough around the edges, please bear with me.

About Me

I'm a software developer for a large technology company in the Houston, Texas area. They contract me out to various companies in the Oil & Gas and Energy vertical markets. I prefer to work with the .NET Framework (ASP.NET mostly) and MS SQL Server, but I've been known to work on other things when the need arises.

"So what would you say, you do here?"

I've been doing the development thing for quite awhile now. There have been many times when I've had to go research how to do something. I've learned a lot from many different people out there on the web and now it's time to try to give some back to the community. I'll be blogging about some of the problems I come across and my approach to fixing them.

Category: Uncategorized | Comments Off on Hello World