Wednesday, September 29, 2010

Fluent Validation Part III – The Repository

This is the fourth installment in this series:

  • Introduction – The basics or what Fluent Validation is
  • Part I – TDD with Fluent Validation and string validation
  • Part II – Date validation and custom property validators

This time we will take a look at how we can take advantage of a repository to help us with our data validation. Using a repository helps separate our data access concern from our model, allows our architecture to be more flexible, and maximizes the amount of testable code by abstracting the data layer.

We will continue to build upon the project we have been using from the beginning, so let’s get started by firing up Visual Studio, and opening our FluentValidation.Example.Solution. Open the Employee class and add a new property SocialSecurityNumber:

public class Employee
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string SocialSecurityNumber { get; set; }
}
Next, we need to create an interface for our employee repository. Add a new interface to the Models project called IEmployeeRepository:
public interface IEmployeeRepository
{
IQueryable<Employee> Select();
void Save(Employee item);
void Delete(Employee item);
bool IsUnique(Employee item);
}
We are going to use the IsUnique method to validate that we are not persisting two Employees with the same social security number. In order the help us with the test, we need some data. Add a new class called FakeEmployeeRepository to the UnitTests propject:
public class FakeEmployeeRepository : IEmployeeRepository
{
private List<Employee> data;

public FakeEmployeeRepository()
{
LoadData();
}

private void LoadData()
{
data
= new List<Employee>
{
new Employee{ ID=1, SocialSecurityNumber = "123-45-6789" }
};
}

public IQueryable<Employee> Select()
{
return data.AsQueryable();
}

public void Save(Employee item)
{
throw new NotImplementedException();
}

public void Delete(Employee item)
{
throw new NotImplementedException();
}

public bool IsUnique(Employee item)
{
return !data.Where(HasMatchingSocialSecurityNumber(item)).Any();
}

private Func<Employee, bool> HasMatchingSocialSecurityNumber(Employee item)
{
return x => !x.ID.Equals(item.ID) && x.SocialSecurityNumber.Equals(item.SocialSecurityNumber);
}
}
We need to update both our EmployeeValidatorTests and our EmployeeValidator classes:
[TestInitialize]
public void Init()
{
//arrange
target = new Employee();
validator
= new EmployeeValidator(new FakeEmployeeRepository());
}
public EmployeeValidator(IEmployeeRepository repository)
{
RuleFor(x
=> x.FirstName)
.NotEmpty()
.WithMessage(
"First name is required.")
.Length(
0, 50)
.WithMessage(
"First name cannot exceed 50 characters.")
.Matches(
@"^[A-Za-z\-\.\s]+$")
.WithMessage(
"First name contains invalid characters.");
}
It is time for us to write some tests that will exercise our new functionality. Add the following tests to the EmployeeValidatorTests class:
[TestMethod]
public void SocialSecurityNumber_NonUniqueValue_ValidationFails()
{
//arrange
target.SocialSecurityNumber = "123-45-6789";

//act
ValidationResult result = validator.Validate(target, x => x.SocialSecurityNumber);

//assert
validator.ContainsRuleFor<Employee>(x => x.SocialSecurityNumber);
result.AssertValidationFails(
"Social security number must be unique.");
}

[TestMethod]
public void SocialSecurityNumber_UniqueValue_ValidationPasses()
{
//arrange
target.SocialSecurityNumber = "987-65-4321";

//act
ValidationResult result = validator.Validate(target, x => x.SocialSecurityNumber);

//assert
validator.ContainsRuleFor<Employee>(x => x.SocialSecurityNumber);
result.AssertValidationPasses();
}
Let’s run these tests the ensure they fail. Add a new custom rule to our EmployeeValidator that uses our repository:
public class EmployeeValidator : AbstractValidator<Employee>
{
private IEmployeeRepository repository;

public EmployeeValidator(IEmployeeRepository repository)
{
this.repository = repository;

RuleFor(x
=> x.FirstName)
.NotEmpty()
.WithMessage(
"First name is required.")
.Length(
0, 50)
.WithMessage(
"First name cannot exceed 50 characters.")
.Matches(
@"^[A-Za-z\-\.\s]+$")
.WithMessage(
"First name contains invalid characters.");

RuleFor(x
=> x.SocialSecurityNumber)
.Must(BeAUniqueSocialSecurityNumber)
.WithMessage(
"Social security number must be unique.");
}

private bool BeAUniqueSocialSecurityNumber(Employee item, string socialSecurityNumber)
{
return repository.IsUnique(item);
}
Now let’s run our tests for the last time and watch with happy hearts the green light of testing Nirvana.

I hope you have enjoyed this series and learned some of the techniques available for simple and complex validation, business rules, and how to unit test them. If you have any questions or if I’ve left any loose ends, feel free to contact me. Thank you and happy coding!

Wednesday, September 22, 2010

Fluent Validation Part II – Dates

This is the third installment in this series:

  • Introduction – The basics or what Fluent Validation is
  • Part I – TDD with Fluent Validation and string validation

This time we will take a look at date validation. We will build upon the project we have been using from the beginning, so let’s get started by firing up Visual Studio, and opening our FluentValidation.Example.Solution. Add a new class to our Models project called Contract:

public class Contract
{
public DateTime ExecutionDate { get; set; }
public DateTime? ExpirationDate { get; set; }
}


In this example, our business requirements state a contract’s execution date must be before and contract’s expiration date (notice the expiration date is nullable) and both dates must be valid SQL dates - the year must be greater than 1753.



Note: If you have been following along in this series, there is a slight change that needs to be made to the ValidatorExtensions class to allow for complex type properties. Replace the existing ContainsRuleFor<T> method with the following:



        public static void ContainsRuleFor<T>(this IValidator validator, Expression<Func<T, object>> propertyExpression)
{
string propertyToTest = ConvertExpressionToString(propertyExpression);
ContainsRuleFor(validator, propertyToTest);
}

private static string ConvertExpressionToString<T>(Expression<Func<T, object>> propertyExpression)
{
if (typeof(UnaryExpression).Equals(propertyExpression.Body.GetType()))
{
var operand = ((UnaryExpression)propertyExpression.Body).Operand;
return ((MemberExpression)operand).Member.Name;
}

return ((MemberExpression)propertyExpression.Body).Member.Name;
}


With that update in place, and our business rules in mind, it is time to write our first test. Add a new class to the UnitTests project called ContractValidatorTests.



[TestClass]
public class ContractValidatorTests
{
private Contract target;
private IValidator<Contract> validator;

[TestInitialize]
public void Init()
{
//arrange
target = new Contract();
validator = new ContractValidator();
}

[TestMethod]
public void ExecutionDate_LessThanJanuary11753_ValidationFails()
{
//act
ValidationResult result = validator.Validate(target);

//assert
validator.ContainsRuleFor<Contract>(x => x.ExecutionDate);
result.AssertValidationFails("Execution date is invalid.");
}


At this point, our code will not compile until we’ve added a ContractValidator class. Add a new class name ContractValidator to the Models project.



public class ContractValidator : AbstractValidator<Contract>
{
}


Our test will compile and fail as expected – so far, so good.



Now, let’s implement our first validation rule and get that test to pass. Add the following to the ContractValidator class:



public ContractValidator()
{
RuleFor(x => x.ExecutionDate)
.Must(BeAValidSqlDate)
.WithMessage("Execution date is invalid.");
}

private bool BeAValidSqlDate(DateTime date)
{
if (ReferenceEquals(date, null))
{
return true;
}

return date.Year > 1753;
}


This time we’ve introduced the Must() predicate validator. There are several ways to implement this method, but in this case, we have chosen to delegate the logic to the BeAValidSqlDate method (this may be an unusual name for a method, but it reads better in context). Let’s run our test again and it will pass. This method will only work for execution date, not expiration date as it is a nullable type. We’ll fix that shortly. 



I am going to add all of our tests now, and then walk through adding the validation rules.



[TestMethod]
public void ExecutionDate_Year1753_ValidationFails()
{
//arrange
target.ExecutionDate = DateTime.Parse("1/1/1753");

//act
ValidationResult result = validator.Validate(target, x => x.ExecutionDate);

//assert
validator.ContainsRuleFor<Contract>(x => x.ExecutionDate);
result.AssertValidationFails("Execution date is invalid.");
}

[TestMethod]
public void ExecutionDate_YearGreaterThan1753_ValidationPasses()
{
//arrange
target.ExecutionDate = DateTime.Parse("1/1/1754");

//act
ValidationResult result = validator.Validate(target, x => x.ExecutionDate);

//assert
validator.ContainsRuleFor<Contract>(x => x.ExecutionDate);
result.AssertValidationPasses();
}

[TestMethod]
public void ExecutionDate_GreaterThanExpirationDate_ValidationFails()
{
//arrange
target.ExecutionDate = DateTime.Today;
target.ExpirationDate = DateTime.Today.AddDays(-1);

//act
ValidationResult result = validator.Validate(target, x => x.ExecutionDate);

//assert
validator.ContainsRuleFor<Contract>(x => x.ExecutionDate);
result.AssertValidationFails("Execution date must be before expiration date.");
}


If we run our tests now, they will fail, again following the TDD method of red-green-refactor.



We could update our rules like this:



RuleFor(x => x.ExecutionDate)
.Must(BeAValidSqlDate)
.WithMessage("Execution date is invalid.")
.LessThan(x => x.ExpirationDate.Value)
.WithMessage("Execution date must be before expiration date.");


and ordinarily our tests would pass. Give it a try. Our tests are still failing. What happened? This is because of the nullable expiration date. In order to get our tests to pass, we must create a custom rule to accommodate the nullable expiration date. Update the ContractValidator so it looks like this:



public ContractValidator()
{
RuleFor(x => x.ExecutionDate)
.Must(BeAValidSqlDate)
.WithMessage("Execution date is invalid.");

Custom(x =>
{
if (ExecutionDateGreaterThanExpirationDate(x))
{
return new ValidationFailure("ExecutionDate", "Execution date must be before expiration date.");
}

return null;
});
}

private bool ExecutionDateGreaterThanExpirationDate(Contract contract)
{
if (ReferenceEquals(contract.ExpirationDate, null))
{
return false;
}

return contract.ExecutionDate > contract.ExpirationDate.Value;
}

private bool BeAValidSqlDate(DateTime date)
{
if (ReferenceEquals(date, null))
{
return true;
}

return date.Year > 1753;
}


With these updated in place, run your tests again. Now they all pass.



Remember earlier I said we would fix the BeAValidSqlDate method so it works with nullable DateTime properties? In order to do that, we need to make another change to the code. First, we will create a custom property validator. Add a new class to the Models project called SqlDateValidator:



public class SqlDateValidator : PropertyValidator
{
public SqlDateValidator()
: base("Year must be greater than 1753")
{
}

protected override bool IsValid(PropertyValidatorContext context)
{
DateTime? date = context.PropertyValue as DateTime?;

if (ReferenceEquals(date, null))
{
return true;
}

return date.Value.Year > 1753;
}
}


Notice that this class extends the PropertyValidator base class. Now let’s add a couple of tests for the expiration date and update our ContractValidator class:



[TestMethod]
public void ExpirationDate_Year1753_ValidationFails()
{
//arrange
target.ExpirationDate = DateTime.Parse("1/1/1753");

//act
ValidationResult result = validator.Validate(target, x => x.ExpirationDate);

//assert
validator.ContainsRuleFor<Contract>(x => x.ExpirationDate);
result.AssertValidationFails("Expiration date is invalid.");
}

[TestMethod]
public void ExpirationDate_YearGreaterThan1753_ValidationPasses()
{
//arrange
target.ExpirationDate = DateTime.Parse("1/1/1754");

//act
ValidationResult result = validator.Validate(target, x => x.ExpirationDate);

//assert
validator.ContainsRuleFor<Contract>(x => x.ExpirationDate);
result.AssertValidationPasses();
}

[TestMethod]
public void ExpirationDate_IsNull_ValidationPasses()
{
//act
ValidationResult result = validator.Validate(target, x => x.ExpirationDate);

//assert
validator.ContainsRuleFor<Contract>(x => x.ExpirationDate);
result.AssertValidationPasses();
}


Run the tests to verify they fail. Now for update the ContractValidator:



public ContractValidator()
{
RuleFor(x => x.ExecutionDate)
.SetValidator(new SqlDateValidator())
.WithMessage("Execution date is invalid.");


Custom(x =>
{
if (ExecutionDateGreaterThanExpirationDate(x))
{
return new ValidationFailure("ExecutionDate", "Execution date must be before expiration date.");
}

return null;
});

RuleFor(x => x.ExpirationDate)
.SetValidator(new SqlDateValidator())
.WithMessage("Expiration date is invalid.");
}

private bool ExecutionDateGreaterThanExpirationDate(Contract contract)
{
if (ReferenceEquals(contract.ExpirationDate, null))
{
return false;
}

return contract.ExecutionDate > contract.ExpirationDate.Value;
}


We’ve simplified our ContractValidator by using the SqlDateValidator class, which accommodates nullable and non-nullable DateTime properties. We’ve also created a reusable property validator. Now all of our tests will pass.



One thing to remember about the FluentValidation library, there are many ways to achieve the same result, some are trickier than others. Making sure we have unit tests to prove our validation works allows us to try different methods and refactor the code to find the best solution without fear of breaking existing functionality.



Next time we will take a look at validation using a repository.

Thursday, September 16, 2010

Upcoming Speaking Engagements

Thursday September 16th, 2010
SELU .NET User Group
Zen Coding
6:30-8:30pm
Fayard Hall Room 207 
Southeastern University Campus
More Info
Wednesday September 22th, 2010
AITP LSU Chapter 
Zen Coding 
Patrick F. Taylor Hall Room 2174
Louisiana State University
Baton Rouge, LA 70803-6316
6:00-7:15pm
More Info

Wednesday, September 15, 2010

Fluent Validation – Part I

In the introduction article of this series, we looked at a very basic example of how to use the Fluent Validation framework. Moving forward, we will be following a Test driven development (TDD) approach to creating and implementing our validation rules and classes (I am assuming you some have knowledge in this area, as this series is not about TDD. There are plenty of great resources on the web for this.)

So let’s get started by firing up Visual Studio, and creating a blank solution called FluentValidation.Example.Solution. We will add two projects to our solution, FluentValidation.Example.Models, and FluentValidation.Example.UnitTests (for unit testing I will be using the MSTest tool, but feel free to use NUnit or any other testing framework). Also, add a reference to the Models project in our UnitTests project and a reference to the FluentValidation.dll in our UnitTests and Modes projects (this can be downloaded here. I am using the 1.3 version).

Add a new class to your UnitTests project called ValidatorExtensions (you may need to add using statements for FluentValidation.Validators and FluentValidation.Results to get this code to compile):

public static class ValidatorExtensions
{
public static void ContainsRuleFor<T>(this IValidator validator, Expression<Func<T, object>> propertyExpression)
{
string propertyToTest = ((MemberExpression)propertyExpression.Body).Member.Name;
ContainsRuleFor(validator, propertyToTest);
}

public static void ContainsRuleFor(this IValidator validator, string propertyToTest)
{
var descriptor = validator.CreateDescriptor();
var validationRules = descriptor.GetValidatorsForMember(propertyToTest);
List<IPropertyValidator> listToTest = new List<IPropertyValidator>(validationRules);
Assert.IsTrue(listToTest.Count > 0, "No validation rules have been defined for " + propertyToTest);
}

public static void AssertValidationFails(this ValidationResult results, string errorMessage)
{
Assert.IsFalse(results.IsValid, "Object is valid");
Assert.IsTrue(results.Errors.Count > 0, "No validation errors were reported");
Assert.AreEqual(errorMessage, results.Errors[0].ErrorMessage);
}

public static void AssertValidationPasses(this ValidationResult results)
{
Assert.IsTrue(results.IsValid, "Object is not valid");
Assert.AreEqual(0, results.Errors.Count, "Validation errors were reported");
}
}

This may look like a lot of code, and you may not understand some of it right now. That’s ok. As we proceed, it will start to make more sense. Our first two extension methods are called ContainsRuleFor. These methods interrogate our validator class looking to see if any validation rules exist for a given property. This is important, because our unit tests will incorrectly pass when no rules exist, which makes sense. If there is no rule to break, the test passes. Since we are going to follow a test-driven approach, we want our tests to fail until we have implemented the validation rules and these methods help facilitate that behavior. Our next two extension methods, AssertValidationFails and AssertValidationPasses test the results of our validation and check to see if the object is valid when it should be. For this example, we are going to create a simple Employee class and add some apply some validation rules to it. Add a new class to the Models project called Employee:

public class Employee
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}

Our business requirements state that an employee must have a first and last name, and the maximum number of characters is fifty. We also don’t want any numbers or special characters in our names so we will limit the input to the ABCs, a dash, a space, and a period. With these rules in mind, it is time to write our first test. Add a new class to the UnitTests project called EmployeeValidatorTests.

[TestClass]
public class EmployeeValidatorTests
{
private Employee target;
private IValidator<Employee> validator;

[TestInitialize]
public void Init()
{
//arrange
target = new Employee();
validator = new EmployeeValidator();
}

[TestMethod]
public void FirstName_OnInitialize_ValidationFails()
{
//act
ValidationResult result = validator.Validate(target, x => x.FirstName);

//assert
validator.ContainsRuleFor<Employee>(x => x.FirstName);
result.AssertValidationFails("First name is required.");
}
}

At this point, our code will not compile until we’ve added a few things. Add using statements for FluentValidation, FluentValidation.Results, and to our Models project namespace. Next we need to create an EmployeeValidator class. Add a new class name EmployeeValidator to the Models project.

public class EmployeeValidator : AbstractValidator<Employee>
{
}

Notice that it extends the AbstractValidator base class provided by the FluentValidation framework. This is how all of our validation classes will begin. If we run this test now, it will fail – which is the result we are looking for (this is in line with the TDD mantra “red-green-refactor”). Now, let’s implement our first validation rule. Add the following to the EmployeeValidator class:

public EmployeeValidator()
{
RuleFor(x => x.FirstName)
.NotEmpty()
.WithMessage("First name is required.");
}

We’ve added a constructor and defined our first validation rule for the FirstName property – it must not be empty or a value is required (the Fluent Validation framework defines “empty” as null or an empty string). Run the test again. Our test passed! We are one step closer to coding Nirvana. Using a TDD approach, we would normally follow a “red-green-refactor” process of writing a failing test, then writing enough code to get the test to pass, then refactor the code to production quality. I am going to skip ahead slightly and just include all of the remaining tests for the FirstName property:

[TestMethod]
public void FirstName_EmptyString_ValidationFails()
{
//arrange
target.FirstName = string.Empty;

//act
ValidationResult result = validator.Validate(target, x => x.FirstName);

//assert
validator.ContainsRuleFor<Employee>(x => x.FirstName);
result.AssertValidationFails("First name is required.");
}

[TestMethod]
public void FirstName_Null_ValidationFails()
{
//arrange
target.FirstName = null;

//act
ValidationResult result = validator.Validate(target, x => x.FirstName);

//assert
validator.ContainsRuleFor<Employee>(x => x.FirstName);
result.AssertValidationFails("First name is required.");
}

[TestMethod]
public void FirstName_GreaterThan50Characters_ValidationFails()
{
//arrange
target.FirstName = "".PadRight(51, 'X');

//act
ValidationResult result = validator.Validate(target, x => x.FirstName);

//assert
validator.ContainsRuleFor<Employee>(x => x.FirstName);
result.AssertValidationFails("First name cannot exceed 50 characters.");
}

[TestMethod]
public void FirstName_StartsWithANumericValue_ValidationFails()
{
//arrange
target.FirstName = "24Name";

//act
ValidationResult result = validator.Validate(target, x => x.FirstName);

//assert
validator.ContainsRuleFor<Employee>(x => x.FirstName);
result.AssertValidationFails("First name contains invalid characters.");
}

[TestMethod]
public void FirstName_ContainsANumericValue_ValidationFails()
{
//arrange
target.FirstName = "Name24Number";

//act
ValidationResult result = validator.Validate(target, x => x.FirstName);

//assert
validator.ContainsRuleFor<Employee>(x => x.FirstName);
result.AssertValidationFails("First name contains invalid characters.");
}

[TestMethod]
public void FirstName_EndsWithANumericValue_ValidationFails()
{
//arrange
target.FirstName = "Name24";

//act
ValidationResult result = validator.Validate(target, x => x.FirstName);

//assert
validator.ContainsRuleFor<Employee>(x => x.FirstName);
result.AssertValidationFails("First name contains invalid characters.");
}

[TestMethod]
public void FirstName_IsANumericValue_ValidationFails()
{
//arrange
target.FirstName = "254";

//act
ValidationResult result = validator.Validate(target, x => x.FirstName);

//assert
validator.ContainsRuleFor<Employee>(x => x.FirstName);
result.AssertValidationFails("First name contains invalid characters.");
}

[TestMethod]
public void FirstName_NotEmptyLessThan50CharactersWithNoNumericValues_ValidationPasses()
{
//arrange
target.FirstName = "Jack";

//act
ValidationResult result = validator.Validate(target, x => x.FirstName);

//assert
validator.ContainsRuleFor<Employee>(x => x.FirstName);
result.AssertValidationPasses();
}

Some of these tests will fail because we have not updated our validator to include the rules for string length and RegEx validation. Update the EmployeeValidator class constructor so it looks like this:

public EmployeeValidator()
{
RuleFor(x => x.FirstName)
.NotEmpty()
.WithMessage("First name is required.")
.Length(0, 50)
.WithMessage("First name cannot exceed 50 characters.")
.Matches(@"^[A-Za-z\-\.\s]+$")
.WithMessage("First name contains invalid characters.");
}

Our validation rules have now been extended to include a range validation for our string (0 to 50 characters), and a RegEx validation for letters, a dash, a period, and a space. You may be wondering why I chose to set the minimum length to 0 when our requirements state that the FirstName property is required. Well, the NotEmpty rule covers that, and I only want to show the user what state requires their attention. If the Length validation was set to Length(1, 50) and the user had not provided a value for FirstName, the validation result would show two error messages: “First name is required”, “First name cannot exceed 50 characters”. The first message makes sense, but the second doesn’t apply since the user has yet to supply a value. After that lengthy explanation, run the tests again and they should all pass. Whew! We’ve covered a lot of ground this time. You've seen how to use FluentValidation with Test-Driven Development, and we’ve created a few extension methods to help us. We’ve done some pretty extensive testing of our business rules, and you can see how to do some really powerful string validation including limiting the number of characters and using RegEx. As an exercise for the reader, implement the tests for the LastName property. Next time we will look at validation for other data types and how to create custom validation rules.

Wednesday, September 8, 2010

Fluent Validation - Introduction

I have been using the Fluent Validation library for a few years and wanted to share some of the tricks I have learned. This will be broken into a series of posts that will gradually introduce more complex functionality and examples.

So what is “fluent validation”? From their website:

A small validation library for .NET that uses a fluent interface and lambda expressions for building validation rules for your business objects.

And it does this very well. To get started, download the latest version (the examples here are using the 1.3 version).

In this post, I am just going to show you the mechanics of creating a validator class and how to use it. For this example, we will have two classes, Employee and EmployeeValidator.

public class Employee
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}

