/
ArrayPropertyBinder.cs
69 lines (55 loc) · 2.12 KB
/
ArrayPropertyBinder.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using FubuCore.Conversion;
using System.Linq;
namespace FubuCore.Binding
{
[Description("Binds an array")]
public class ArrayPropertyBinder : IPropertyBinder
{
private readonly ConverterLibrary _library;
public ArrayPropertyBinder(ConverterLibrary library)
{
_library = library;
}
public bool Matches(PropertyInfo property)
{
var propertyType = property.PropertyType;
if (!propertyType.IsArray) return false;
var elementType = propertyType.GetElementType();
return !_library.CanBeParsed(elementType);
}
public void Bind(PropertyInfo property, IBindingContext context)
{
var builder = typeof (ArrayBuilder<>).CloseAndBuildAs<IArrayBuilder>(property.PropertyType.GetElementType());
builder.FillValues(property, context);
}
public interface IArrayBuilder
{
void FillValues(PropertyInfo property, IBindingContext context);
}
public class ArrayBuilder<T> : IArrayBuilder
{
public void FillValues(PropertyInfo property, IBindingContext context)
{
var requests = context.GetEnumerableRequests(property.Name).ToList();
// TODO -- need an end to end test on this behavior
if (!requests.Any()) return;
var data = new T[requests.Count];
for (int i = 0; i < requests.Count; i++)
{
var requestData = requests[i];
context.Logger.PushElement(typeof(T));
// TODO -- got to add the BindResult to context to store it later
context.BindObject(requestData, typeof (T), o =>
{
data[i] = (T) o;
});
}
property.SetValue(context.Object, data, null);
}
}
}
}