Skip to content

Commit

Permalink
Handle binding to initialized abstract members (#93090)
Browse files Browse the repository at this point in the history
If an abstract member is encountered in an object graph we should only
throw if it's not already initialized.
  • Loading branch information
ericstj authored Oct 6, 2023
1 parent 915a2f9 commit 4dcad85
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1047,15 +1047,13 @@ void EmitBindingLogic(string instanceToBindExpr, InitializationKind initKind)
else
{
Debug.Assert(!type.IsValueType);

EmitStartBlock($"if ({instanceToBindExpr} is not null)");
EmitBindCoreCall();
EmitEndBlock();
if (type is ObjectSpec { InitExceptionMessage: string exMsg })
{
EmitStartBlock("else");
_writer.WriteLine($@"throw new {Identifier.InvalidOperationException}(""{exMsg}"");");
}
else
{
EmitStartBlock($"if ({instanceToBindExpr} is not null)");
EmitBindCoreCall();
EmitEndBlock();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,11 @@ internal sealed class DerivedWithAnotherProp : AbstractBase
{
public int Value2 { get; set; }
}

internal class ClassWithAbstractProp
{
public AbstractBase AbstractProp { get; set; }
}

internal class ClassWithAbstractCtorParam
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2324,6 +2324,25 @@ public static void TestBindingAbstractMember_AsCtorParam()
Assert.Throws<InvalidOperationException>(configuration.Get<ClassWithOptionalAbstractCtorParam>);
}

[Fact]
public static void TestBindingInitializedAbstractMember()
{
IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{ ""AbstractProp"": {""Value"":1} }");
ClassWithAbstractProp c = new();
c.AbstractProp = new Derived();
configuration.Bind(c);
Assert.Equal(1, c.AbstractProp.Value);
}

[Fact]
public static void TestBindingUninitializedAbstractMember()
{
IConfiguration configuration = TestHelpers.GetConfigurationFromJsonString(@"{ ""AbstractProp"": {""Value"":1} }");
ClassWithAbstractProp c = new();
c.AbstractProp = null;
Assert.Throws<InvalidOperationException>(() => configuration.Bind(c));
}

[Fact]
public void GetIConfigurationSection()
{
Expand Down

0 comments on commit 4dcad85

Please sign in to comment.