Blazor

Blazor comes in 2 flavors – serverside and clientside.

This article will discuss the status of ServerSideBlazor in MDriven Turnkey.

Creating Blazor components usable from MDriven Turnkey

Create an Assembly in VS2022 for BlazorComponents

Use .net5.

Import any 3:th party blazor components that you want to base your work on (or work from scratch)

In this example I import MatBlazor 2.9

Create a razor file – in markup. Use the any logic you need to build the component from details in the viewModel you will get access to from the mandatory parameter named VMC wit type Eco.ViewModel.Runtime.VMAbstractMember 

@using MatBlazor
<div class=”my-component”>
     This Blazor component is defined in the <strong>RazorClassLibrary1</strong> package.
   <MatTable Items=”@List” >
     <MatTableHeader>
       <th>@VMC.ViewModelColumn.DetailAssociation.Columns[0].PresentationString</th>
       <th>@VMC.ViewModelColumn.DetailAssociation.Columns[1].PresentationString</th>
       <th>@VMC.ViewModelColumn.DetailAssociation.Columns[2].PresentationString</th>
     </MatTableHeader>
     <MatTableRow>
       <td>@((context[“Attribute1”] as Eco.ViewModel.Runtime.VMNativeTypeAttribute).ValueAsString)</td>
       <td>@((context[“Attribute2”] as Eco.ViewModel.Runtime.VMNativeTypeAttribute).ValueAsString)</td>
       <td>@((context[“Attribute3”] as Eco.ViewModel.Runtime.VMNativeTypeAttribute).ValueAsString)</td>
     </MatTableRow>
   </MatTable>

</div>
@code
{
   [Parameter]
   public Eco.ViewModel.Runtime.VMAbstractMember VMC { set; get; }
   public Eco.ViewModel.Runtime.VMManyAssociation<Eco.ViewModel.Runtime.VMClass> List {
     get{ return VMC as Eco.ViewModel.Runtime.VMManyAssociation<Eco.ViewModel.Runtime.VMClass>; }
   }

}

You must also declare a class implementing IUIComponentFactory  – in this class Turnkey will discover the linking between a component name and the type:

public class UIComponentFactory : IUIComponentFactory
{
   public Dictionary<string, Type> GetComponentTypes()
   {
     var res = new Dictionary<string, Type>();
     res.Add(“Component1”, typeof(Component1));
     res.Add(“BlazorDateTime”, typeof(BlazorDateTime));
     return res;
   }
}

Including Blazor components where MDriven Turnkey expects them

Set your build output of the component file to AssetsTK/EXT_ComponentsRazor

Your project must have have EnableDynamicLoading – this makes .net provide all the needed references in the output:

<PropertyGroup>
   <TargetFramework>net5.0</TargetFramework>
   <BaseOutputPath>C:\temp\SampleModleForAssociations_AssetsTK\EXT_ComponentsRazor</BaseOutputPath>
   <!– This prepares the assembly to be used as a plugin–>
   <EnableDynamicLoading>true</EnableDynamicLoading>
</PropertyGroup>

Referencing a Blazor component from a ViewModel

To use a component you set the tagged value Ext_ComponentRazor to the assembly-name ; component-name – like so: RazorClassLibrary1;Component1

Set this on the viewmodelcolumn you want to have as the mandatory VMC parameter in the component you have defined

Make turnkey load a page as Blazor instead of MVC or AngularJS

To bring up the page rendered with blazor use the blaapp controller like so: http://localhost:5020/blaapp/ViewOneThing/9!1

Tricky things with AssemblyLoaderContext

It was tricky to discover how to intercept the reflection loading that takes place when .net see a razor page referring your components – but basically we load all assemblies from EXT_ComponentsRazor at the same time as any ModelCodeAssemblies for codedress. We then also intercept the AppDomain.CurrentDomain.AssemblyResolve event to see if loader discovers missing assemblies upon compilation of razor page – if so we check our loaded list of EXT_ComponentsRazor assemblies and return the correct one.

Early days – what is left

If you do not provide components for a given datatype we send out our default blazor implementation – our Blazor DataGrid is very rudimentary and not really expected to be used

Save context and left side menus are not all there yet