Skip to content

Instantly share code, notes, and snippets.

@thecodejunkie
Last active December 10, 2015 09:38
Show Gist options
  • Save thecodejunkie/4415623 to your computer and use it in GitHub Desktop.
Save thecodejunkie/4415623 to your computer and use it in GitHub Desktop.
Dynamic member resolution chaining
namespace DynamicMemberChaining
{
using System;
using System.Dynamic;
using Xunit;
public interface ITextResource
{
string this[string key] { get; }
}
public class DefaultTextResource : ITextResource
{
public string this[string key]
{
get { return "Returned from resource, for key: " + key; }
}
}
public class TextResourceFinder : DynamicObject
{
private readonly ITextResource textResource;
public TextResourceFinder(ITextResource textResource)
{
this.textResource = textResource;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = new MemberChainer(binder.Name, this.textResource);
return true;
}
private class MemberChainer : DynamicObject
{
private string memberName;
private readonly ITextResource textResource;
public MemberChainer(string memberName, ITextResource resource)
{
this.memberName = memberName;
this.textResource = resource;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
this.memberName =
string.Concat(this.memberName, ".", binder.Name);
result = this;
return true;
}
public override bool TryConvert(ConvertBinder binder, out object result)
{
if (binder.ReturnType == typeof (string))
{
result = this.textResource[this.memberName];
return true;
}
throw new InvalidOperationException("Cannot cast dynamic member access to anything else than a string.");
}
}
}
public class Fixture
{
[Fact]
public void Should_FactMethodName()
{
// Given
var textResource = new DefaultTextResource();
dynamic finder = new TextResourceFinder(textResource);
// When
var result = finder.foo.bar.other;
// Then
Assert.Equal("Returned from resource, for key: foo.bar.other", (string)result);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment