YamlDotNet icon indicating copy to clipboard operation
YamlDotNet copied to clipboard

Support read-only collection interfaces

Open ejball opened this issue 8 years ago • 3 comments

It would be great if the library could deserialize into properties of the following interfaces:

ejball avatar Jan 23 '17 17:01 ejball

@aaubry - I was interested in this feature and was thinking about coming up with a PR. Would you be able to offer any hints as to what changes might be required? I thought it might just be a case of adding these extra interfaces to DefaultObjectFactory but, after playing around with a customised version via WithObjectFactory(), I don't know if it's that simple.

Edit: ah, it seems like WithNodeTypeResolver() is actually the way forward.

mparry avatar May 21 '20 08:05 mparry

In the meantime, hooking the below in via WithNodeTypeResolver() seems to work well.

public sealed class ReadOnlyCollectionNodeTypeResolver : INodeTypeResolver
{
    public bool Resolve(NodeEvent nodeEvent, ref Type type)
    {
        if (type.IsInterface && type.IsGenericType && CustomGenericInterfaceImplementations.TryGetValue(type.GetGenericTypeDefinition(), out var concreteType))
        {
            type = concreteType.MakeGenericType(type.GetGenericArguments());
            return true;
        }
        return false;
    }
    private static readonly IReadOnlyDictionary<Type, Type> CustomGenericInterfaceImplementations = new Dictionary<Type, Type>
    {
        {typeof(IReadOnlyCollection<>), typeof(List<>)},
        {typeof(IReadOnlyList<>), typeof(List<>)},
        {typeof(IReadOnlyDictionary<,>), typeof(Dictionary<,>)}
    };
}

mparry avatar May 21 '20 12:05 mparry