Is it possible to define and implement razor component interfaces?
I guess I would imagine something like the following for components (I'm aware this isn't valid code)
IWelcomeComponent.razor
@code
{
[Parameter]
public string Name;
}
WelcomeComponentA.razor
@implements IWelcomeComponent
<div>
Hello @Name!
</div>
@code
{
[Parameter]
public string Name;
}
WelcomeComponentB.razor
@implements IWelcomeComponent
<div>
Welcome @Name!
</div>
@code
{
[Parameter]
public string Name;
}
Why would I like this? Per install display changes. Ideally I would like to be able to define which type of components get used via config, similar to how I do this when defining which IEmailService
I want to use.
switch (configuration.GetValue<string>("EmailProvider"))
{
case "Mock":
services.AddScoped<IEmailService, MockEmailService>();
break;
case "Smtp":
services.AddScoped<IEmailService, SmtpEmailService>();
services.Configure<SmtpConfiguration>(configuration.GetSection("SmtpConfiguration"));
break;
default:
throw new Exception("appsettings.json EmailProvider must be set. Use 'Mock' to send emails to console log");
}
so if I wanted to implement WelcomeComponentB
I would have something that lets me state "hey, when I say IWelcomeComponent I want you to show WelcomeComponentB", again I'm aware this isn't remotely correct but something like...
services.AddScoped<IWelcomeComponent, WelcomeComponentB>();
and then within my razor pages, each IWelcomeComponent
would render as a WelcomeComponentB
e.g.
<IWelcomeComponent Name="Chris"/>
would render as
<div>
Welcome Chris!
</div>
Any ideas? Thank you.
CodePudding user response:
- You can extend from
ComponentBase
for component blazor component inheritance. Additionally, it can implement interfaces - Check out the new experimental
DynamicComponent
if you want truly dynamic type-driven component polymorphism. https://docs.microsoft.com/en-us/aspnet/core/blazor/components/dynamiccomponent?view=aspnetcore-6.0
However, I am not sure the idea of injecting a blazor component is valid. You cannot inject a blazor component as a service.
CodePudding user response:
Not sure if you searching for something like this, but I used it in an similar situation as you described
@CreateComponent();
@code {
private RenderFragment CreateComponent() => builder =>
{
builder.OpenElement(0, "p", implementedBySomething.YourString);
builder.ElementClose();
};
}
Like this you can render everything at runtime