-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
MvxSourceBindingFactory.cs
111 lines (97 loc) · 4.32 KB
/
MvxSourceBindingFactory.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// MvxSourceBindingFactory.cs
// (c) Copyright Cirrious Ltd. http://www.cirrious.com
// MvvmCross is licensed using Microsoft Public License (Ms-PL)
// Contributions and inspirations noted in readme.md and license.txt
//
// Project Lead - Stuart Lodge, @slodge, me@slodge.com
using System.Collections.Generic;
using System.Linq;
using Cirrious.MvvmCross.Binding.Bindings.Source.Chained;
using Cirrious.MvvmCross.Binding.Bindings.Source.Construction.PropertyTokens;
using Cirrious.MvvmCross.Binding.Bindings.Source.Leaf;
using Cirrious.MvvmCross.Binding.Interfaces.Bindings.Source;
using Cirrious.MvvmCross.Binding.Interfaces.Bindings.Source.Construction;
using Cirrious.MvvmCross.Exceptions;
using Cirrious.MvvmCross.ExtensionMethods;
using Cirrious.MvvmCross.Interfaces.ServiceProvider;
namespace Cirrious.MvvmCross.Binding.Bindings.Source.Construction
{
public class MvxSourceBindingFactory
: IMvxSourceBindingFactory
, IMvxServiceConsumer
{
private static readonly char[] FieldSeparator = new[] {'.', '['};
private IMvxPropertyTokeniser _propertyTokeniser;
private IMvxPropertyTokeniser PropertyTokeniser
{
get
{
if (_propertyTokeniser == null)
{
_propertyTokeniser = this.GetService<IMvxPropertyTokeniser>();
}
return _propertyTokeniser;
}
}
#region IMvxSourceBindingFactory Members
public IMvxSourceBinding CreateBinding(object source, string combinedPropertyName)
{
if (combinedPropertyName == null)
combinedPropertyName = "";
var tokens = PropertyTokeniser.Tokenise(combinedPropertyName);
var queue = new List<MvxBasePropertyToken>(tokens);
return CreateBinding(source, queue);
}
#warning CreateBinding should probably take an IList to make the code run quicker!
public IMvxSourceBinding CreateBinding(object source, IList<MvxBasePropertyToken> tokens)
{
if (tokens == null || tokens.Count == 0)
{
throw new MvxException("empty token list passed to CreateBinding");
}
var currentToken = tokens[0];
if (tokens.Count == 1)
{
return CreateLeafBinding(source, currentToken);
}
else
{
var remainingTokens = tokens.Skip(1).ToList();
return CreateChainedBinding(source, currentToken, remainingTokens);
}
}
private static MvxChainedSourceBinding CreateChainedBinding(object source, MvxBasePropertyToken propertyToken,
List<MvxBasePropertyToken> remainingTokens)
{
if (propertyToken is MvxIndexerPropertyToken)
{
return new MvxIndexerChainedSourceBinding(source, (MvxIndexerPropertyToken) propertyToken,
remainingTokens);
}
else if (propertyToken is MvxPropertyNamePropertyToken)
{
return new MvxSimpleChainedSourceBinding(source, (MvxPropertyNamePropertyToken) propertyToken,
remainingTokens);
}
throw new MvxException("Unexpected property chaining - seen token type {0}",
propertyToken.GetType().FullName);
}
private static IMvxSourceBinding CreateLeafBinding(object source, MvxBasePropertyToken propertyToken)
{
if (propertyToken is MvxIndexerPropertyToken)
{
return new MvxIndexerLeafPropertyInfoSourceBinding(source, (MvxIndexerPropertyToken) propertyToken);
}
else if (propertyToken is MvxPropertyNamePropertyToken)
{
return new MvxSimpleLeafPropertyInfoSourceBinding(source, (MvxPropertyNamePropertyToken) propertyToken);
}
else if (propertyToken is MvxEmptyPropertyToken)
{
return new MvxDirectToSourceBinding(source);
}
throw new MvxException("Unexpected property source - seen token type {0}", propertyToken.GetType().FullName);
}
#endregion
}
}