ImmutableDictionary regression in 2.7
See original GitHub issueHello,
In 2.7, AutoBogus throws an exception when using AutoFaker.Generate<T>() with classes that expose an ImmutableDictionary<T,U> as a public property. In 2.6, such classes used to be able to generate without having to skip these properties - they would just be null.
This also seems to happen with ReadOnlyDictionary<T,U>, which is a regression - in 2.6, a ReadOnlyDictionary would work and be faked correctly.
The regression can be worked-around by calling WithSkip in AutoFaker.Configure.
The below console app demonstrates the issue. If you install the 2.6.0 AutoBogus package, it runs and produces the below output (the immutable dictionary is left as null). If you update to 2.7.0 or beyond, it crashes with one of the exceptions below. Skipping both the ReadOnlyDictionary and ImmutableDictionary works around the problem.
SomeStringProperty = JSON
SomeReadOnlyDictionary = System.Collections.ObjectModel.ReadOnlyDictionary`2[System.String,System.String]
SomeReadOnlyDictionary Count = 3
SomeImmutableDictionary =
SomeImmutableDictionary Count =
In 2.7.0 and after, it crashes with an exception. Even if you skip the immutable dictionary property, it still crashes when trying to call Add.
Example of exception for converting to ReadOnlyDictionary<T,U>:
System.ArgumentException
HResult=0x80070057
Message=Object of type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' cannot be converted to type 'System.Collections.ObjectModel.ReadOnlyDictionary`2[System.String,System.String]'.
Source=System.Private.CoreLib
StackTrace:
at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
at AutoBogus.AutoMember.<>c__DisplayClass0_0.<.ctor>b__1(Object obj, Object value)
at AutoBogus.AutoBinder.PopulateInstance[TType](Object instance, AutoGenerateContext context, IEnumerable`1 members)
at AutoBogus.Generators.TypeGenerator`1.AutoBogus.IAutoGenerator.Generate(AutoGenerateContext context)
at AutoBogus.AutoGenerateContextExtensions.Generate[TType](AutoGenerateContext context)
at AutoBogus.AutoFaker.AutoBogus.IAutoFaker.Generate[TType](Action`1 configure)
at AutoBogus.AutoFaker.Generate[TType](Action`1 configure)
at AutoBogusImmutableIssue.Program.Main(String[] args) in C:\Users\SteveOgnibene\source\repos\AutoBogusImmutableIssue\AutoBogusImmutableIssue\Program.cs:line 21
Example of exception for converting to ImmutableDictionary<T,U>:
System.ArgumentException
HResult=0x80070057
Message=Object of type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' cannot be converted to type 'System.Collections.Immutable.ImmutableDictionary`2[System.String,System.String]'.
Source=System.Private.CoreLib
StackTrace:
at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
at AutoBogus.AutoMember.<>c__DisplayClass0_0.<.ctor>b__1(Object obj, Object value)
at AutoBogus.AutoBinder.PopulateInstance[TType](Object instance, AutoGenerateContext context, IEnumerable`1 members)
at AutoBogus.Generators.TypeGenerator`1.AutoBogus.IAutoGenerator.Generate(AutoGenerateContext context)
at AutoBogus.AutoGenerateContextExtensions.Generate[TType](AutoGenerateContext context)
at AutoBogus.AutoFaker.AutoBogus.IAutoFaker.Generate[TType](Action`1 configure)
at AutoBogus.AutoFaker.Generate[TType](Action`1 configure)
at AutoBogusImmutableIssue.Program.Main(String[] args) in C:\Users\SteveOgnibene\source\repos\AutoBogusImmutableIssue\AutoBogusImmutableIssue\Program.cs:line 11
Demo program:
using AutoBogus;
using System;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
namespace AutoBogusImmutableIssue
{
class Program
{
static void Main(string[] args)
{
//AutoFaker.Configure(builder =>
//{
// builder
// .WithSkip<MyClass>(mc => mc.SomeImmutableDictionary)
// .WithSkip<MyClass>(mc => mc.SomeReadOnlyDictionary)
// ;
//});
var myInstance = AutoFaker.Generate<MyClass>();
Console.WriteLine($"{nameof(MyClass.SomeStringProperty)} = {myInstance.SomeStringProperty}");
Console.WriteLine($"{nameof(MyClass.SomeReadOnlyDictionary)} = {myInstance.SomeReadOnlyDictionary}");
Console.WriteLine($"{nameof(MyClass.SomeReadOnlyDictionary)} Count = {myInstance.SomeReadOnlyDictionary?.Count}");
Console.WriteLine($"{nameof(MyClass.SomeImmutableDictionary)} = {myInstance.SomeImmutableDictionary}");
Console.WriteLine($"{nameof(MyClass.SomeImmutableDictionary)} Count = {myInstance.SomeImmutableDictionary?.Count}");
}
}
public class MyClass
{
public string SomeStringProperty { get; set; }
public ReadOnlyDictionary<string, string> SomeReadOnlyDictionary { get; set; }
public ImmutableDictionary<string, string> SomeImmutableDictionary { get; set; }
}
}
I’m willing to give it a shot to fix this if you can come up with a good idea. I can try bisecting if you think that would be valuable. Thanks for this great library.
Issue Analytics
- State:
- Created 4 years ago
- Comments:13 (6 by maintainers)

Top Related StackOverflow Question
Hey @kevin-david
I have now got
IReadOnlyDictionary<T,U>working again. Turns out some of my tests weren’t executing which would have highlighted the issue. A new version will be available shortly.Hey @nycdotnet
I can’t get
ImmutableDictionaryto work as expected because the AutoBogus code runs on .NET Standard, butImmutableDictionaryseems to only be available in .NET Core.https://docs.microsoft.com/en-us/dotnet/api/system.collections.immutable.immutabledictionary-2?view=netcore-2.0
I do have plans for a big refactor of AutoBogus (v3) to cater for this, which I am currently working on.
However, I did wonder how you managed to get it working in v2.6, so I checked out that version of the code to run some tests. Do your properties populate as expected, because when I run my test code, the
ImmutableDictionaryproperty is alwaysnull. As far as I can tellImmutableDictionaryinstances need to be created using static factory methods on the class (which AutoBogus doesn’t know about to create an instance).Nick.
Hi @nycdotnet
Thanks for the details above. I am surprised you are seeing an issue with
ReadOnlyDictionary. That type should be handled, so I will need to investigate further.With the
ImmutableDictionarythat could possibly be a special case that doesn’t follow the supported collection interfaces. Again, I will need to investigate to see why.Watch this space 😄
Nick.