Home > Software design >  .NET CORE dependency injection passing parameter to constructor
.NET CORE dependency injection passing parameter to constructor

Time:12-18

I'm trying to register a class as defined below with DI:

public class MyService
{
    private string _serviceAddress;

    public MyService(string serviceAddress)
    {
        _serviceAddress = serviceAddress;
    }

    public void DoWork()
    {
        // do work
    }
}

In the program.cs, register it with DI:

builder.Services.AddSingleton<MyService>(new MyService(serviceAddress));    

And in the razor component, inject it:

    [Inject]
    MyService myService { get; set; }    
    public WeatherForecast()
    {
        myService.DoWork();  // <- error points to this line
    }

And when accessing the page, got NullReferenceException, pointing to the DoWork line above:

Unhandled exception rendering component: Exception has been thrown by the target of an invocation. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.

Any advice is appreciated.

CodePudding user response:

You can't use [Inject] services in the component constructors. That property/service hasn't been initialized yet. You should be doing that work in component initialization:

    [Inject]
    MyService myService { get; set; }    

    public WeatherForecast()
    {
        // myService is null here. It hasn't been initialized.
        // How could it be? We are currently constructing this object!
    }

    protected override Task OnInitializedAsync()
    {
        // myService has been initialized by this point.
        // You can safely use it now.
        myService.DoWork();
        return base.OnInitializedAsync();
    }

CodePudding user response:

To back up Andy's answer:

The Renderer manages the lifecycle of components. Services are injected into the component instance by the Renderer after it has instantiated an instance of the component. It will throw an exception if it doesn't find a matching service.

The normal way to declare an injected property in a nullable environment is:

[Inject] MyService myService { get; set; } = default!;

If you use @inject in a Razor file it turns off the nullable warnings for the specific declaration.

  • Related