From bcf735f4f8d122d394bbd3fb0ec05c7a187c684c Mon Sep 17 00:00:00 2001 From: "agrath@gmail.com" Date: Sun, 6 Feb 2011 19:52:05 -1300 Subject: [PATCH] Added support for DynamicLinq in place of Lambda syntax. The short version is you can't use a Lambda with a DynamicNode e.g. @Model.Children.Where(node=>node.shouldBeVisible) To solve this, I used the DynamicQueryable class from the Linq samples which has a parser that can take a string then modified the internals a bit so that if your object is a DynamicObject, an additional expression tree is generated which calls the TryGetMember on it The end result is that you can now do this [I have Random(this DynamicNodeList nodes, int max) in my bin folder] @Model.Children.Where("shouldBeVisible").Random(2) => two nodes, randomly picked, from the ones that should be visible *Only* Where is implemented here currently, I'll add support by OrderBy and ThenBy after I've tested some more complex scenarios. I need to fix a small issue with my DynamicLoading of extensions - under some scenarios the class doesn't get found and i'm not sure why. --- umbraco.MacroEngines.Juno/DynamicDictionary.cs | 9 ++++++++- umbraco.MacroEngines.Juno/DynamicNode.cs | 6 +++++- umbraco.MacroEngines.Juno/DynamicNodeList.cs | 15 ++++++++++++++- .../umbraco.MacroEngines.csproj | 2 ++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/umbraco.MacroEngines.Juno/DynamicDictionary.cs b/umbraco.MacroEngines.Juno/DynamicDictionary.cs index ad16edf8b5..dfe85bb561 100644 --- a/umbraco.MacroEngines.Juno/DynamicDictionary.cs +++ b/umbraco.MacroEngines.Juno/DynamicDictionary.cs @@ -15,7 +15,14 @@ namespace umbraco.MacroEngines } public override bool TrySetMember(SetMemberBinder binder, object value) { - _dictionary[binder.Name] = value; + if (_dictionary.ContainsKey(binder.Name)) + { + _dictionary[binder.Name.ToLower()] = value; + } + else + { + _dictionary.Add(binder.Name.ToLower(), value); + } return true; } public override bool TryGetMember(GetMemberBinder binder, out object result) diff --git a/umbraco.MacroEngines.Juno/DynamicNode.cs b/umbraco.MacroEngines.Juno/DynamicNode.cs index bef5ea2bce..27441e17f2 100644 --- a/umbraco.MacroEngines.Juno/DynamicNode.cs +++ b/umbraco.MacroEngines.Juno/DynamicNode.cs @@ -370,7 +370,11 @@ namespace umbraco.MacroEngines { get { if (n == null) return null; return n.Name; } } - + public bool Visible + { + get; + set; + } public string Url { get { if (n == null) return null; return n.Url; } diff --git a/umbraco.MacroEngines.Juno/DynamicNodeList.cs b/umbraco.MacroEngines.Juno/DynamicNodeList.cs index 8dc7630b0a..bd3ae00c20 100644 --- a/umbraco.MacroEngines.Juno/DynamicNodeList.cs +++ b/umbraco.MacroEngines.Juno/DynamicNodeList.cs @@ -8,7 +8,8 @@ using System.Collections; using System.Reflection; using System.Runtime.CompilerServices; using System.Web.Compilation; - +using System.Linq.Expressions; +using System.Linq.Dynamic; namespace umbraco.MacroEngines { public class DynamicNodeList : DynamicObject, IEnumerable @@ -31,6 +32,13 @@ namespace umbraco.MacroEngines public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { var name = binder.Name; + if (name == "Where") + { + string predicate = args.First().ToString(); + var values = args.Skip(1).ToArray(); + result = new DynamicNodeList(this.Where(predicate, values).ToList()); + return true; + } try { @@ -209,5 +217,10 @@ namespace umbraco.MacroEngines { return Items.GetEnumerator(); } + + public IQueryable Where(string predicate, params object[] values) + { + return ((IQueryable)Items.AsQueryable()).Where(predicate, values); + } } } diff --git a/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj b/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj index 67de9971b7..102c62fea3 100644 --- a/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj +++ b/umbraco.MacroEngines.Juno/umbraco.MacroEngines.csproj @@ -63,9 +63,11 @@ + +