Lightweight tools for your next Blazor project
Monday, 20 September 2021
I have been working on a Blazor WebAssembly application for a couple of months. During the development process I realized some small tools might help a lot. Here I want to introduce you to two tools I have developed to tackle my own problems. I hope you could make use of them two.
Styling
Like any web application, it needs lots of styling which has to be done using CSS classes. Each HTML element needs different CSS classes to be applied to it, some permanently some conditionally. I've developed a couple of web application using ReactJS. In ReactJS world there is package called Classnames that simplifies working with CSS classes. Feeling comfortable with it, I decided to replicate its behaviors. The result is Classmate. It allows you to write pieces of code like this:
@foreach (var forecast in forecasts)
{
int tp = forecast.TemperatureC;
<tr class=@(
Classes(
"row",
"cold".If(tp<=0),
"moderate".If(tp>0 && tp<40),
"hot".If(tp>=40)
)
)>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
As you can see each row takes two CSS classes, 'row' and one of 'cold', 'moderate' or 'hot' classes based on its temperature value. Check the documentation to get more familiar with other syntaxes.
Object mapping
Each real application needs some kind of object mapping. The Blazor project I have been working is no exception. I needed to map models to view models. There are lots of options in .Net ecosystem but what I wanted was a very simple and light mapper (because size really matters in Blazor WASM) size I did not need to define advanced and complex rules. Most object mappers are so flexible but in my case this amount of flexibility means heavy deployment size only.
So I developed DirectMapper to solve my problems. Here is the simplest example that show how it works:
public class Product
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public DateTime IntroductionDate { get; set; }
public int InStockQty { get; set; }
public string FullName=> $"{Code} - {Name}";
public bool Available => InStockQty>0;
}
public class ProductVM
{
public string Name { get; set; }
public string FullName { get; set; }
public int InStockQty { get; set; }
public string IntroductionDate { get; set; }
}
.
.
.
using DirectMapper;
// The original model object
var tea = new Product{
Id=1, Code="001",
Name = "Tea", InStockQty=20,
IntroductionDate=new DateTime(2018,10,3)
};
// Creating a clone object by shallow copying properties.
var clone = tea.DirectMap<Product, Product>();
// Creating a view model instance.
/* NOTE: Only Name, FullName and InStockQty properties
* are copied but not IntroductionDate. Read the
* explanation below. */
var vm = tea.DirectMap<Product, ProductVM>();
You can also define conversion rules globally or case-by-case. It is better to check its documentation to get better understanding of its capabilities.