Using DI in components works great with inject (@inject or in Codebehind with [inject]).
Now how does it work if you want to use DI in a normal class? I found exactly the same question here:
Blazor - Call JavaScript from C# class
Unfortunately, although the question is marked as answered, it is not clear how this is actually supposed to work. I'll summarize it here:
- you create a class which should be used as DI, here for example for JSInterop (e.g. to use JavaScript outside from components):
public class JsInteropForClasses { private readonly IJSRuntime jSRuntime; public JsInteropForClasses(IJSRuntime jSRuntime) { this.jSRuntime = jSRuntime; } public async void MessageBox() { await jSRuntime.InvokeVoidAsync("MessageBox", "DI question!!!"); } }
- you register service in Program.cs
builder.Services.AddTransient<JsInteropForClasses>();
- and now comes the crucial question, how do you use this in a other class that is not a component (so where you can't use inject)? I applied the suggested solution, but I get argument problem because constructor of DI-class expects an object type IJSRuntime and I don't pass anything during creation:
JsInteropForClasses js = new JsInteropForClasses(); js.MessageBox();
Therefore, I can't use DI (because program can't start).
The following variant does not work either:
JsInteropForClasses js; js.MessageBox();
I searched for a long time, but only found this one entry (see link). All others refer to DI and components.
Does anyone know about how to use DI in own class (not components)?
Thanks
CodePudding user response:
When you register a service in the DI container (in Program.cs) initialization of the service will be handled by the DI. That means you should NOT call the constructor on your own. The only thing you need to do is to register the service (with the interface if necessary) properly. Like this:
builder.Services.AddTransient<JsInteropForClasses>();
or
builder.Services.AddTransient<IJsInteropForClasses, JsInteropForClasses>();
Then you can inject the service (or interface of the service) in the class constructor you want to use. Like:
public class SomeClass {
private readonly JsInteropForClasses jsInteropForClasses;
public SomeClass(JsInteropForClasses jsInteropForClasses) {
this.jsInteropForClasses = jsInteropForClasses;
}
}
or in Razor as shown by Henk here
@inject JsInteropForClasses ij