HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Fluent Interface for a XmlQueryBuilder

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
xmlquerybuilderinterfacefluentfor

Problem

In this answer I suggested using a fluent interface "builder" to replace all the hard-coded, repetitive and quite error-prone inline XML string concatenations.

This code might need a bit of tweaking to work perfectly with the OP's code in the question this code is following-up on, but it seems to work as expected. Thoughts?

public enum XmlQueryOperator
{
    Equals,
    LessThan,
    LessThanOrEqual,
    GreaterThan,
    GreaterThanOrEqual
}


```
public class XmlQueryBuilder
where TEntity : class
{
private readonly XDocument _xDoc = new XDocument();
private readonly XElement _queryNode = new XElement("query");

public XmlQueryBuilder()
{
var rootNode = new XElement("queryxml");
rootNode.SetAttributeValue("version", "1.0");

var entityNode = new XElement("entity");
entityNode.Value = typeof (TEntity).Name;

rootNode.Add(entityNode);
_xDoc.Add(rootNode);
}

public XmlQueryBuilder Where(Expression> property, XmlQueryOperator operation, string value)
{
var xCondition = new XElement("condition");
var xField = new XElement("field");
xField.Value = GetPropertyName(property);

var xExpression = new XElement("expression");
xExpression.SetAttributeValue("op", operation.ToString());
xExpression.Value = value;

xField.Add(xExpression);
xCondition.Add(xField);

_queryNode.Add(xCondition);
return this;
}

public override string ToString()
{
var parent = _xDoc.Element("queryxml");
if (parent == null) throw new InvalidOperationException("root node was not created.");

parent.Add(_queryNode);
return _xDoc.ToString();
}

private string GetPropertyName(Expression> propertyLambda)
{
// credits http://stackoverflow.com/questions/671968/retrieving-property-name-from-lambda-expression/672212#672212 (modified to return property name)
var type = typeof(

Solution

ToString() does too many things, it should only be calling _xDoc.ToString(); it has side-effects that make it dangerous to call more than once:

var foo = builder.ToString()
Console.WriteLine(builder.ToString());
Console.ReadLine();


Will not produce the expected output, and will not throw an exception either, resulting in an XML document with _queryNode showing up as many times as ToString() was called.

Code Snippets

var foo = builder.ToString()
Console.WriteLine(builder.ToString());
Console.ReadLine();

Context

StackExchange Code Review Q#49003, answer score: 4

Revisions (0)

No revisions yet.