DEV Community

Claudio Bernasconi
Claudio Bernasconi

Posted on • Originally published at claudiobernasconi.ch

Blazor Components: How to Split Template and C# Code

In the Blazor Introduction and specifically in the article about How to Create a Blazor Component, we’ve seen how simple it is to write C# code for our components.

It’s not the only way to write C# code for our components, though. Instead of having the C# code below the template in the component file, we can move it into a separate file.

Reasons for separating code and template

Some people don’t like having the C# code directly in the component definition file. Although I personally like to have both artifacts within the same file most of the time, there are reasons to split the code into separate files.

  • You might want to reuse parts of your code for multiple components. You maybe want to put the shared code into a library.
  • Or you have a lot of C# code and a big template, and you feel like separating the matters will help with readability and maintainability.
  • As a WPF developer, you might be familiar with the concept of a view template and a code-behind file.

Maybe you prefer to have the template separated from the code-behind.

Moving the C# code into a code-behind file

Let’s take a look at the following ProductCard component definition that we build in the How to Create a Blazor Component article:

<div class="product-card">
    <div class="card" style="width: 18rem;">
        <img class="card-img-top" src="@imageUrl" alt="Card image cap">
        <div class="card-body">
            <h5 class="card-title">@productName</h5>
            <p class="card-text">@productDescription</p>
            <a href="" class="btn btn-primary">Add to cart</a>
        </div>
    </div>
</div>

@code {
    private string imageUrl = 
        "https://dummyimage.com/286x180/8EB1C7/FEFDFF.png&text=Awesome+Product";
    private string productName = 
        "Awesome Product";
    private string productDescription = 
        "You won't believe how great this product is until you actually use it yourself.";
}

Our ProductCard component file lives in the Components folder of our project. We create a new file in the same namespace with the name ProductCard.razor.cs. We open the file and insert the following class definition:

using Microsoft.AspNetCore.Components;

namespace BlazorApp5.Components
{
    public partial class ProductCard : ComponentBase
    {
        private string imageUrl =
        "https://dummyimage.com/286x180/8EB1C7/FEFDFF.png&text=Awesome+Product";
        private string productName =
            "Awesome Product";
        private string productDescription =
            "You won't believe how great this product is until you actually use it yourself.";
    }
}

As we can see in line 6 of the code above, we define a partial class derived from ComponentBase. The ComponentBase class comes from the Microsoft.AspnetCore.Components namespace and acts as the base class for all Blazor components.

We can now remove the @code directive from the template definition within the CardComponent.razor file. The component definition in the ProductCard.razor file looks like this:

<div class="product-card">
    <div class="card" style="width: 18rem;">
        <img class="card-img-top" src="@imageUrl" alt="Card image cap">
        <div class="card-body">
            <h5 class="card-title">@productName</h5>
            <p class="card-text">@productDescription</p>
            <a href="" class="btn btn-primary">Add to cart</a>
        </div>
    </div>
</div>

If we position the cursor on a variable definition and press F12, we will still jump into the code-behind file to the location of the variable definition.

This is how it looks in the Solution Explorer within Visual Studio:

Blazor App: C# Code in Code-Behind File

We have successfully separated the template and the C# code of a Blazor component into different files.

How Blazor components work

Let’s take a look at what we just did. We learned that we could use the @code directive in a .razor file, or we can use a separate .razor.cs file to write our C# code.

The way we define our code only matters at development time. When we compile the application, the compiler turns our @code directive into a C# class for us.

In the end, the .NET runtime executes the code that the compiler creates for us. There are different ways to achieve the same compiler output.

When should I separate the code-behind?

As written above, there are different reasons why you might want to separate the code-behind from the template definition. I suggest having a rule on how you want to create your components.

I’m currently a friend of having both the template and the code within the same file. As long as it’s maintainable, and as long as I don’t want to reuse parts of the code, it feels natural to me.

If I either want to reuse code or if the code file becomes too big, I tend to split the definition into separate files.

In the end, it is a personal preference. The goal of this article is to give you a choice. I hope you understand how to separate the code from the template, and why you might want to do it.

What’s next?

Check out these other blog posts about Blazor:

If you’re interested in learning more about Blazor, you’ll definitely want to join my email list, where I talk a lot about Blazor, share information with the community, and offer answers to your questions.

If you want to dive deep into Blazor, you can also check out my upcoming Blazor – Creating Web Applications with C# online course. Everyone signing up before the launch of the course in April will be eligible for a massive discount.

This article was originally published on claudiobernasconi.ch on February 8th, 2020.

Top comments (2)

Collapse
 
edcharbeneau profile image
Ed Charbeneau #Blazor #StateHasChanged

We no longer need to inherit from ComponentBase. This was the pattern when code-behind was done through inheritance. With partial classes ComponentBase should be available from the other part(ial).

However, it's likely you'll still need the using statement for proper scope and more importantly the [Inject] attribute.
using Microsoft.AspNetCore.Components;

Collapse
 
claudiobernasconi profile image
Claudio Bernasconi

Thank you very much for pointing that out, Ed. I was not aware of this change. I don't think it hurts to define it the way I do it above, but it's great to see that it is not required anymore.