Razor Component interfaces

Viewed 261

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.

2 Answers

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

Related