Make Encapsulation Easy with dotNetTips.Utility

f2540271b4d7eb0e4089b7a3006e948dEncapsulation is the first pillar of Object Oriented Programming (OOP), yet most code that I see does not implement encapsulation correctly or not all. Like I say in many of my conference sessions “If you do not implement encapsulation, you aren’t doing OOP!” I also say “Bad data in, bad data out!“.

Several years ago, Microsoft Labs came out with Code Contracts which made encapsulation easy so I implemented in all my projects and even did conference sessions about it. Unfortunately, the future of Code Contracts looks dim and it does not work in .NET Core or .NET Standard. Since I moved some of the code I’ve been writing since .NET came out in my open source project dotNetTips.Utility to .NET Standard, I needed a way to mimic the encapsulation features of Code Contracts.

Introducing the dotNetTips.Utility OOP Namespace

I created a new namespace in my open source project called OOP in both my .NET Portable project and .NET Standard project. The first class in this namespace is named Encapsulation. In this class, you will find overloaded methods called TryValidateParam, designed to make encapsulation easier. Here is the main method in this class.

public static void TryValidateParam<TException>(bool condition, 
                     string paramName = "", string message = "") 
                     where TException : ArgumentException, new()
{
  // Confirm proper Exception type
  var t = typeof(TException);

  if (t.Name == nameof(Exception))
  {
    throw new InvalidCastException(Resources.CannotBeOfTypeException,
                nameof(TException)));
  }

  var defaultMessage = Resources.ParameterIsInvalid;

  if (string.IsNullOrEmpty(message) == false)
  {
    defaultMessage = message;
  }

  if (condition == false)
  {
    var ex = Activator.CreateInstance(typeof(TException), 
               paramName, defaultMessage).As<TException>();
    throw ex;
  }
}

There are a few things I would like to point out in this method. First, it prevents users from throwing the type Exception, which you should never do since it is not descriptive enough. The only Exception type that should be thrown when checking parameters is one derived from ArgumentException. The exceptions included in the .NET Framework are:

  • ArgumentNullException
  • ArgumentOutOfRangeException

If one of these types does not meet your needs, then create your own inheriting ArgumentException. I did this in dotNetTips.Utility with the ArgumentInvalidException and ArgumentReadOnlyException.

The overloaded methods in this class makes it easy to check strings, collections, enums, GUID’s and more.

Example

Here is an example on how to use TryValidateParam (also from dotNetTips.Utility).

public static DateTime GetLastDay(this DateTime input, DayOfWeek dayOfWeek)
{             
  Encapsulation.TryValidateParam(dayOfWeek, nameof(dayOfWeek));

  var daysToSubtract = input.DayOfWeek > dayOfWeek ? input.DayOfWeek - 
                        dayOfWeek : (7 - (int)dayOfWeek) + 
                        (int)input.DayOfWeek;

  return input.AddDays(daysToSubtract * -1);

}

I hope you will implement this in your code too. To download from GitHub, click here. If you have any comments about this project, please add one on the GitHub site.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s