When your base class serves as a common implementation (as opposed to a common data model) you might sometimes want to force an implementation or behavior, but also allow the behavior to be extended without it being modified or omitted completely. What do I mean by this?

Consider when you have a User domain or view model. Some users are players, and other users are spectators. They share a common set of validations and CRUD operations, but also have unique elements that set them apart. So, you write a base class:


public class User
{
	public string Email { get; set; }

	public virtual void Validate()
	{ 
		if (string.IsNullOrEmpty(Email))
		{
			ModelState.AddError("Email", "Email cannot be null");
		}
	}
}

Anything that extends this will have the Validate() method available, but nothing stops the implementer of the Player class to omit the base implementation:


public class Player : User 
{
	public int Health { get; set; }

	public override void Validate()
	{
		//this is omitted, and now Email is not validated anymore
		//base.Validate();

		if (Health < 0)
		{
			Health = 0;
		}
	}
}

This violates the "O" of SOLID, that is, open to extension but closed to modification. The base implementation is effectively modified by the consumer of your base class. In most cases this is an oversight, and one of the leading causes of errors in the code. Static code analysis, and of course unit tests, will help in finding and pointing out such mistakes.

A better design is to not include required functionality in the virtual method. To do this we introduce a protected internal validation method which we make the virtual implementation instead:


public class User
{
	public string Email { get; set; }

	public void Validate()
	{ 
		if (string.IsNullOrEmpty(Email))	
		{
			ModelState.AddError("Email", "Email cannot be null");
		}

		Validate_Internal();
	}


	protected virtual void Validate_Internal() { }
}

Now, the user of your base class can provide any custom validation by overriding Validate_Internal(), yet the required base validation is unaffected and unmodified:


public class Player : User 
{
	public int Health { get; set; }
	
	protected override void Validate_Internal()
	{
		if (Health < 0)
		{		
			Health = 0;
		}
	}
}

And of course, the accessibility (or public signature) of the User class remains unaffected; there is still only the Validate() method available.

This pattern is officially called the template pattern or the nanny pattern. I typically would just refer to it as the internal implementation of Validate. Not to be confused with the `internal` keyword. It stems from the fact that I post-fix _Internal to the method name, but you can choose any name you want here. For example, you could follow the old Microsoft standard for the Windows API and call it ValidateEx, or the event naming standard as used in the WinForms classes and name it OnValidated (specifically past tense because the method is called at the end) or OnValidating (if the method was called first). It doesn’t really matter, as long as you isolate and protect your required base implementation from the user of your class.

Recently on helloserve

Here’s a question for you: how quickly do you think it is best to fail in your code? And at what level do you think it should be handled? My answers to those two questions are immediately, and at no level. Let me explain.

It's been a year and a bit since I took delivery of my CX-5. If you're wondering how it has been living with this car, read on. Spoiler alert: It's been pretty fantastic.

A while ago I wrote about interfaces and how everybody just uses it for IoC these days. This time I want to discuss something with regards to established and advertised IoC patterns and problems I have with it.