最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

世界观速讯丨您是否存在想在浏览器动态编译razor的组件的想法?

来源:博客园

不知道是否有人跟我一样想在浏览器上直接可以动态的编译blazor的一些组件库?而不是通过引用NuGet以后才能查看到效果,并且在使用别人的组件的时候可以在动态的调整组件的一些样式


【资料图】

不说了开始正文:

本文我们将使用Masa提供的一个组件实现动态编译github.com直通车 ,执行环境将在WebAssembly中执行,为什么使用WebAssembly而不是Server呢?首先我们需要先了解这俩种模式的执行原理

WebAssembly:

  • Blazor WebAssemblyBlazor WebAssembly,用于使用 .NET 生成交互式客户端 Web 应用。 Blazor WebAssembly使用无插件或将代码重新编译为其他语言的开放式 Web 标准。 Blazor WebAssembly适用于所有新式 Web 浏览器,包括移动浏览器。

Server:

  • Blazor ServerASP.NET Core应用中支持在服务器上托管 Razor 组件。 可通过 SignalR 连接处理 UI 更新。

    运行时停留在服务器上并处理:

    • 执行应用的 C# 代码。
    • 将 UI 事件从浏览器发送到服务器。
    • 将 UI 更新应用于服务器发送回的已呈现的组件。

由于编译是完全可操作的,存在安全问题,在Server的模式下用户编译的环境就是服务器的环境,这样用户就可以通过动态编译代码实现操作侵入安全,问题很严重,如果有心人使用对于安全影响过于严重,不建议在Server中使用动态编译

实现我们来创建一个空的WebAssembly项目

mkdir compileRazorcd compileRazordotnet new blazorwasm-empty

使用vs打开项目添加Masa.Blazor.Extensions.Languages.Razor ,将一下代码添加到项目文件中

修改Program.cs文件的代码

using Microsoft.AspNetCore.Components.Web;using Microsoft.AspNetCore.Components.WebAssembly.Hosting;using compileRazor;using Masa.Blazor.Extensions.Languages.Razor;using Microsoft.AspNetCore.Razor.Language;using Microsoft.CodeAnalysis;var builder = WebAssemblyHostBuilder.CreateDefault(args);builder.RootComponents.Add("#app");builder.RootComponents.Add("head::after");builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });var app = builder.Build();// 初始化RazorCompileRazorCompile.Initialized(await GetReference(app.Services), await GetRazorExtension());await app.RunAsync();// 添加程序集引用async Task?> GetReference(IServiceProvider services){    #region WebAsembly    // need to add Service    var httpClient = services.GetService();    var portableExecutableReferences = new List();    foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())    {        try        {            //你需要通过网络获取程序集,应为无法通过程序集目录获取            var stream = await httpClient!.GetStreamAsync($"_framework/{assembly.GetName().Name}.dll");            if (stream.Length > 0)            {                portableExecutableReferences?.Add(MetadataReference.CreateFromStream(stream));            }        }        catch (Exception e) // There may be a 404        {            Console.WriteLine(e.Message);        }    }    #endregion    // 由于WebAssembly和Server返回portableexecutablerreference机制不同,需要分开处理    return portableExecutableReferences;}async Task> GetRazorExtension(){    var razorExtension = new List();    foreach (var asm in typeof(Program).Assembly.GetReferencedAssemblies())    {        razorExtension.Add(new AssemblyExtension(asm.FullName, AppDomain.CurrentDomain.Load(asm.FullName)));    }    return razorExtension;}

修改Pages\Index.razor的代码

@page "/"@using Masa.Blazor.Extensions.Languages.Razor;
@if (ComponentType != null){ }@code{ private string Code = @"

Doctor Who™ Episode Database

Episodes

  • ...
  • ...
  • ...
Doctor Who is a registered trademark of the BBC. https://www.doctorwho.tv/
"; private Type? ComponentType; private void Run() { ComponentType = RazorCompile.CompileToType(new CompileRazorOptions() { Code = Code // TODO: 在WebAssembly下保证ConcurrentBuild是false 因为Webassembly不支持多线程 }); StateHasChanged(); }}

然后启动程序效果如图:

首次编译会比较慢,在WebAssembly下还可以因为电脑问题造成卡顿,如果是需要提供开发效率可以使用Server调试,在Server调试的话是比WebAssembly快很多,而且WebAssembly还没有做Aot,性能不会太好

来自token的分享

技术交流群:737776595

推荐一个超级好用的Blazor UI组件 MASA Blazor 开源协议 MIT商用完全没问题

关键词: 服务器上 编译代码 可以使用