Mart Apon
Mart Apon

Reputation: 119

Problem with [Inject], not working in C# class (Blazor)

I want to trigger a JavaScript function from .net class in a Blazor Wasm project. I created a class (client side)

  public class InvokeMyJavaScript
{
   private readonly IJSRuntime jSRuntime;

   public InvokeMyJavaScript(IJSRuntime jSRuntime)
   {
      this.jSRuntime = jSRuntime;
   }

   public async ValueTask InvokeMyJs()
   {
      await jSRuntime.InvokeVoidAsync("giveMeAMessage");
   }
}

I added to Program.cs:

builder.Services.AddTransient<InvokeJavaScript>();

In my Razor component I now can do this:

[Inject]
InvokeMyJavaScript imjs { get; set; }

public async void InvokeMyJs()
{
   await imjs.InvokeMyJs();
}

Works perfectly, thanks to the people who helped me here. but when I try to do this from a class it goes wrong. I tried:

[Inject]
InvokeMyJavaScript ij { get; set; }

private async Task TestnaarJs()
{
   await ij.InvokeMyJs();
}

But then I receive an error: Object reference not set to an instance of an object. I cant figure out what is going wrong... How can I inject in a class?

Upvotes: 3

Views: 4171

Answers (1)

Nkosi
Nkosi

Reputation: 247471

[Inject] attribute is meant to work for components, but in order to inject into a normal classes then use constructor injection. Read more about that here

@inject (or the [Inject] attribute) isn't available for use in services. Constructor injection must be used instead. Required services are added by adding parameters to the service's constructor.

//...

private InvokeMyJavaScript ij;

//CTOR
public MyServiceClass(InvokeMyJavaScript ij) {
    this.ij = ij;
}

private async Task TestnaarJs() {
   await ij.InvokeMyJs();
}

//...

Additionally I would suggest abstracting InvokeMyJavaScript behind an interface and injecting the abstraction instead of the concrete implementation to avoid tight coupling to implementation details/concerns.

Upvotes: 4

Related Questions