Skip to content

Instantly share code, notes, and snippets.

@muhanov-apps
Last active April 11, 2018 16:59
Show Gist options
  • Save muhanov-apps/8643dbd9fcdcd92cef8d25ed8cfa1804 to your computer and use it in GitHub Desktop.
Save muhanov-apps/8643dbd9fcdcd92cef8d25ed8cfa1804 to your computer and use it in GitHub Desktop.
DeltaContractResolver
public class DeltaContractResolver : DefaultContractResolver
{
public DeltaContractResolver( )
: base( )
{
}
protected override JsonContract CreateContract(Type objectType)
{
// This class special cases the JsonContract for just the Delta<T> class. All other types should function
// as usual.
if (objectType.IsGenericType &&
objectType.GetGenericTypeDefinition() == typeof(Delta<>) &&
objectType.GetGenericArguments().Length == 1)
{
var contract = CreateDynamicContract(objectType);
contract.Properties.Clear();
var underlyingContract = CreateObjectContract(objectType.GetGenericArguments()[0]);
foreach (var property in underlyingContract.Properties)
{
property.DeclaringType = objectType;
property.ValueProvider = new DynamicObjectValueProvider()
{
PropertyName = property.PropertyName,
};
contract.Properties.Add(property);
}
return contract;
}
return base.CreateContract(objectType);
}
private class DynamicObjectValueProvider : IValueProvider
{
public string PropertyName
{
get;
set;
}
public object GetValue(object target)
{
DynamicObject d = (DynamicObject)target;
object result;
var binder = CreateGetMemberBinder(target.GetType(), PropertyName);
d.TryGetMember(binder, out result);
return result;
}
public void SetValue(object target, object value)
{
DynamicObject d = (DynamicObject)target;
var binder = CreateSetMemberBinder(target.GetType(), PropertyName);
d.TrySetMember(binder, value);
}
}
private static GetMemberBinder CreateGetMemberBinder(Type type, string memberName)
{
return (GetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.GetMember(
Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None,
memberName,
type,
new Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[]
{
});
}
private static SetMemberBinder CreateSetMemberBinder(Type type, string memberName)
{
return (SetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.SetMember(
Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags.None,
memberName,
type,
new Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[]
{
Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags.None, null),
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment