Created
November 21, 2012 14:48
-
-
Save xsurge83/4125192 to your computer and use it in GitHub Desktop.
Power of Dynamics
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Dynamic; | |
namespace Demo | |
{ | |
class Program | |
{ | |
static void Main() | |
{ | |
var dataStore = new DataStore(); | |
dataStore.Add(new Artist("Mozart", "Classical")); | |
dataStore.Add(new Artist("Bach", "Classical")); | |
dataStore.Add(new Song("Air")); | |
// case 1 : find category property with value classical | |
dynamic dataFinder = new SmartDataFinder(dataStore); | |
var matchingClassicals = dataFinder.FindByCategory("Classical"); | |
PrintNames(matchingClassicals); | |
// case 2: find name property with value air | |
var matchingNames = dataFinder.FindByName("Air"); | |
PrintNames(matchingNames); | |
} | |
private static void PrintNames(IEnumerable<dynamic> foundItems) | |
{ | |
foreach (var item in foundItems) | |
{ | |
Console.WriteLine(item.Name); | |
} | |
} | |
} | |
public class SmartDataFinder : DynamicObject | |
{ | |
const string FindByMethodMatch = "FindBy"; | |
readonly DataStore _dataStore; | |
public SmartDataFinder(DataStore dataStore) | |
{ | |
_dataStore = dataStore; | |
} | |
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) | |
{ | |
if (binder.Name.StartsWith(FindByMethodMatch)) | |
{ | |
var matchingPropertyName = binder.Name.Substring(FindByMethodMatch.Length); | |
var value = args[0].ToString(); | |
// find items with matching property and value | |
var matchingItems = new List<object>(); | |
foreach (var item in _dataStore.Items) | |
{ | |
var properties = item.GetType().GetProperties(); | |
foreach(var propertyInfo in properties) | |
{ | |
if (!propertyInfo.Name.Contains(matchingPropertyName)) continue; | |
var propertyVal = propertyInfo.GetValue(item, null); | |
if (!(propertyVal is string) || (string) propertyVal != value) continue; | |
matchingItems.Add(item); | |
break; | |
} | |
} | |
result = matchingItems; | |
return true; | |
} | |
return base.TryInvokeMember(binder, args, out result); | |
} | |
} | |
public class DataStore | |
{ | |
readonly IList<dynamic> _items; | |
public IEnumerable<dynamic> Items { get { return _items; } } | |
public DataStore() | |
{ | |
_items = new List<dynamic>(); | |
} | |
public void Add<T>(T item) | |
{ | |
_items.Add(item); | |
} | |
} | |
public class Song | |
{ | |
public string Name { get; private set; } | |
public Song(string name) | |
{ | |
Name = name; | |
} | |
} | |
public class Artist | |
{ | |
public string Name { get; private set; } | |
public string Category { get; private set; } | |
public Artist(string name, string category) | |
{ | |
Category = category; | |
Name = name; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment