This is the fifth article in a series about one way to use the Model-View-ViewModel pattern with client side Blazor. If you would like to read the series from the beginning the first article is located here:

All of the source code that goes with this series is available on GitHub. The code that represents the starting point of this article is contained in the ArticleFour branch and the 4.4 release. The code at the ending of this article will become the ArticleFive branch and the 4.5 release. All of the code and articles have been updated to use .Net Core 3 Preview 4.

Why are we doing this?

I have had several questions come up more than once since I started working with Blazor and started using MVVM to build a client side app. Those questions are:

How do I get my code out of my View?

Why do I need a ViewModel when I can do everything in my View?

Why do I even need MVVM for my Blazor app?

That last question might be the easiest one to answer. The really short answer is “You might not need MVVM for your app”. The use of MVVM (or any design pattern) is situational and the goal is to reduce complexity in your application. If you are not transforming any of the data in your model before you display it with the UI and if you don’t have the same data being displayed in multiple parts of your application you might not have a good use case for MVVM. MVVM lets you break up your application into smaller classes with well defined responsibilities. If your classes are already small in the beginning and only have a single responsibility there is nothing to gain from breaking them up further.

That being said you can start off without MVVM and introduce it later using refactoring if your code was reasonably designed to start with. A single View which does everything can be refactored into a View and a ViewModel. That ViewModel can then be refactored into a ViewModel and a Model at a later time. If you have followed this series of articles from the beginning you’ve seen that we started with FetchData.razor and refactored it from a single View in the beginning to full MVVM with multiple children over the course of four articles.

The @functions{} block

I currently have mixed feelings about @functions{} . On the one hand I feel that there shouldn’t be any code in the View; it should be UI markup. On the other hand I can’t count how many times in the last 20 years I was investigating the behavior of a page and realized I was only looking at the ViewModel and needed to go look at the code behind. Blazor is still in preview so for the time being I am going to hold off on making a personal decision on the matter and show both ways to interact with the View. I will however say that it is important to clearly understand that some code should be part of the View and other code belongs in the ViewModel.

To work through looking at the code behind we are going to start building up the structure of a shopping cart. This should provide us with some valid examples of using code in the View and in the ViewModel. To start things off we will need items to put in our cart so go to the BlazorMVVM.Shared project and add a new class InventoryItem.cs . Populate that class with this code:

There’s not much there but it’s enough to work with for our examples. Next we will make a ViewModel. To prove my earlier point I am not going to make a separate Model and just put everything in here. Down the road when we are ready we can refactor and extract the Model out into its own class. Make a new class ShoppingCartViewModel.cs and put the following code in it.

You can see we built a class and declared the necessary interface to use it. We put a List<InventoryItem> in our class and made it accessible with the property Cart . We also added three methods to our class; one to add items to the cart, one to total the quantity and price and finally one to display prices in my local currency (apologies to the rest of the world).

With the ViewModel created we can register it in Startup.cs with the syntax that everyone should be used to by now:

services.AddTransient<IShoppingCartViewModel, ShoppingCartViewModel>();

The final step is do create a View to bind to and display our shopping cart. Create a new View named ShoppingCart.razor and paste in the following code:

Finally go to NavMenu.razor and add a new section that allows us to navigate to our shopping cart.

With all of this in place we can launch our application and see our cart but there is not really much of anything to see. Lets add an OnInit() call to our View that loads items into our card when the page loads. We can pretend that this simulates a user coming back to our site after having navigating away with items still in the cart. Add this @functions block to the bottom of the View.

If we now launch our app and navigate to our shopping cart we will see several items along with totals:

Moving to code behind

Now lets say that design decision is to use code behind and not use the @function block in the View. This is not a lot of work. The basic idea is that we make a class that inherits from ComponentBase and then have the View inherit from that class. Everything available to the View will be accessible in that class.

First go into our Views folder and add a new class ShoppingCart.razor.cs . Visual Studio will be helpful and nest that code beneath the View. We will have a class name conflict with ShoppingCart , go into the new class and rename it ShoppingCartBase and have it inherit from ComponentBase . With the code behind wired up we can go back to our View and have it inherit from the code behind.

@inherits ShoppingCartBase

With that in place we can start migrating code out of the View and into the code behind. First remove all three using directives from the view and put them at the top of the code behind. Next remove the inject directive at the top of the page and put it into the code behind as well. The new code will look different from the constructor injection we’ve been doing in our classes up to this point.

[Inject] public IShoppingCartViewModel ViewModel { get; set; }

It was hard to realize it when we were using @inject in a razor View but we were actually doing property injection and not constructor injection this whole time for our Views. This line of code lets us use property injection to pass the ViewModel into our code behind.

The final step is to remove the OnInit() method from our @functions and place it in our code behind class. We can then delete that empty block from our View. After shuffling everything around our View now looks like this:

and the code behind looks like this:

If we launch the application once more we will see that everything still works and we have a separate View, code behind and ViewModel.

Code behind vs ViewModel

So we have two different classes now holding code that can affect our View. When do we put code in the code behind and when do we put code in the ViewModel?

Currently I feel that the only reason we need to use the code behind is to gain access to the lifecycle methods of the View. Every layer of MVVM is not aware of the layer above it. The Model does not know anything about the ViewModel that it gets injected into and the ViewModel does not know anything about the View. If you need to hook into OnInit , OnParametersSet , OnAfterRender or if you are going to call BuildRenderTree you are going to be working in the code behind.

If you are going to be formatting your data you are probably going to want to do it in the ViewModel. Go back to the ViewModel and look at the DisplayPrice() method. We could have put this code into the code behind just as easily as into the ViewModel. However if we build a new View and bind our ViewModel to it and that method had been in the code behind it would not be available. We would have to duplicate our code in the new View again if we had taken that route. With that function in the ViewModel we have access to it every time we use that ViewModel throughout our system.

I feel that the proper way to wire up the View to the ViewModel is to do everything possible with a binding in the razor file. If you need to use @functions or the code behind try to make it a method call to keep the level of separation the same.

Wrapping Up

By now you should have some good ideas regarding when and how to use @functions , code behind and ViewModels. I will say again that Design Patterns are guidance and there is always more than one way to do something. Take this information and use it to build something better than the examples we went through today.

In the next article the plan is to add multiple components to our shopping cart and examine the behavior of multiple components inside of one View when using MVVM with client side Blazor.