Blazor Single-File-Ansatz
Standardmässig werden Blazor-Projektvorlagen mit dem Single-File-Ansatz initialisiert. Es wird eine einzige Datei mit der Endung «.razor» erstellt. Diese Datei beinhaltet sowohl die Präsentationslogik in C# als auch das HTML. Folgendes Beispiel veranschaulicht das:
@*Directives*@
@page "/coffee/single-file"
@*HTML*@
<h3>Coffee</h3>
@foreach (var size in Sizes)
{
<p>@size</p>
}
@*Präsentationslogik*@
@code {
public string[] Sizes { get; set; }
protected override void OnInitialized()
{
Sizes = new string[] { "Small", "Medium", "Large" };
}
}
Wie zu erkennen ist, wird der C# Code mithilfe der Syntax «@code» abgetrennt. Aktionen wie Importe, Attribute, Injections oder Route-Angaben werden im obersten Teil der Datei definiert. Dazwischen ist das HTML wiederzufinden.
Natürlich sieht dies einfach und praktisch aus. Leider gibt es aber auch negative Aspekte. Im vorherigen Beispiel ist der Anteil an HTML überschaubar und einfach. Bei grösserem Umfang leidet darunter schnell die Verständlichkeit und Wartbarkeit einer Anwendung.
Gibt es eine Alternative? Die Antwort ist: Ja, Code-Behind.
Code-Behind-Ansatz für Blazor
Mit ASP.NET WebForms gab es diesen Ansatz bereits. Entwickler, die ASP.NET WebForms kennen, sind damit vertraut. Dabei wird die Präsentationslogik durch eine eigene Klasse vom HTML getrennt. Das gleiche Prinzip gibt es bei den ASP .NET Core WebPages:
Um dasselbe im Blazor zu erreichen, braucht es eine neue C#-Klasse mit folgender Konvention: «[Komponenten-Name].razor.cs». Wird diese Konvention eingehalten, führt dies beim vorherigen Beispiel zu folgendem Ergebnis:
Wurde diese Klasse erstellt, führt dies zu einem Fehler mit der Meldung, dass eine solche schon besteht. Dieser lässt sich mit der «partial»-Signatur auf der neu erstellten Klasse beheben:
public partial class CoffeCodeBehindPartial
{
}
Als nächster Schritt können alle Inhalte im «@code»-Teil in die Klasse kopiert/verschoben werden.
public partial class CoffeCodeBehindPartial
{
public string[] Sizes { get; set; }
protected override void OnInitialized()
{
Sizes = new string[] { "Small", "Medium", "Large" };
}
}
Schon sieht die «.razor»-Datei schlanker aus:
@*Directives*@
@page "/coffee/code-behind-partial"
@*HTML*@
<h3>Coffee</h3>
@foreach (var size in Sizes)
{
<p>@size</p>
}
Partial oder ComponentBase
Die einfachste Variante ist der im vorherigen Teil beschriebener Weg mit «partial». Es gibt eine weitere Möglichkeit, wie das Code-Behind für Blazor umgesetzt werden kann.
Die Datei-Erstellung gestaltet sich genau gleich, wie beim vorherigen Ansatz. Anstelle der Verwendung von «partial» kann der Klassenamen geändert werden. Als Konventionsbeispiel: «[Kompoenten-Name]Base. Ergänzend muss die Klasse von «ComponentBase» erben.
using Microsoft.AspNetCore.Components;
…
public class CoffeCodeBehindBase : ComponentBase
{
public string[] Sizes { get; set; }
protected override void OnInitialized()
{
Sizes = new string[] { "Small", "Medium", "Large" };
}
}
Nun besteht eine Blazor-Komponente als C#-Klasse. Ein Kompromiss ist natürlich die Differenz zwischen Klassennamen und Dateinamen. Im Beispiel wäre dies der Dateiname «CoffeCodeBehind.razor.cs» und die Klasse «CoffeCodeBehindBase».
Bei diesem Ansatz ist die Klasse ein eigenständiges Objekt und muss daher im «.razor» mit @inherits vererbt werden:
@inherits CoffeCodeBehindBase
@*Directives*@
@page "/coffee/code-behind-base"
@*HTML*@
<h3>Coffee</h3>
@foreach (var size in Sizes)
{
<p>@size</p>
}
Auch bei diesem Ansatz wird die Präsentationslogik in einer C#-Klasse getrennt und führt daher zum gleichen Ergebnis.
Mit welchen Ansätzen strukturierst du deinen Blazor-Code? Dein Feedback interessiert mich!