Introduction
This is the second part of the series about implementing open source music notation library Manufaktura.Controls
in Blazor. The first part about Blazor 0.4 can be found here. Article about Manufaktura.Controls
library can be found here.
A few days ago, a new version 0.5.1 of Blazor was released so I decided to write a new article about how the issues described in part 1 have been resolved.
Upgrading the Project from Blazor 0.4 to 0.5
The process of upgrading project from Blazor 0.4 to 0.5 is described in this article.
Updated Blazor libraries are available on Nuget. After updating, you might have to manually edit your project file and change version number of Microsoft.AspNetCore.Blazor.Cli
from 0.4. to 0.5.1:
<DotNetCliToolReference Include="Microsoft.AspNetCore.Blazor.Cli" Version="0.5.1" />
The way of injecting Blazor into HTML has slightly changed:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width">
<title>BlazorApp1</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/site.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>
<script src="_framework/blazor.webassembly.js"></script>
</body>
</html>
There are also some changes in startup classes:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
BlazorWebAssemblyHost.CreateDefaultBuilder()
.UseBlazorStartup<Startup>();
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IBlazorApplicationBuilder app)
{
app.AddComponent<App>("app");
}
}
After applying these changes, the project created in part 1 should run without problems.
Changes in NoteViewer Component
Blazor 0.5 enables a programmer to insert raw HTML in Razor views:
@((MarkupString)RenderScore())
In part 1, I created a RawHtml
component which is not needed anymore so we can remove it from the project as well as the dependency to HtmlAgilityPack
. Now, NoteViewer
component looks like this:
@using Manufaktura.Controls.Model
@using Manufaktura.Controls.Rendering.Implementations
@((MarkupString)RenderScore())
@functions {
[Parameter]
Score Score { get; set; }
[Parameter]
HtmlScoreRendererSettings Settings { get; set; }
private int canvasIdCount = 0;
public string RenderScore()
{
IScore2HtmlBuilder builder;
if (Settings.RenderSurface == HtmlScoreRendererSettings.HtmlRenderSurface.Canvas)
builder = new Score2HtmlCanvasBuilder
(Score, string.Format("scoreCanvas{0}", canvasIdCount), Settings);
else if (Settings.RenderSurface == HtmlScoreRendererSettings.HtmlRenderSurface.Svg)
builder = new Score2HtmlSvgBuilder(Score, string.Format
("scoreCanvas{0}", canvasIdCount), Settings);
else throw new NotImplementedException("Unsupported rendering engine.");
string html = builder.Build();
canvasIdCount++;
return html;
}
}
What Has Been Fixed
The first thing worth noticing is that updating SVG now works properly. When you click Add Note button, a note is added to the staff without problems. On Firefox browser, it is added almost instantly, however in other browsers like Chrome, there is a significant lag of about 1 second. This happens because all DOM manipulation is currently done with invokes so it’s slower compared to JavaScript DOM manipulation (vide this question on Stackoverflow). I hope that the performance will improve in future releases.
In the first part, I mentioned an exception that was thrown in Rebeam
method. Now this method throws a different error:
Uncaught (in promise) Error: System.NullReferenceException:
Object reference not set to an instance of an object.
at System.Linq.Expressions.Interpreter.LightLambda.MakeRunDelegateCtor
(:59341/System.Type delegateType) <0x212c460 + 0x00294> in <d4b4182dc3854440a5ca922d80e29ea1>:0
at System.Linq.Expressions.Interpreter.LightLambda.GetRunDelegateCtor
(:59341/System.Type delegateType) <0x212bde0 + 0x00048> in <d4b4182dc3854440a5ca922d80e29ea1>:0
at System.Linq.Expressions.Interpreter.LightLambda.MakeDelegate
(:59341/System.Type delegateType) <0x212bc50 + 0x0000e> in <d4b4182dc3854440a5ca922d80e29ea1>:0
at System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate
(:59341/System.Runtime.CompilerServices.IStrongBox[] closure) <0x212b3a8 +
0x00028> in <d4b4182dc3854440a5ca922d80e29ea1>:0
at :59341/System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate ()
<0x212b238 + 0x0000a> in <d4b4182dc3854440a5ca922d80e29ea1>:0
at System.Linq.Expressions.LambdaExpression.Compile
(:59341/System.Boolean preferInterpretation) <0x2103b20 + 0x0001c> in
<d4b4182dc3854440a5ca922d80e29ea1>:0
at :59341/System.Linq.Expressions.LambdaExpression.Compile ()
<0x2103908 + 0x0000a> in <d4b4182dc3854440a5ca922d80e29ea1>:0
at Manufaktura.Controls.Extensions.StaffBuilder+<>c.<Rebeam>b__13_1
(:59341/System.Reflection.TypeInfo t) [0x00000] in
C:\Development\manufakturalibraries\Manufaktura.Controls\Extensions\StaffBuilder.cs:229
I will inform you about further progress of implementing Manufaktura.Controls
in Blazor when a new version is released.