Skip to content

Logging Source Generator fails with partial methods with implicit ILogger definition when using partial classes #61547

@MithrilMan

Description

@MithrilMan

Description

I found a bug that causes the error SYSLIB1019 when it shouldn't be triggered.

If you declare the ILogger field in a file containing part of your partial class (let's call the class Foo)and you define the log methods that uses source generation logging in another physical file that's of course a partial class of Foo, the compiler complain with the error

SYSLIB1019 Couldn't find a field of type Microsoft.Extensions.Logging.ILogger in class Foo

If I move the ILogger declaration from first physical file to the other containing log methods, it works.

Reproduction Steps

Create a project that makes use of logging, create a Foo class like this, in two distinct files (probably even if you declare them in a single file should trigger the problem too)

public partial class Foo
{
   ILogger _logger;

   public void Test()
   {
      LogPeriodicWorkFailure("workName");
   }
}

public partial class Foo
{
   [LoggerMessage(0, LogLevel.Critical, "An unhandled exception has been raised in the {PeriodicWork} work.")]
   partial void LogPeriodicWorkFailure(string periodicWork);
}

If you move the declaration ILogger _logger; to the second partial class, it works.

Expected behavior

Source Generator should find ILogger declaration in every partial class.

If it isn't possible, the problem should be documented.

Actual behavior

Described into "Reproduction Steps"

Regression?

No response

Known Workarounds

Moving the declaration from one physical file to the file containing logging method works, but if you define partial methods in multiple partial classes, the problem can't be solved and you can't use partial methods that implicitly get reference to the ILogger.

Configuration

.Net 6
Visual Studio 2022

Other information

Having to move ILogger definition, even if easy, isn't the best because when using dependency injection the workflow is usually to declare the constructor parameter you want to inject and then use helpers like VS suggestion action "create and assign field" that of course defines the filed in the class containing the constructor

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions