Skip to content

Commit

Permalink
Support IReadOnlySet. Refactor out method that determines most suitab…
Browse files Browse the repository at this point in the history
…le type for collections that are already specified in the destination.
  • Loading branch information
SteveDunn committed Apr 19, 2022
1 parent 85f9dbe commit 133ee2e
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
Expand Down Expand Up @@ -296,11 +297,14 @@ private static object BindToCollection(Type type, IConfiguration config, BinderO
return instance;
}

collectionInterface = FindOpenGenericInterface(typeof(IReadOnlyCollection<>), type);
collectionInterface = FindOpenGenericInterface(typeof(ISet<>), type);
#if NET5_0_OR_GREATER
collectionInterface ??= FindOpenGenericInterface(typeof(IReadOnlySet<>), type);
#endif
if (collectionInterface != null)
{
// IReadOnlyCollection<T> is guaranteed to have exactly one parameter
return BindToCollection(type, config, options);
// ISet<T> is guaranteed to have exactly one parameter
return BindToSet(type, config, options);
}

collectionInterface = FindOpenGenericInterface(typeof(ICollection<>), type);
Expand Down Expand Up @@ -527,7 +531,11 @@ private static Array BindArray(Type type, IEnumerable? source, IConfiguration co
else // e. g. IEnumerable<T>
{
elementType = type.GetGenericArguments()[0];
}

if ((type = sourceType.GetInterface("IReadOnlySet`1", false)) != null)
{
return (typeof(HashSet<>), type.GenericTypeArguments[0]);
}

IList list = new List<object?>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ public string ReadOnly

public IEnumerable<string> NonInstantiatedIEnumerable { get; set; } = null!;
public ISet<string> InstantiatedISet { get; set; } = new HashSet<string>();
#if NET5_0_OR_GREATER
public IReadOnlySet<string> InstantiatedIReadOnlySet { get; set; } = new HashSet<string>();
public IReadOnlySet<string> NonInstantiatedIReadOnlySet { get; set; }
#endif
public IEnumerable<string> InstantiatedIEnumerable { get; set; } = new List<string>();
public ICollection<string> InstantiatedICollection { get; set; } = new List<string>();
public IReadOnlyCollection<string> InstantiatedIReadOnlyCollection { get; set; } = new List<string>();
Expand Down Expand Up @@ -267,11 +271,52 @@ public void CanBindNonInstantiatedISet()

var options = config.Get<ComplexOptions>()!;

Assert.Equal(2, options.NonInstantiatedISet.Count());
Assert.Equal(2, options.NonInstantiatedISet.Count);
Assert.Equal("Yo1", options.NonInstantiatedISet.ElementAt(0));
Assert.Equal("Yo2", options.NonInstantiatedISet.ElementAt(1));
}

#if NET5_0_OR_GREATER
[Fact]
public void CanBindInstantiatedIReadOnlySet()
{
var dic = new Dictionary<string, string>
{
{"InstantiatedIReadOnlySet:0", "Yo1"},
{"InstantiatedIReadOnlySet:1", "Yo2"},
};
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddInMemoryCollection(dic);

var config = configurationBuilder.Build();

var options = config.Get<ComplexOptions>()!;

Assert.Equal(2, options.InstantiatedIReadOnlySet.Count);
Assert.Equal("Yo1", options.InstantiatedIReadOnlySet.ElementAt(0));
Assert.Equal("Yo2", options.InstantiatedIReadOnlySet.ElementAt(1));
}

[Fact]
public void CanBindNonInstantiatedIReadOnlySet()
{
var dic = new Dictionary<string, string>
{
{"NonInstantiatedIReadOnlySet:0", "Yo1"},
{"NonInstantiatedIReadOnlySet:1", "Yo2"},
};
var configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddInMemoryCollection(dic);

var config = configurationBuilder.Build();

var options = config.Get<ComplexOptions>()!;

Assert.Equal(2, options.NonInstantiatedIReadOnlySet.Count);
Assert.Equal("Yo1", options.NonInstantiatedIReadOnlySet.ElementAt(0));
Assert.Equal("Yo2", options.NonInstantiatedIReadOnlySet.ElementAt(1));
}
#endif
[Fact]
public void CanBindNonInstantiatedDictionaryOfISet()
{
Expand Down

0 comments on commit 133ee2e

Please sign in to comment.