runtime: The "Collection was of a fixed size." exception when configuring options.

Description

Exception thrown from the collection when configuring and options. This bug happens when we configure the options using the Configure callback AFTER the Bind extension is called.

This happens when you are using non-concrete collection type in our options:

public class MyOptions
{
    public IList<string> MyList { get; set; } = new List<string>();
}

I suspect that the Bind extension materializes incorrect IList type that has a fixed size. and no more items can be added to it after that.

We use this pattern across our codebase, and it breaks our scenarios completely. It blocks us from migrating to .NET 7. Full repro source here

Reproduction Steps

Run the following code in .NET 7.0 RC2 console app:

var config = new ConfigurationBuilder()
    .AddInMemoryCollection(new Dictionary<string, string?>() {{ "MyList:0", "item1" }})
    .Build();

var services = new ServiceCollection();
services
    .AddOptions<MyOptions>()
    .Bind(config)
    .Configure(o => o.MyList.Add("xxx"));

var val = services.BuildServiceProvider().GetRequiredService<IOptions<MyOptions>>().Value;

Console.WriteLine("List size: {0}", val.MyList.Count);

public class MyOptions
{
    public IList<string> MyList { get; set; } = new List<string>();
}

Expected behavior

The code snippet above should work.

Actual behavior

When trying to add a new item to a list the list throws the following exception:

Unhandled exception. System.NotSupportedException: Collection was of a fixed size.

Regression?

No response

Known Workarounds

Change the collection to a concrete type. i.e. IList<string> -> List<string>

Configuration

Running on .NET 7 using the default console template.

Other information

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 16 (16 by maintainers)

Most upvoted comments

This is fixed by the PR https://github.com/dotnet/runtime/pull/78118. The fix will be in the next 7.0 service release.

Correct. It would be in a subsequent servicing release.

CC @SteveDunn as FYI.

Very important thing to note. This is new behavior in .NET 7, this bug was not present in previous versions of .NET. This change in .NET behavior breaks a lot of our code and our customer’s code.