Skip to content

Instantly share code, notes, and snippets.

@xsurge83
Created November 21, 2012 14:48
Show Gist options
  • Save xsurge83/4125192 to your computer and use it in GitHub Desktop.
Save xsurge83/4125192 to your computer and use it in GitHub Desktop.
Power of Dynamics
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