public class EmployeeValidator : AbstractValidator<Employee>
{
public EmployeeValidator()
{
RuleFor(x => x.FirstName)
.NotEmpty()
.WithMessage("First name is required.");

RuleFor(x => x.LastName)
.NotEmpty()
.WithMessage("Last name is required.");
}
}

Our Employee class is pretty basic so let’s spend some time examining our validator class. First, notice that it extends the AbstractValidator base class from the FluentValidator library (you may need to add a reference to the FluentValidation.dll you downloaded earlier). Next, we define a set of business rules in the constructor. In this case our business rules are:

  1. First name cannot be null or empty
  2. Last name cannot be null or empty

To define a rule, we use the RuleFor method that uses a Lambda expression to define what property the rule will apply to. There are several built-in validators for strings, numbers, predicates, RegEx, even an email validator (you can also create custom validators which I will get to later in the series).

Now that we have a validator, the usage is quite simple. We pass our object to our validator through the Validate method and receive a ValidationResult:

class Program
{
static void Main(string[] args)
{
Employee employee = new Employee();
IValidator validator = new EmployeeValidator();

ValidationResult result = validator.Validate(employee);
ShowResult(result);

employee.FirstName = "Jack";
employee.LastName = "Handy";
result = validator.Validate(employee);
ShowResult(result);
}

static void ShowResult(ValidationResult result)
{
if (result.IsValid)
{
Console.WriteLine("Employee is valid.");
}
else
{
Console.WriteLine("Employee is NOT valid.");
List<ValidationFailure> errors = new List<ValidationFailure>(result.Errors);
errors.ForEach(x => Console.WriteLine(x.ErrorMessage));
}
}
}

