mirror of https://github.com/ogoun/Zero.git
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.
140 lines
5.0 KiB
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();
|
|
}
|
|
}
|
|
} |