As far as I can tell, all three of these patterns work to inject a DI service in a Blazor (.net 7/C#/Razor) project:
@inject NavigationManager NavManager
in the Razor component[Inject] private NavigationManager NavManager { get; set; }
in the class definiton- The typical DI pattern:
private readonly IMyDependency _myDependency;
public Index2Model(IMyDependency myDependency)
{
_myDependency = myDependency;
}
As far as I can tell, they all work.
Is there any difference in their implementation? Is it safe to use any or all of them?
Thanks!
CodePudding user response:
Additional Information to Dimitris's answer.
Yes there is a difference between 1/2 and 3. A component's injection process (handled by the Renderer process) is run after the Ctor. You can't use any DI services in the Ctor.
The difference between 1 and 2 is nullability.
- With
@inject
, the Razor compiler disables nullable checking for the property. - With
[Inject]
, you need to handle it manually. The normal way to do this is to setdefault!
as the default value. It will never be null once you get toSetParametersAsync
and the normal lifecycle methods as the runtime will throw an exception during the injection process if it can't find the service.
[Inject] private NavigationManager NavManager { get; set; } = default!;
CodePudding user response:
Only difference is that the first two syntaxes you mentioned should be used in Razor components while the third syntax should be used in all other cases.
@inject NavigationManager NavManager
syntax is used to inject services in Razor components using mark-up.
[Inject] private NavigationManager NavManager { get; set; }
is used to inject services in Razor components using C# code. (Inside @code { ... }
section or inside the partial class in code-behind approach).
You can use both approaches in the same component.
@inject IToDoApi ToDoApi
@inject ISomeServiceType AnotherService
@code
{
[Inject]
private IYetAnotherServiceType PropertyInjectedDependency { get; set; }
}
The constructor syntax is used to inject a service to another service.
public class NewsletterService : INewsletterService
{
private readonly IEmailService EmailService;
public NewsletterService(IEmailService emailService)
{
EmailService = emailService;
}
}
Request a service in a component
Code snippets were from: Injecting dependencies into Blazor components