According to our validation rules, when we instantiate a new Employee object, it will be invalid because the FirstName and LastName properties will be empty. The first time we call ShowResult, our employee object will be invalid. We iterate over the Errors collection of the ValidationResult object and write the error messages to the console window. The second time we call ShowResult, the FirstName and LastName properties have been set, and our object is valid.

Running the above code will result in:

image


Hopefully this very simple example gives you an idea of how this might be used in your domain. Next time we will take a TDD approach to writing validation rules and look at some more complex examples.

Wednesday, September 1, 2010

Something a Little Different

I wanted to share something that served as an inspiration to General Douglas MacArthur, Akio Morita, co-founder of Sony, Yoichi Morishita, former President of Panasonic, and others. In 1990, reporters and employees gathered to hear the plans for the future of Pittsburgh, Pennsylvania's National Steel Corporation. The chairman, Kokichi Hagiwara, began his meeting by reading his business plan, the poem “Youth” by Samuel Ullman.

Youth

By Samuel Ullman

Youth is not a time of life; it is a state of mind; it is not a matter of rosy cheeks, red lips and supple knees; it is a matter of the will, a quality of the imagination, a vigor of the emotions; it is the freshness of the deep springs of life.

Youth means a temperamental predominance of courage over timidity of the appetite, for adventure over the love of ease. This often exists in a man of sixty more than a boy of twenty. Nobody grows old merely by a number of years. We grow old by deserting our ideals.

Years may wrinkle the skin, but to give up enthusiasm wrinkles the soul. Worry, fear, self-distrust bows the heart and turns the spirit back to dust.

Whether sixty or sixteen, there is in every human being’s heart the lure of wonder, the unfailing child-like appetite of what’s next, and the joy of the game of living. In the center of your heart and my heart there is a wireless station; so long as it receives messages of beauty, hope, cheer, courage and power from men and from the infinite, so long are you young.

When the aerials are down, and your spirit is covered with snows of cynicism and the ice of pessimism, then you are grown old, even at twenty, but as long as your aerials are up, to catch the waves of optimism, there is hope you may die young at eighty.