Skip to content
Browse files

lots of accessor cleanup to handle methods and indexers better

  • Loading branch information...
1 parent 9c54937 commit 8693e74d1d764636eff9fcce073b8ad74623fd0b @jeremydmiller jeremydmiller committed
View
2 VERSION.txt
@@ -1 +1 @@
-BUILD_VERSION = "1.0.0"
+BUILD_VERSION = "1.0.1"
2 buildsupport
@@ -1 +1 @@
-Subproject commit 6bb8aa4ef73564752c2b394a7d869a522abe8ca1
+Subproject commit d74703ea397f4153b5d06703ced85d604f777257
View
4 src/FubuCore.Docs/FubuCore.Docs.csproj
@@ -31,8 +31,8 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
- <Reference Include="FubuDocs, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>..\packages\FubuDocs.0.0.0.10\lib\net40\FubuDocs.dll</HintPath>
+ <Reference Include="FubuDocs">
+ <HintPath>..\packages\FubuDocs.0.0.0.46\lib\net40\FubuDocs.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
View
2 src/FubuCore.Docs/packages.config
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="FubuDocs" version="0.0.0.10" targetFramework="net40" />
+ <package id="FubuDocs" version="0.0.0.46" targetFramework="net40" />
</packages>
View
10 src/FubuCore.Testing/Reflection/PropertyChainTester.cs
@@ -221,6 +221,16 @@ public void propertyChain_can_get_child_accessor()
}
[Test]
+ public void propertyChain_can_get_child_accessor_from_indexer()
+ {
+ var expected = ReflectionHelper.GetAccessor<Target>(x => x.Child.GrandChildren[1].Name);
+ var child = ReflectionHelper.GetAccessor<Target>(x => x.Child.GrandChildren[1])
+ .GetChildAccessor<GrandChildTarget>(x => x.Name);
+
+ child.ShouldEqual(expected);
+ }
+
+ [Test]
public void propertyChain_can_get_the_name()
{
ReflectionHelper.GetAccessor<Target>(t => t.Child.GrandChild.BirthDay).Name.ShouldEqual(
View
22 src/FubuCore.Testing/Reflection/ReflectionHelperTester.cs
@@ -212,6 +212,8 @@ public void TryingToCallSetDoesNotBlowUpIfTheIntermediateChildrenAreNotThere()
}
+
+
[Test]
public void get_value_by_indexer_when_the_indexer_is_variable_reference()
{
@@ -314,9 +316,29 @@ public void get_value_by_indexer_when_the_indexer_is_variable_reference_of_a_com
}
+ [Test]
+ public void get_owner_type_by_indexer()
+ {
+ var accessor = ReflectionHelper.GetAccessor<Target>(x => x.Child.Grandchildren[1].Deep.Color);
+ accessor.OwnerType.ShouldEqual(typeof (DeepTarget));
+ ReflectionHelper.GetAccessor<Target>(x => x.Child.Grandchildren[1]).OwnerType.ShouldEqual(typeof(ChildTarget));
+ }
+ [Test]
+ public void get_inner_property_with_method_accessor()
+ {
+ var accessor = ReflectionHelper.GetAccessor<Target>(x => x.Child.Grandchildren[1]);
+ accessor.PropertyType.ShouldEqual(typeof (GrandChildTarget));
+ }
+ [Test]
+ public void get_field_name_by_method_accessor()
+ {
+ var accessor = ReflectionHelper.GetAccessor<Target>(x => x.Child.Grandchildren[1]);
+ accessor.FieldName.ShouldEqual("Grandchildren[1]");
+ accessor.Name.ShouldEqual("ChildGrandchildren[1]");
+ }
}
[TestFixture]
View
2 src/FubuCore.Testing/packages.config
@@ -2,4 +2,4 @@
<packages>
<package id="NUnit" version="2.5.10.11092" />
<package id="RhinoMocks" version="3.6.1" />
-</packages>
+</packages>
View
3 src/FubuCore/Reflection/IValueGetter.cs
@@ -9,6 +9,9 @@ public interface IValueGetter
string Name { get; }
Type DeclaringType { get; }
+ Type ValueType { get; }
+
Expression ChainExpression(Expression body);
+ void SetValue(object target, object propertyValue);
}
}
View
10 src/FubuCore/Reflection/MethodValueGetter.cs
@@ -42,6 +42,11 @@ public Type DeclaringType
get { return _methodInfo.DeclaringType; }
}
+ public Type ValueType
+ {
+ get { return _methodInfo.ReturnType; }
+ }
+
public Type ReturnType
{
get { return _methodInfo.ReturnType; }
@@ -52,6 +57,11 @@ public Expression ChainExpression(Expression body)
throw new NotSupportedException();
}
+ public void SetValue(object target, object propertyValue)
+ {
+ throw new NotSupportedException();
+ }
+
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
View
120 src/FubuCore/Reflection/PropertyChain.cs
@@ -9,7 +9,6 @@ namespace FubuCore.Reflection
public class PropertyChain : Accessor
{
private readonly IValueGetter[] _chain;
- private readonly SingleProperty _innerProperty;
private readonly IValueGetter[] _valueGetters;
@@ -21,14 +20,14 @@ public PropertyChain(IValueGetter[] valueGetters)
_chain[i] = valueGetters[i];
}
- var innerValueGetter = valueGetters[valueGetters.Length - 1] as PropertyValueGetter;
- if (innerValueGetter != null)
- {
- _innerProperty = new SingleProperty(innerValueGetter.PropertyInfo);
- }
_valueGetters = valueGetters;
}
+ public IValueGetter[] ValueGetters
+ {
+ get { return _valueGetters; }
+ }
+
public void SetValue(object target, object propertyValue)
{
@@ -41,11 +40,6 @@ public void SetValue(object target, object propertyValue)
setValueOnInnerObject(target, propertyValue);
}
- protected virtual void setValueOnInnerObject(object target, object propertyValue)
- {
- _innerProperty.SetValue(target, propertyValue);
- }
-
public object GetValue(object target)
{
target = findInnerMostTarget(target);
@@ -60,36 +54,58 @@ public object GetValue(object target)
public Type OwnerType
{
- get
+ get
{
- //TODO: Does MethodValueGetter need to provide some kind of OwnerType if its the last item in the chain?
- //assuming the last item is a PropertyValueGetter for now...
- //example: Person.FamilyMembers[0].FirstName would have the _chain.Last() output a MethodValueGetter
- //in which case we would not be able to get to our OwnerType the same way as being done below
+ // Check if we're an indexer here
+ if (_valueGetters.Last() is MethodValueGetter)
+ {
+ var nextUp = _chain.Reverse().Skip(1).FirstOrDefault() as PropertyValueGetter;
+ if (nextUp != null)
+ {
+ return nextUp.PropertyInfo.PropertyType;
+ }
+ }
var propertyGetter = _chain.Last() as PropertyValueGetter;
return propertyGetter != null ? propertyGetter.PropertyInfo.PropertyType : null;
}
}
- public string FieldName { get { return _innerProperty.FieldName; } }
-
- public Type PropertyType { get { return _innerProperty.PropertyType; } }
+ public string FieldName
+ {
+ get {
+ var last = _valueGetters.Last();
+ if (last is PropertyValueGetter) return last.Name;
- public PropertyInfo InnerProperty { get { return _innerProperty.InnerProperty; } }
+ var previous = _valueGetters[_valueGetters.Count() - 2];
+ return previous.Name + last.Name;
+ }
+ }
- public Type DeclaringType { get { return _chain[0].DeclaringType; } }
+ public Type PropertyType
+ {
+ get { return _valueGetters.Last().ValueType; }
+ }
- public Accessor GetChildAccessor<T>(Expression<Func<T, object>> expression)
+ public PropertyInfo InnerProperty
{
- PropertyInfo property = ReflectionHelper.GetProperty(expression);
- var list = new List<IValueGetter>(_chain)
+ get
{
- new PropertyValueGetter(_innerProperty.InnerProperty),
- new PropertyValueGetter(property)
- };
+ var last = _valueGetters.Last() as PropertyValueGetter;
+ return last == null ? null : last.PropertyInfo;
+ }
+ }
- return new PropertyChain(list.ToArray());
+ public Type DeclaringType
+ {
+ get { return _chain[0].DeclaringType; }
+ }
+
+ public Accessor GetChildAccessor<T>(Expression<Func<T, object>> expression)
+ {
+ var accessor = expression.ToAccessor();
+ var allGetters = Getters().Union(accessor.Getters()).ToArray();
+ return new PropertyChain(allGetters);
}
public string[] PropertyNames
@@ -97,24 +113,22 @@ public string[] PropertyNames
get { return _valueGetters.Select(x => x.Name).ToArray(); }
}
-
+
public Expression<Func<T, object>> ToExpression<T>()
{
- var parameter = Expression.Parameter(typeof(T), "x");
+ ParameterExpression parameter = Expression.Parameter(typeof (T), "x");
Expression body = parameter;
- _valueGetters.Each(getter =>
- {
- body = getter.ChainExpression(body);
- });
+ _valueGetters.Each(getter => { body = getter.ChainExpression(body); });
- var delegateType = typeof(Func<,>).MakeGenericType(typeof(T), typeof(object));
+ Type delegateType = typeof (Func<,>).MakeGenericType(typeof (T), typeof (object));
return (Expression<Func<T, object>>) Expression.Lambda(delegateType, body, parameter);
}
public Accessor Prepend(PropertyInfo property)
{
- var list = new List<IValueGetter>{
+ var list = new List<IValueGetter>
+ {
new PropertyValueGetter(property)
};
list.AddRange(_valueGetters);
@@ -127,27 +141,19 @@ public IEnumerable<IValueGetter> Getters()
return _valueGetters;
}
- public IValueGetter[] ValueGetters { get { return _valueGetters; } }
-
/// <summary>
- /// Concatenated names of all the properties in the chain.
- /// Case.Site.Name == "CaseSiteName"
+ /// Concatenated names of all the properties in the chain.
+ /// Case.Site.Name == "CaseSiteName"
/// </summary>
public string Name
{
- get
- {
- string returnValue = string.Empty;
- foreach (IValueGetter info in _chain)
- {
- returnValue += info.Name;
- }
-
- returnValue += _innerProperty.Name;
+ get { return _valueGetters.Select(x => x.Name).Join(""); }
+ }
- return returnValue;
- }
+ protected virtual void setValueOnInnerObject(object target, object propertyValue)
+ {
+ _valueGetters.Last().SetValue(target, propertyValue);
}
@@ -175,17 +181,7 @@ public bool Equals(PropertyChain other)
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
- if (_chain.Length != other._chain.Length) return false;
-
- for (int i = 0; i < _chain.Length; i++)
- {
- IValueGetter info = _chain[i];
- IValueGetter otherInfo = other._chain[i];
-
- if (!info.Equals(otherInfo)) return false;
- }
-
- return _innerProperty.Equals(other._innerProperty);
+ return _valueGetters.SequenceEqual(other._valueGetters);
}
public override bool Equals(object obj)
View
10 src/FubuCore/Reflection/PropertyValueGetter.cs
@@ -30,6 +30,11 @@ public Type DeclaringType
get { return _propertyInfo.DeclaringType; }
}
+ public Type ValueType
+ {
+ get { return _propertyInfo.PropertyType; }
+ }
+
public Expression ChainExpression(Expression body)
{
var memberExpression = Expression.Property(body, _propertyInfo);
@@ -41,6 +46,11 @@ public Expression ChainExpression(Expression body)
return Expression.Convert(memberExpression, typeof (object));
}
+ public void SetValue(object target, object propertyValue)
+ {
+ _propertyInfo.SetValue(target, propertyValue, null);
+ }
+
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
View
8 src/FubuCore/Reflection/SingleMethod.cs
@@ -70,7 +70,13 @@ public object GetValue(object target)
return _getter.GetValue(target);
}
- public Type OwnerType { get { return _ownerType ?? DeclaringType; } }
+ public Type OwnerType
+ {
+ get
+ {
+ return _ownerType ?? DeclaringType;
+ }
+ }
public bool Equals(SingleMethod other)
View
2 src/FubuCore/packages.config
@@ -1,3 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
-</packages>
+</packages>
View
2 src/FubuTestingSupport/packages.config
@@ -4,4 +4,4 @@
<package id="RhinoMocks" version="3.6.1" />
<package id="structuremap" version="2.6.3" />
<package id="structuremap.automocking" version="2.6.3" />
-</packages>
+</packages>

0 comments on commit 8693e74

Please sign in to comment.
Something went wrong with that request. Please try again.