Skip to content

Commit

Permalink
Fix exception when deserializing an interface
Browse files Browse the repository at this point in the history
Fixes #439
Also adds default implementations for the following non-generic collections:
- IEnumerable
- ICollection
- IList
- IDictionary
  • Loading branch information
aaubry committed Oct 19, 2019
1 parent 6c1a7b4 commit 2c0ae4c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
9 changes: 9 additions & 0 deletions YamlDotNet.Test/Serialization/ObjectFactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using System.Collections;
using FluentAssertions;
using Xunit;
using YamlDotNet.Serialization.ObjectFactories;
Expand Down Expand Up @@ -49,5 +50,13 @@ public void ObjectFactoryIsInvoked()

result.Should().BeOfType<EmptyDerived>();
}

[Fact]
public void DefaultObjectFactorySupportsNonGenericInterfaces()
{
var sut = new DefaultObjectFactory();
var result = sut.Create(typeof(IList));
Assert.IsAssignableFrom<IList>(result);
}
}
}
25 changes: 22 additions & 3 deletions YamlDotNet/Serialization/ObjectFactories/DefaultObjectFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
// SOFTWARE.

using System;
using System.Collections;
using System.Collections.Generic;

namespace YamlDotNet.Serialization.ObjectFactories
Expand All @@ -29,21 +30,39 @@ namespace YamlDotNet.Serialization.ObjectFactories
/// </summary>
public sealed class DefaultObjectFactory : IObjectFactory
{
private static readonly Dictionary<Type, Type> defaultInterfaceImplementations = new Dictionary<Type, Type>
private static readonly Dictionary<Type, Type> defaultGenericInterfaceImplementations = new Dictionary<Type, Type>
{
{ typeof(IEnumerable<>), typeof(List<>) },
{ typeof(ICollection<>), typeof(List<>) },
{ typeof(IList<>), typeof(List<>) },
{ typeof(IDictionary<,>), typeof(Dictionary<,>) }
};

private static readonly Dictionary<Type, Type> defaultNonGenericInterfaceImplementations = new Dictionary<Type, Type>
{
{ typeof(IEnumerable), typeof(List<object>) },
{ typeof(ICollection), typeof(List<object>) },
{ typeof(IList), typeof(List<object>) },
{ typeof(IDictionary), typeof(Dictionary<object, object>) }
};

public object Create(Type type)
{
if (type.IsInterface())
{
if (defaultInterfaceImplementations.TryGetValue(type.GetGenericTypeDefinition(), out var implementationType))
if (type.IsGenericType())
{
if (defaultGenericInterfaceImplementations.TryGetValue(type.GetGenericTypeDefinition(), out var implementationType))
{
type = implementationType.MakeGenericType(type.GetGenericArguments());
}
}
else
{
type = implementationType.MakeGenericType(type.GetGenericArguments());
if (defaultNonGenericInterfaceImplementations.TryGetValue(type, out var implementationType))
{
type = implementationType;
}
}
}

Expand Down

0 comments on commit 2c0ae4c

Please sign in to comment.