Skip to content

Global filter dependency injection NullReferenceException #209

Description

@gintarasd-bentley

Hello, thank you for this project, it's great!

I recently moved from v5.6.2 to v5.7.3, and ran into an exception:

Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
   at ConsoleAppFramework.ConsoleApp.ConsoleAppBuilder.Command0Invoker.BuildFilter() in ...\obj\Debug\net10.0\ConsoleAppFramework\ConsoleAppFramework.ConsoleAppGenerator\ConsoleApp.Builder.g.cs:line 82
   at ConsoleAppFramework.ConsoleApp.ConsoleAppBuilder.Run(String[] args, Boolean startHost, Boolean stopHost, Boolean disposeServiceProvider, CancellationToken cancellationToken) in ...\obj\Debug\net10.0\ConsoleAppFramework\ConsoleAppFramework.ConsoleAppGenerator\ConsoleApp.Builder.Run.g.cs:line 32
   at ConsoleAppFramework.ConsoleApp.ConsoleAppBuilder.Run(String[] args) in ...\obj\Debug\net10.0\ConsoleAppFramework\ConsoleAppFramework.ConsoleAppGenerator\ConsoleApp.Builder.Run.g.cs:line 24
   at Program.
$(String[] args) in ...\Program.cs:line 7

While debugging I found that the ServiceProvider is null when BuildFilter is invoked:

// ConsoleApp.Builder.g.cs
sealed class Command0Invoker(ConsoleAppBuilder builder) : ConsoleAppFilter(null!)
{
    public ConsoleAppFilter BuildFilter()
    {
        var filter0 = new global::MyFilter(this, (global::MyService)ServiceProvider!.GetService(typeof(global::MyService))!);
        return filter0;
    }

    public override Task InvokeAsync(ConsoleAppContext context, CancellationToken cancellationToken)
    {
        return builder.RunCommand0Async(context, cancellationToken);
    }
}

For context, I am using a global filter which depends on a service from DI.

The exception is not thrown when using v5.6.2, or when there is no filter (e.g. comment out the app.UseFilter<> line)

I managed to reproduce this issue in the sample below:

Sample
<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>ExeOutputType>
        <TargetFramework>net10.0TargetFramework>
        <ImplicitUsings>enableImplicitUsings>
        <Nullable>enableNullable>
    PropertyGroup>
    <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App"/>
        <PackageReference Include="ConsoleAppFramework" Version="5.7.3"/>
    ItemGroup>
Project>
// Program.cs
using ConsoleAppFramework;
using Microsoft.Extensions.DependencyInjection;

var app = ConsoleApp.Create();
app.ConfigureServices(services => services.AddSingleton<MyService>());
app.UseFilter<MyFilter>();
app.Run(["cmd", "test"]);

public class MyService
{
    public void Test() => Console.WriteLine("Test");
}

internal class MyFilter(ConsoleAppFilter next, MyService myService) : ConsoleAppFilter(next)
{
    public override async Task InvokeAsync(ConsoleAppContext context, CancellationToken cancellationToken)
    {
        myService.Test();
        await Next.InvokeAsync(context, cancellationToken);
    }
}

[RegisterCommands("cmd")]
public class MyCommand
{
    [Command("test")]
    public int Test()
    {
        return 1;
    }
}

Let me know if there's anything else I can provide. Also, #88 might be related.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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