You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel/Services/Specification/Services/SpecificationBuilder.cs

140 lines
5.0 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using ZeroLevel.Contracts.Specification.Building;
using ZeroLevel.Services.Trees;
namespace ZeroLevel.Specification
{
/// <summary>
/// Creates a specification using a specific constructor.
/// </summary>
public class SpecificationBuilder :
ISpecificationBuilder,
IEquatable<SpecificationBuilder>
{
/// <summary>
/// Type of specification
/// </summary>
private readonly Type _instanceType;
/// <summary>
/// List of Constructor Parameters
/// </summary>
private readonly List<SpecificationParameter> _values =
new List<SpecificationParameter>();
/// <summary>
/// Constructor name
/// </summary>
public string Name { get; }
public Type FilterType { get { return _instanceType; } }
public IEnumerable<SpecificationParameter> Parameters { get { return _values; } }
internal SpecificationBuilder(string name,
List<SpecificationParameter> parameters,
Type specificationType)
{
Name = name;
_instanceType = specificationType;
_values = parameters;
}
/// <summary>
/// Parameter traversal
/// </summary>
public void ParametersTraversal(Action<SpecificationParameter> parameterHandler)
{
foreach (var p in _values)
{
parameterHandler(p);
}
}
/// <summary>
/// Build specification
/// </summary>
public ISpecification<T> Build<T>()
{
var parameters = new object[_values.Count];
for (int i = 0; i < _values.Count; i++)
{
switch (SpecificationConstructorParametersResolver.
ResolveParameterKind(_instanceType, _values[i].ParameterName))
{
case SpecificationConstructorParameterKind.Enum:
if (_values[i].Value is string[])
{
parameters[i] = (_values[i].Value as string[]).
Select(name =>
SpecificationConstructorParametersResolver.
GetEnumInstance(_instanceType, _values[i].ParameterName, name)).
ToArray();
}
else
{
parameters[i] = SpecificationConstructorParametersResolver.GetEnumInstance(_instanceType, _values[i].ParameterName, _values[i].Value as string);
}
break;
case SpecificationConstructorParameterKind.Tree:
var tree = (ITree)_values[i].Value;
var list = new List<object>();
Action<ITreeNode> visitor = null;
visitor = new Action<ITreeNode>(node =>
{
if (node.IsSelected)
{
if (node.Tag != null || _values[i].ParameterType.GetElementType() != typeof(string))
{
list.Add(node.Tag);
}
else
{
list.Add(node.Name);
}
}
foreach (var n in node.Children)
visitor(n);
});
foreach (var n in tree.RootNodes)
visitor(n);
var a = Array.CreateInstance(_values[i].ParameterType.GetElementType(), list.Count);
for (int index = 0; index < list.Count; index++)
a.SetValue(list[index], index);
parameters[i] = a;
break;
default:
parameters[i] = _values[i].Value;
break;
}
}
return (ISpecification<T>)Activator.CreateInstance(_instanceType, parameters);
}
public override bool Equals(object obj)
{
return this.Equals(obj as ISpecificationBuilder);
}
public bool Equals(ISpecificationBuilder other)
{
if (null == other) return false;
if (object.ReferenceEquals(this, other)) return true;
if (_instanceType != other.FilterType) return false;
return _values.SequenceEqual(other.Parameters);
}
public bool Equals(SpecificationBuilder other)
{
return this.Equals(other as ISpecificationBuilder);
}
public override int GetHashCode()
{
return _instanceType.GetHashCode() ^ Name.GetHashCode();
}
}
}

Powered by TurnKey Linux.