Question

I was playing around with impromptu interface over a jobject and ran into the following issue

https://code.google.com/p/impromptu-interface/issues/detail?id=17

The issue is marked as 'Won't fix' and in the comments the author says that it could be fixed by implementing a custom impromptuobject.

Anyone have a sample of such an implementation? Or know another solution to this problem?

Was it helpful?

Solution

So the problem is that JArray has GetEnumerator() defined as interface-only, which makes the method no longer duck callable by the DLR. So below I've overriden the trygetmember to check if the result is a JArray's and convert it to a JEnumerable that implements GetEnumerator() in a dlr invokable way.

 public class NonRecursiveJArrayConversionDictionary : ImpromptuDictionary{

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if(base.TryGetMember(binder, out result)){
          if(result is JArray){
             result = ((JArray)result).AsJEnumerable();
          }
          return true;
        }
        result = null;
        return false;
    }
 }

However, this will only work for json structures that don't have arrays more then one property deep. You'll either have modify the above to recursively check anytime anything is returned maybe with a proxy, or modify the dictionary indexer's set to check and convert when deserialized instead.


Update: Json.net verion >= 5.0.4.16101 and ImpromptuInterface >= 6.1.4 will work out of the box.

void Main()
{
    ICustomer customer = Impromptu.ActLike(JObject.Parse(@"
        {
            Id: 1,
            Name:'Test',
            Location:'Somewhere',
            Employees: [
                { Id:1, EmployerId:39421, Name:'Joe' },
                { Id:2, EmployerId:39421, Name:'Jane' },
            ]
        }
    "));

    foreach(var employee in customer.Employees){
        employee.Id.Dump();
        employee.Name.Dump();
    }
}


public interface ICustomer
{
    int Id { get; set; }
    string Name { get; set; }
    string Location { get; set; }
    IList<IEmployee> Employees { get; } 
}

public interface IEmployee
{
    int Id { get; set; }
    int EmployerId { get; set; }
    string Name { get; set; }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top