Posted

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.

Author

Posted

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.

Update August 2021

The Visual Studio Marketplace now offers several extensions to hide / suppress regions without removing them from code. This is a good compromise when team members have different opinions on whether regions are good or bad. As you can see from the extension names, regions generate similar feelings as var among developers.

Author

Posted

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 a large or unfamiliar code base. 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 it 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 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.

Author

Posted

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();
}

Author