Fluent API or Fluent Interfaces
https://www.primaryobjects.com/2011/02/07/fluent-interfaces-in-c-net-with-expression-builder-method-chaining-and-rpg-games/
Fluent XML document validation
Fluent Interface
An interface designed in a way that actions are chained together gives a fluent, readable and natural style of logic
https://en.wikipedia.org/wiki/Fluent_interface
- It improves code readability and flow, like writing sentences
- It is commonly used in query builders, configuration settings, and ORMs (like Entity Framework).
In this article you will have a POC (Proof of Concept) which uses a fluent interface for the steps needed to fully validate an XML document
A fluent interface fits perfectly with the step you need to go though in a specific ordering when you validate XML data
Interfaces we are going to use
- Create Document
- Create prepares the document for validation
- Check syntax
- First check document for syntax errors
- Check structure
- Next check the document for structural integrity, eg do schema validation
- Check content
- Basic validation is done we can check the document for the business requirements
- Transform document
- Or we are ready to style and transform the document to a readable presentation by using eg a stylesheet
- Result
- Return the validation result
Main class to stich it all together
- XMLValidator
- Inherits
- Document
- ValidateSyntax
- ValidateStructure
- Validated
- CheckContent
- TransformContent
- ValidationResult
The resulting work flow
- Fulfilment
- Validation occurs in strict order or chain defined by the returned interface in the methods called
- Response is added to StringBuilder by each step
- Validation result is returned to user and thus the chain is terminated
POC of FluentValidator
All interfaces
Steps needed for the document object to be prober validated
// Interfaces used for building the fluent validator
namespace FluentValidator.Interface
{
/// <summary>
/// Prepare document for validation
/// </summary>
public interface IDocument
{
public IValidateSyntax Create();
}
/// <summary>
/// RuUn a syntax check on the document
/// </summary>
public interface IValidateSyntax
{
public IValidateStructure CheckSyntax();
}
/// <summary>
/// Validate the structure of the document using a schema
/// </summary>
public interface IValidateStructure
{
public IValidated CheckStructure();
}
/// <summary>
/// Document is structural and semantic valid
/// </summary>
public interface IValidated
{
public IValidationResult CheckContent();
public IValidationResult TransformContent();
}
/// <summary>
/// Return validation result
/// </summary>
public interface IValidationResult
{
public string GetMessage();
}
}
The concrete class implementation using the interfaces we have created
using System.Text;
using FluentValidator.Interface;
namespace FluentValidator.Validator
{
/// <summary>
/// Concrete implementation of the fluent validator
/// </summary>
/// <seealso cref="FluentValidator.Interface.IValidateSyntax" />
/// <seealso cref="FluentValidator.Interface.IValidateStructure" />
/// <seealso cref="FluentValidator.Interface.IValidated" />
/// <seealso cref="FluentValidator.Interface.IValidationResult" />
/// <seealso cref="FluentValidator.Interface.IDocument" />
public class ValidateXML : IValidateSyntax, IValidateStructure, IValidated, IValidationResult, IDocument
{
private StringBuilder message = new StringBuilder();
/// <summary>
/// Creates the instance.
/// </summary>
/// <returns></returns>
public IValidateSyntax Create()
{
return new ValidateXML();
}
/// <summary>
/// Checks the syntax.
/// </summary>
/// <returns>IValidateStructure</returns>
public IValidateStructure CheckSyntax()
{
message.Append("Syntax validated\r\n");
return this;
}
/// <summary>
/// Checks the structure.
/// </summary>
/// <returns>IValidated</returns>
public IValidated CheckStructure()
{
message.Append("Structure validated\r\n");
return this;
}
/// <summary>
/// Checks the content.
/// </summary>
/// <returns>IValidationResult</returns>
public IValidationResult CheckContent()
{
message.Append("Content validated\r\n");
return this;
}
/// <summary>
/// Transforms the content.
/// </summary>
/// <returns>IValidationResult</returns>
public IValidationResult TransformContent()
{
message.Append("Stylesheet applied\r\n");
return this;
}
/// <summary>
/// Gets the message.
/// </summary>
/// <returns>string</returns>
public string GetMessage()
{
return message.ToString();
}
}
}
POC program to run
using FluentValidator.Validator;
namespace FluentValidator
{
internal class Program
{
static void Main(string[] args)
{
ValidateXML validate = new ValidateXML();
Console.WriteLine("Validate XML file:");
Console.WriteLine("------------------");
Console.WriteLine(
validate.Create()
.CheckSyntax()
.CheckStructure()
.CheckContent()
.GetMessage()
);
Console.WriteLine("");
Console.WriteLine("Validate and transform XML file:");
Console.WriteLine("--------------------------------");
Console.WriteLine(
validate.Create()
.CheckSyntax()
.CheckStructure()
.TransformContent()
.GetMessage()
);
Console.ReadKey();
}
}
}
Console output from the program
Validate XML file:
------------------
Syntax validated
Structure validated
Content validated
Validate and transform XML file:
--------------------------------
Syntax validated
Structure validated
Stylesheet applied
Try the example at Fiddle
https://dotnetfiddle.net/gqNieE