Created
January 3, 2011 12:48
-
-
Save jfromaniello/763423 to your computer and use it in GitHub Desktop.
This file contains 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.Dynamic; | |
using System.Linq; | |
using System.Reflection; | |
using Microsoft.CSharp.RuntimeBinder; | |
using NUnit.Framework; | |
using SharpTestsEx; | |
namespace SampleMixin | |
{ | |
public class Foo | |
{ | |
public string FooProperty { get; set; } | |
} | |
public class Bar | |
{ | |
public string BarProperty { get; set; } | |
} | |
[TestFixture] | |
public class SampleTests | |
{ | |
[Test] | |
public void CanGetProperty() | |
{ | |
var foo = new Foo {FooProperty = "Test"}; | |
var bar = new Bar {BarProperty = "Other"}; | |
dynamic mixin = new Mixin(foo, bar); | |
Assert.AreEqual("Test", mixin.FooProperty); | |
Assert.AreEqual("Other", mixin.BarProperty); | |
} | |
[Test] | |
public void CanSetProperty() | |
{ | |
var foo = new Foo {FooProperty = "Test"}; | |
var bar = new Bar {BarProperty = "Other"}; | |
dynamic mixin = new Mixin(foo, bar); | |
mixin.FooProperty = "Alll"; | |
foo.FooProperty.Should().Be.EqualTo("Alll"); | |
} | |
[Test] | |
public void WhenGettingAPropertyThatDoesNotExistsThenThrowRuntimeBinderException() | |
{ | |
var foo = new Foo {FooProperty = "Test"}; | |
var bar = new Bar {BarProperty = "Other"}; | |
dynamic mixin = new Mixin(foo, bar); | |
Assert.Throws<RuntimeBinderException>(() => { dynamic r = mixin.InvalidProperty; }); | |
} | |
[Test] | |
public void WhenSettingAPropertyThatDoesNotExistsThenThrowRuntimeBinderException() | |
{ | |
var foo = new Foo {FooProperty = "Test"}; | |
var bar = new Bar {BarProperty = "Other"}; | |
dynamic mixin = new Mixin(foo, bar); | |
Assert.Throws<RuntimeBinderException>(() => { mixin.InvalidProperty = "Jjjs"; }); | |
} | |
} | |
public class Mixin : DynamicObject | |
{ | |
private readonly object[] mixeds; | |
public Mixin(params object[] mixeds) | |
{ | |
this.mixeds = mixeds; | |
} | |
public override bool TryGetMember(GetMemberBinder binder, out object result) | |
{ | |
PropertyObjectPair pair = GetPropertyObjectPair(binder.Name); | |
if (pair == null) | |
{ | |
result = null; | |
return false; | |
} | |
object value = pair.Property.GetValue(pair.Object, null); | |
result = value; | |
return true; | |
} | |
public override bool TrySetMember(SetMemberBinder binder, object value) | |
{ | |
PropertyObjectPair pair = GetPropertyObjectPair(binder.Name); | |
if (pair == null) return false; | |
pair.Property.SetValue(pair.Object, value, null); | |
return true; | |
} | |
private PropertyObjectPair GetPropertyObjectPair(string binderName) | |
{ | |
return mixeds.Select(m => new PropertyObjectPair | |
{ | |
Property = m.GetType().GetProperty(binderName), | |
Object = m | |
}) | |
.FirstOrDefault(p => p.Property != null); | |
} | |
#region Nested type: PropertyObjectPair | |
public class PropertyObjectPair | |
{ | |
public object Object { get; set; } | |
public PropertyInfo Property { get; set; } | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment