Skip to content

ObjectArgumentValue can fail to bind to proper Constructors when parameter names are identicalΒ #420

@jkrueger-veradigm

Description

@jkrueger-veradigm

In situations where the Configuration binding matches identically to multiple public constructors via the naming of parameters all matched between themselves, the complex ObjectArgumentValue binding code will only attempt to use the first matched constructor. This will obviously lead to failure in the case where the first constructor has invalid matching types against the provided arguments within a Serilog configuration section.

i.e. (rough examples to demonstrate the issue)

public class Test {
   public Constructor1(string a, string b, FirstType c) {}
   public Constructor2(string a, string b, SecondType c) {}
}
// Causes Exception
{
  "Serilog": {
    "WriteTo": {
      "TestSink": {
        "Name": "TestSink",
        "Args": {
          "parameterOfTestType": {
            "$type": "Test",
            "a": "value-for-a",
            "b": "value-for-b",
            "c": {
              "$type": "SecondType",
              "parameterForSecondType": "some-value"
...
// Loads Successfully
{
  "Serilog": {
    "WriteTo": {
      "TestSink": {
        "Name": "TestSink",
        "Args": {
          "parameterOfTestType": {
            "$type": "Test",
            "a": "value-for-a",
            "b": "value-for-b",
            "c": {
              "$type": "FirstType",
              "parameterForFirstType": "some-value"
...

Ideally, this could be solved while still picking the first constructor, by matching parameter names in addition to matching criteria for the Types of each corresponding Parameter, which is currently ignored.

let argumentBindResult = suppliedArguments.TryGetValue(p.Name ?? "", out var argValue) switch
{
true => new { success = true, hasMatch = true, value = (object?)argValue },
false => p.HasDefaultValue switch
{
true => new { success = true, hasMatch = false, value = (object?)p.DefaultValue },
false => new { success = false, hasMatch = false, value = (object?)null },
},
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions