Skip to content

Instantly share code, notes, and snippets.

@Buildstarted
Last active December 22, 2015 01:09
Show Gist options
  • Save Buildstarted/6394542 to your computer and use it in GitHub Desktop.
Save Buildstarted/6394542 to your computer and use it in GitHub Desktop.
public class DucknamicObject : DynamicObject, IDictionary<string, object>, ICollection<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>, IEnumerable
{
private readonly IDictionary<string, object> _backing;
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (_backing.ContainsKey(binder.Name))
{
if (args.Any() && args[0].GetType() == typeof (bool) && ((bool) args[0]))
{
//force value in db to true
var backingValue = (bool) _backing[binder.Name];
if (backingValue == true)
{
result = true;
}
else
{
result = false;
}
}
else
{
result = true;
}
}
else
{
result = false;
}
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (!_backing.ContainsKey(binder.Name))
{
_backing.Add(binder.Name, value);
}
else
{
_backing[binder.Name] = value;
}
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (!_backing.ContainsKey(binder.Name))
{
result = null;
return true;
}
result = _backing[binder.Name];
return true;
}
public DucknamicObject()
{
_backing = new Dictionary<string, object>();
}
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
return _backing.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(KeyValuePair<string, object> item)
{
_backing.Add(item);
}
public void Clear()
{
_backing.Clear();
}
public bool Contains(KeyValuePair<string, object> item)
{
return _backing.Contains(item);
}
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
{
_backing.CopyTo(array, arrayIndex);
}
public bool Remove(KeyValuePair<string, object> item)
{
return _backing.Remove(item);
}
public int Count { get { return _backing.Count; } }
public bool IsReadOnly { get { return _backing.IsReadOnly; } }
public bool ContainsKey(string key)
{
return _backing.ContainsKey(key);
}
public void Add(string key, object value)
{
_backing.Add(key, value);
}
public bool Remove(string key)
{
return _backing.Remove(key);
}
public bool TryGetValue(string key, out object value)
{
return _backing.TryGetValue(key, out value);
}
public object this[string key]
{
get
{
return _backing[key];
}
set
{
_backing[key] = value;
}
}
public ICollection<string> Keys { get { return _backing.Keys; } }
public ICollection<object> Values { get { return _backing.Values; } }
}
public class DucknamicObjectTests
{
[Test]
public void Setting_Property_Adds_New_Property_To_DynamicObject()
{
dynamic obj = new DucknamicObject();
obj.Name = "Ben";
Assert.AreEqual(obj.Name, "Ben");
}
[Test]
public void Check_If_Property_Exists_Returns_True_When_Property_Exists()
{
dynamic obj = new DucknamicObject();
obj.Name = "Ben";
Assert.IsTrue(obj.Name());
}
[Test]
public void Check_If_Property_Exists_Returns_False_When_Property_Doesnt_Exist()
{
dynamic obj = new DucknamicObject();
Assert.IsFalse(obj.PropertyDoesExist());
}
[Test]
public void Check_If_Property_Exists_With_Passed_Boolean_Value_Returns_True_When_Both_Are_True()
{
dynamic obj = new DucknamicObject();
obj.ReturnsTrue = true;
Assert.IsTrue(obj.ReturnsTrue(true));
}
[Test]
public void Check_If_Property_Exists_With_Passed_Boolean_Value_Returns_False_When_Backing_Is_False_Or_Doesnt_Exist()
{
dynamic obj = new DucknamicObject();
obj.ReturnsFalse = false;
Assert.IsFalse(obj.ReturnsFalse(true));
}
[Test]
public void Check_If_Property_Exists_With_Passed_Boolean_Value_Returns_False_When_Backing_Property_Doesnt_Exist()
{
dynamic obj = new DucknamicObject();
Assert.IsFalse(obj.DoesntExist(true));
}
[Test]
public void Check_If_Property_Exists_With_Passed_Boolean_Value_Returns_True_When_Backing_Property_Doesnt_Exist_And_Passed_Value_Is_False()
{
dynamic obj = new DucknamicObject();
Assert.IsTrue(obj.DoesntExist(false));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment