Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#

The Essence Pattern in C#

Rate me:
Please Sign up or sign in to vote.
4.40/5 (37 votes)
7 Oct 2013CPOL3 min read 111.5K   293   69   31
An implementation of the Essence Pattern in C#

Introduction

The Essence Pattern provides a way to enforce users of an object to enter valid properties for that object. A full description of the pattern can be found in the original paper here (PDF). In this article, I shall provide a C# implementation of this pattern.

Background 

If you are providing an external interface to your code either as an API or because your code forms a tier in an n-tier system, then the Essence Pattern can be used to force other programmers to put valid, required fields into an object before they start using that object. One common situation where this is required is for key fields to be saved to a database. The user of the object must not attempt to save that object to the database without the key properties, or the database will complain.

Of course, you could simply provide just one constructor that forces the programmer to enter all the required properties. In the simple case this is perfectly acceptable. However, if you are exposing an external interface, you may also want it to be COM wrappable. In this case, you can only have one, parameterless constructor which disallows that particular strategy. Also, what if there are a lot of required parameters, some of which need to be calculated or read from a data source? Are you going to make the user of your object store all these in local variables before they can construct your object?

The Example Code

The code sample with this article shows a very simple implementation of the Essence Pattern for a small class representing a contact. The Contact class has 5 properties, three of which are required (FirstName, LastName and Email), and two of which are optional (PhoneNumber and PostalAddress ).

The first thing we do is create the ContactEssence class as an internal class of the Contact class. The ContactEssence contains only the required properties for the contact (FirstName, LastName and Email), and allows read and write access to them all.

One of the two important methods of the ContaceEssence is the Validate method (shown below). This method essentially checks that all the required parameters are present and correct. Only when the Validate method returns true can the class advance to the next stage.

C#
// Validates the essence fields.
private bool Validate()
{

  // Check we have a firstname
  if (mFirstName.Length == 0)
    return false;

  // ... and a last name
  if (mLastName.Length == 0)
    return false;

  // Check email exists and if it does, then check it's valid.
  if (mEmail.Length == 0)
    return false;
  else
  {
    // Use a regular expression to match an email address.
    System.Text.RegularExpressions.Regex emailReg = 
      new System.Text.RegularExpressions.Regex(
      @"^[\w-]+(?:\.[\w-]+)*@(?:[\w-]+\.)+[a-zA-Z]{2,7}$", 
      System.Text.RegularExpressions.RegexOptions.CultureInvariant);
    System.Text.RegularExpressions.MatchCollection results = 
      emailReg.Matches(mEmail, 0);

    // If we didn't get a mtach, fail the validation
    if (results.Count == 0)
      return false;
  }

  // Getting this far means validation is good
  return true;

}

The next stage is the creation of the real Contact class, which is done through a call to the ContactEssence.CreateContact method.

C#
/// <summary>
/// Creates a <c>Contact</c> instance based on this essence.
/// </summary>
/// <returns>A new <c>Contact</c> 
/// if this <c>ContactEssence</c> is valid, 
/// otherwise a <c>null</c> reference.</returns>
public Contact CreateContact()
{
  if (this.Validate() == true)
    return new Contact(this);
    
  return null;
}

As you can see, if the ContactEssence is validated correctly, a Contact is returned.

The final part of the puzzle is the Contact class itself. The first area to look at are the constructors:

C#
 // Private constructor can only be accessed by internal classes.
private Contact(ContactEssence xEssence) 
{
  // Copy required, immutable properties from essence
  mEmail = xEssence.Email;
  mFirstName = xEssence.FirstName;
  mLastName = xEssence.LastName; 
}

The constructor is private. ContactEssence is an internal class to the Contact, so it has access to the private constructor. This means that the Contact class can only be created by the ContactEssence class.

When the Contact is created from the ContactEssence, it simply copies all the required fields. Additional (optional) fields are left in their original initialised state. 

Finally, in the Contact class, the required fields are exposed as read-only properties, while the optional fields are read-write. This means that once the required fields are created, they cannot be changed.

So how do we use the Contact class?

The example code shows the role of the ContactEssence and the validation of required Contact properties:

C#
// Cannot create contact directly this line 
// of code will create an error
//Essence.Contact c = new Contact(new Contact.ContactEssence());

// Create the essence
Contact.ContactEssence essence = new Contact.ContactEssence();

// Add the first required field
essence.Email = "me@mydomain.com";

// Cannot create Contact yet ...
Contact invalidContact = essence.CreateContact();
if (invalidContact == null)
  Console.WriteLine("Created NULL contact!");


// Fill in the rest of the required fields
essence.FirstName = "Dermot";
essence.LastName = "Gubbins";

// Try creating contact again
Contact validContact = essence.CreateContact();
if(validContact == null)
  Console.WriteLine("Oops! This should be valid!");
else
{
  // Add a phone number (optional)
  // but not an address.
  validContact.PhoneNumber = "(+44) 444 444";

  // Display the valid contact.
  Console.WriteLine("\nContact Created ...\n");
  Console.WriteLine(validContact.ToString());

}

Points of Interest

As explained in the original paper the Essence Pattern can be used in object creational patterns to create multiple valid classes by changing one or more of the required fields and then creating a new instance of the main class. Additionally, the Essence can also act as a builder class.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader
United Kingdom United Kingdom
After ten years studying biology and evolution, I threw it all away and became a fully paid up professional programmer. Since 1990 I have done C/C++ Windows 3.1 API, Pascal, Win32, MFC, OOP, C#, etc, etc.

PS. In the picture, I'm the one in blue. On the right.

Comments and Discussions

 
BugBroken Link? Pin
james983721-Sep-13 15:14
james983721-Sep-13 15:14 
GeneralRe: Broken Link? Pin
Dr Herbie7-Oct-13 1:38
Dr Herbie7-Oct-13 1:38 
GeneralVery useful article. Thanks a lot. Pin
jahfer18-Aug-13 5:45
jahfer18-Aug-13 5:45 
GeneralMy vote of 4 Pin
hichaeretaqua29-Jul-13 20:55
hichaeretaqua29-Jul-13 20:55 
BugMinor code improvment Pin
hichaeretaqua29-Jul-13 20:54
hichaeretaqua29-Jul-13 20:54 
GeneralRe: Minor code improvment Pin
Dr Herbie30-Jul-13 22:33
Dr Herbie30-Jul-13 22:33 
QuestionQuestion Pin
FatCatProgrammer8-Jul-13 5:45
FatCatProgrammer8-Jul-13 5:45 
AnswerRe: Question Pin
Dr Herbie11-Jul-13 0:54
Dr Herbie11-Jul-13 0:54 
QuestionDead links? Pin
mrchief_200010-Jun-13 7:46
mrchief_200010-Jun-13 7:46 
GeneralMy vote of 4 Pin
User 67245138-Jun-13 13:43
User 67245138-Jun-13 13:43 
GeneralVery good. Pin
Septimus Hedgehog8-Jun-13 10:43
Septimus Hedgehog8-Jun-13 10:43 
QuestionThe Essence Pattern in C# Pin
Fregate21-Dec-12 14:09
Fregate21-Dec-12 14:09 
AnswerRe: The Essence Pattern in C# Pin
Dr Herbie21-Dec-12 23:49
Dr Herbie21-Dec-12 23:49 
GeneralRe: The Essence Pattern in C# Pin
bertkid8-Jun-13 13:57
bertkid8-Jun-13 13:57 
GeneralRe: The Essence Pattern in C# Pin
Jasmine250110-Jun-13 8:19
Jasmine250110-Jun-13 8:19 
GeneralRe: The Essence Pattern in C# Pin
Dr Herbie11-Jul-13 1:03
Dr Herbie11-Jul-13 1:03 
GeneralRe: The Essence Pattern in C# Pin
Jasmine250112-Jul-13 5:08
Jasmine250112-Jul-13 5:08 
GeneralRe: The Essence Pattern in C# Pin
Dr Herbie12-Jul-13 5:59
Dr Herbie12-Jul-13 5:59 
QuestionDo you see this as different from the Memento pattern? Pin
panmanphil23-Jun-04 6:25
panmanphil23-Jun-04 6:25 
AnswerRe: Do you see this as different from the Memento pattern? Pin
Dr Herbie23-Jun-04 21:38
Dr Herbie23-Jun-04 21:38 
GeneralRe: Do you see this as different from the Memento pattern? Pin
panmanphil24-Jun-04 4:58
panmanphil24-Jun-04 4:58 
GeneralRe: Do you see this as different from the Memento pattern? Pin
Dr Herbie24-Jun-04 10:42
Dr Herbie24-Jun-04 10:42 
GeneralRe: Do you see this as different from the Memento pattern? Pin
angrylala15-Mar-07 19:34
angrylala15-Mar-07 19:34 
GeneralMore like builder patther, Haha Pin
Member 97513418-Jun-04 17:38
Member 97513418-Jun-04 17:38 
GeneralMore like builder patther, Haha Pin
Member 97513418-Jun-04 17:32
Member 97513418-Jun-04 17:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.