Add support for ObservableCollection in relations.

Issue #36 resolved
Benjamin created an issue

It would be good if we could use ObservableCollections as relations.

I've hacked this together because I needed it for my own project. The things I've changed are:

ReflectionExtensions.cs

public enum EnclosedType
{
    None,
    Array,
    List,
    Collection
}

public static Type GetEntityType(this PropertyInfo property, out EnclosedType enclosedType)
{
    var type = property.PropertyType;
    enclosedType = EnclosedType.None;

    if (type.IsArray)
    {
        type = type.GetElementType();
        enclosedType = EnclosedType.Array;
    }
    else if (type.IsGenericType && typeof(List<>).IsAssignableFrom(type.GetGenericTypeDefinition()))
    {
        type = type.GetGenericArguments()[0];
        enclosedType = EnclosedType.List;
    }
    else if (type.IsGenericType && type.GetInterfaces().Where(i => i.IsGenericType).Select(i => i.GetGenericTypeDefinition()).Contains(typeof(ICollection<>)))
    {
        type = type.GetGenericArguments()[0];
        enclosedType = EnclosedType.Collection;
    }
    return type;
}

ReadOperation.cs

private static IEnumerable GetManyToManyChildren<T>(this SQLiteConnection conn, T element,
    PropertyInfo relationshipProperty, 
    bool recursive, ObjectCache objectCache)
{
    // <snip>
    // Create a generic list of the expected type
    if (enclosedType == EnclosedType.List)
    {
        values = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(entityType));
    }
    else if (enclosedType == EnclosedType.Collection)
    {
        values = (IList)Activator.CreateInstance((relationshipProperty.PropertyType));
    }
    else
    {
        values = array = Array.CreateInstance(entityType, queryResults.Count);
    }

    // <snip>
    if(enclosedType == EnclosedType.Collection)
    {
        relationshipProperty.SetValue(element, Convert.ChangeType(values, relationshipProperty.PropertyType, null), null);
    } else
    {
        relationshipProperty.SetValue(element, values, null);
    }
    // <snip>
}

I think those are all I changed.

Comments (6)

  1. Guillermo Gutiérrez

    Why is the type conversion required?

    Convert.ChangeType(values, relationshipProperty.PropertyType, null)
    
  2. Patrick Lind

    This is exactly what I was looking for... has observable collection support been pushed out to the MvvmCross nuget?

  3. Log in to comment