Saturday, May 7, 2016

Using namespaces to promote code reuse

A well defined namespace hierarchy promotes code reuse by exposing existing types through an IDE's Intellisense, without developers needing to know which namespaces to include or which types exist in which namespaces.

Software developers make use of namespaces when referencing code from others as well as when organizing their own code. Visual Studio defaults to a root namespace that is the same as the project name, and classes within sub-folders in the project receive a default namespace of ProjectName.FolderName.
using System;
using System.IO;

namespace ProjectName.FolderName
{
  public class Person
  {
    public int Id { get; set; }
  }
}
This is a perfectly logical approach, but can lead to disorganized namespaces within a solution if no thought is given to the resulting namespace hierarchy at the time the projects are created. Consider a product called RetailMe that provides inventory and accounting functionality for a retail business. The solution and project structure might look similar to this:

RetailMe.sln
  - Accounting.csproj
       - Vendor.cs
  - Common.csproj
       - IProduct.cs
  - Inventory.csproj
       - Bicycle.cs

The classes and interfaces will be defined in their project namespace and probably define using statements to more easily reference types in other namespaces.
namespace Common
{
  public interface IProduct
  {
    string Name { get; set; };
  }
}
using Common;
using Accounting;

namespace Inventory
{
  public class Bicycle : IProduct
  {
    public void Sell()
    {
      if (Bicycle.NumberInStock < 5)
      {
         Vendor v = Vendor.For(this);
         Vendor.Order(5);
      }
    }
  }
}
using Common;
using Inventory;

namespace Accounting
{
  public class Vendor
  {
    public void Order(int numberOfItems)
    {
       //call vendor service to order more
    }

    public static Vendor For(IProduct item)
    {
      //return something
    }
  }
}    
There is nothing incorrect with the solution/project structure shown above; however, changing the namespaces to a hierarchical structure can promote better code reuse among the projects in the solution. In the examples above, using statements for Common, Inventory, and Accounting are defined at the top of each class, which means the developer needed to know that IProduct is defined in the Common namespace.

Using a hierarchical namespace allows the shared or common items to be more easily exposed to developers. A common way of doing this is to start all the namespaces with CompanyName.ProductName. If we change the namespaces from the above example, the new namespace structure might look something like this:
namespace Acme.RetailMe
{
  public interface IProduct
  {
    string Name { get; set; };
  }
}
using Acme.RetailMe.Accounting;

namespace Acme.RetailMe.Inventory
{
  public class Bicycle : IProduct
  {
    public void Sell()
    {
      if (Bicycle.NumberInStock < 5)
      {
         Vendor v = Vendor.For(this);
         Vendor.Order(5);
      }
    }
  }
}
namespace Acme.RetailMe.Accounting
{
  public class Vendor
  {
    public void Order(int numberOfItems)
    {
       //call vendor service to order more
    }

    public static Vendor For(IProduct item)
    {
      //return something
    }
  }
}      
Defining the namespaces in this way eliminates the need to define a using statement for a "Common" project and the Acme.RetailMe.IProduct interface will automatically show up in Intellisense while developers are making changes in the Acme.RetailMe.Inventory and Acme.RetailMe.Accounting namespaces.

This becomes more important as the code base and number of developers grows because it becomes more difficult for developers to know about all of the existing types that can be reused. If the reusable types continually show up in Intellisense while the developers are working on other changes, they are more likely to know about them and use them in the future.

Wednesday, July 22, 2015

Visual Studio code regions

The Visual Studio IDE allows user-defined regions to easily expand / collapse sections of code.
#region "public methods"
public void Add(int x, int y)
{
  
}

public void Subtract(int x, int y)
{

}
#endregion
When this feature was introduced, I was a proponent of using regions to organize code, and would create sections for fields, properties, public methods, private methods, etc. Over the years, I've changed my mind about using regions and no longer recommend them.

If my classes are large enough that adding regions to show/hide relevant sections is helpful, that is a good indication that my class is probably too large. The Single Responsibility Principle of SOLID suggests that a class should only have one reason to change. A class that only has one reason to change is usually going to be a small class. If the entire class can be viewed in one or two screens / pages of code, the need for regions is eliminated, or at least greatly reduced.

Even if you don't agree with the benefits of smaller classes, another reason against grouping sections of code by scope is that it is not particularly productive. Consider the following (admittedly, contrived) example of methods grouped by scope (public methods on top, private methods on the bottom)
#region "public methods"
public void Insert(Order order)
{
  InsertOrder(order);
  InsertLineItems(order);
  UpdateInventory(order);
  UpdateAccountsReceivable(order);
}

public void Update(Order order)
{
  UpdateOrder(order);
  UpdateLineItems(order);
  UpdateInventory(order);
  UpdateAccountsReceivable(order);
}

#endregion

#region "private methods"

private void InsertOrder(Order order)
{
  //Insert the order
}

private void InsertLineItems(Order order)
{
  //Insert order line items
}

private void UpdateInventory(Order order)
{
  //Update inventory
}

private void UpdateAccountsReceivable(Order order)
{
  //Update accounting information
}

private void UpdateOrder(Order order)
{
  //Update the order
  InsertLineItems(order);
  UpdateLineItems(order);
  DeleteLineItems(order.LineItems);
}

private void UpdateLineItems(Order order)
{
  //Update order line items
}

private void DeleteLineItems(LineItems items)
{
  //Delete order line items
}

#endregion
Again, this is a contrived example, but it illustrates the issue with grouping by scope. Attempting to debug the Update method at the top would require a fair amount of scrolling to view the private methods at the bottom, especially if any of the methods are large. That makes it harder to remember the context of the currently executing code. If the public/private regions were removed and the methods were rearranged to be closer based on functionality rather than scope, debugging is easier because more relevant code can fit on the screen at the same time.

Some may suggest surrounding the groups of methods in regions after they have been rearranged by functionality. In that case I would suggest taking the extra step and refactoring that functionality into its own class. With the prevalence of multiple widescreen monitors, displaying the relevant code across multiple monitors is more productive than splitting a single class in the same window/tab and continually scrolling up and down among the relevant methods.

Friday, July 17, 2015

C# Using Static statement

C# 6.0 introduced the "using static" statement, which allows developers to specify a static class (as well as enums and structs) rather than a namespace in a using statement. Many examples describing this new feature use System.Console as an example.
using static System.Console;
using static System.IO.File;

public static void Main(string[] args)
{
  WriteLine("Some value");
}
It is not clear where "Some value" is being written in the above code. In this case System.IO.File does not have a WriteLine method, so we can deduce that System.Console.WriteLine is being called. This becomes much less obvious when working on large or unfamiliar code bases. I therefore initially thought the "using static" statement would only make code less readable, not more. However, I have recently encountered a situation where I found the "using static" statement to be very useful.

First a bit of context. When developing WCF web services, I usually create three separate projects

  • BusinessDomain.Service.Wcf - Contains contract classes, interfaces, and DTO mapping extension methods.
  • BusinessDomain.Service.Wcf.Host - Contains service implementation.
  • BusinessDomain.Service.Wcf.Proxy - Contains client implementation.

The BusinessDomain.Service.Wcf project contains static classes with extension methods which map values between DTO objects and other objects. For example, with a Person domain class, and a Person DTO, the following ToDomainEntity method would map values from the DTO object to the domain object.
namespace BusinessDomain.Service.Wcf.EntityMappers
{
  public static class PersonMapper
  {
    public static Person ToDomainEntity(this PersonDTO source)
    {
      // map values from PersonDTO to Person
    }
  }
}

This method is then used to easily convert the DTO to a domain object when interacting with the web service. The BusinessDomain.Service.Wcf.Proxy project might contain code similar to the following, to interact with the service and return an object to the client. Note the using statement with the namespace of the mapping classes and extension methods.
using BusinessDomain.Service.Wcf.EntityMappers;

namespace BusinessDomain.Service.Wcf.Proxy
{
  public class PersonServiceProxy
  {
    public Person FindPerson(int personId)
    {
      PersonDTO response = Svc.FindPerson(personId);
      
      return response.ToDomainEntity();
    }
  }
}

This approach works well for WCF projects, but I recently tried the same approach with a Web API project. With Web API, all of the service responses are of type HttpResponseMessage. Adding extension methods for HttpResponseMessage quickly becomes unwieldy because every extension method shows up in Intellisense, including those that are not appropriate in the current context. Expanding on the WCF example above, imagine I have a Person class and a Car class, along with mapper classes for each.
namespace BusinessDomain.Service.WebApi.EntityMappers
{
  public static class PersonMapper
  {
    public static Person ToPerson(this HttpResponseMessage source)
    {
      // map values
    }
  }

  public static class CarMapper
  {
    public static Car ToCar(this HttpResponseMessage source)
    {
      // map values
    }
  }
}

using BusinessDomain.Service.WebApi.EntityMappers;

namespace BusinessDomain.Service.WebApi
{
  public class PersonServiceProxy
  {
    public Person FindPerson(int personId)
    {
      HttpResponseMessage response = Svc.FindPerson(personId);

      return response.ToPerson();
    }
  }
}
In the FindPerson method, the Intellisense for the response object is populated with both ToPerson and ToCar. Calling the ToCar extension method would never be appropriate in this context. In this situation, the "using static" method can be used to limit the Intellisense items to the methods appropriate to the current context.
using BusinessDomain.Service.WebApi.EntityMappers;
using static BusinessDomain.Service.WebApi.EntityMappers.PersonMapper;

namespace BusinessDomain.Service.WebApi
{
  public class PersonServiceProxy
  {
    public Person FindPerson(int personId)
    {
      HttpResponseMessage response = Svc.FindPerson(personId);

      return response.ToPerson();
    }
  }
}
The Intellisense for the response object would still contain the ToPerson extension method, but would no longer be cluttered with the ToCar or other inappropriate extension methods.


Thursday, May 7, 2015

ASP.NET MVC 5 custom errors

ASP.NET MVC 5 allows you to define custom errors in the config file, similar to the following:

  <system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="404"/>
      <remove statusCode="500"/>
      <error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />
      <error statusCode="500" responseMode="ExecuteURL" path="/Error/ServerError" />
    </httpErrors>
  </system.webServer>

This usually works, but depending on the version of IIS, you may also need to set TrySkipIisCustomErrors on the Response.

public ActionResult NotFound()
{
    Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
    Response.TrySkipIisCustomErrors = true;

    return View();
}


Friday, July 25, 2014

Create web.config transform based on publish profile

If you've used Visual Studio since 2010 or 2012, you know how easy it is to transform config files based on the build configuration.

If you've used SlowCheetah, you know how easy it is to transform config files (other than web.config) based on the build configuration OR Visual Studio publish profiles.

You probably also know how unintuitive it can be to add a web.config transformation based on the project's publish profiles. Here's how.

From an existing profile







Right-click and choose "Add Config Transform", not "Add Transform".











Friday, May 9, 2014

Windows 7 and multiple clocks

Windows 7 allows you to define 2 additional clocks / time zones.

Right click on the time in the taskbar and choose Adjust date/time.



















Click on the Additional Clocks tab, and choose up to two additional clocks.

Store dates and times using UTC

UTC is better because it's precise. Local time zones are ambiguous.

In the past, I've tended to avoid UTC and just use my local time zone for dates and times because troubleshooting was easier when I didn't have to convert time zones (for log entries, database tables, etc). This generally worked OK when I was working alone, and all my computers were set to my local time zone. However, I started noticing situations where time conversions were necessary, such as when I wanted to publish a website on a host server outside my time zone, or when I was working on a project with one or more developers in different time zones.

In these situations, I was already converting to one or more time zones, so converting to UTC should be, at worst, no more difficult, and at best, easier, since everyone converts to the same base time. I also noticed that converting between time zones actually became impossible in certain situations when dealing with Daylight Saving Time (DST).

  • When the local time 'falls back' at 2:00am, 1:30am has two valid values.
  • When the local time 'springs forward' at 2:00am, 2:30am has zero valid values.

I finally became a UTC convert when I was writing an application that needed to trigger alarms at specific times, and users were allowed to enter times in their local time zones. This was fine when everything was the same time zone, but it quickly became clear I was going to have issues with users outside my time zone.

  • Do I store alarm times in the user's time zone?
  • Do I store alarm times in a common time zone? Which one?
  • When I host this on a server will it still work on servers outside my time zone?
  • What if my server "springs forward"? Will it miss sending out alarms for that hour?

I solved all of these problems by storing the times in UTC, because UTC is UTC, regardless of time zones.