¿Tiene alguna idea para compilar dinámicamente los componentes de la maquinilla de afeitar en el navegador?

blazorNo sé si alguien quiere compilar dinámicamente algunas bibliotecas de componentes directamente en el navegador como yo . En lugar de NuGetver el efecto después de la referencia, y al usar los componentes de otras personas, puede ajustar dinámicamente algunos estilos de los componentes.

Por no hablar del comienzo del texto:

En este artículo, usaremos Masaun componente proporcionado para implementar la compilación dinámica de github.com through-train y el entorno de ejecución se WebAssemblyejecutará en él. ¿Por qué WebAssemblyno usarlo Server? En primer lugar, debemos comprender los principios de ejecución de estos dos modos.

Ensamblaje web:

  • Blazor WebAssemblyBlazor WebAssembly, para crear aplicaciones web interactivas del lado del cliente mediante .NET. Blazor WebAssemblyUtilice estándares web abiertos sin complementos ni recompilación de código en otros idiomas. Blazor WebAssemblyFunciona con todos los navegadores web modernos, incluidos los navegadores móviles.

Servidor:

  • Blazor ServerASP.NET CoreLa aplicación admite el alojamiento de componentes de Razor en el servidor. Las actualizaciones de la interfaz de usuario se pueden gestionar a través de una conexión SignalR .

    El tiempo de ejecución permanece en el servidor y procesa:

    • Ejecute el código C# de la aplicación.
    • Envía eventos de UI desde el navegador al servidor.
    • Aplica actualizaciones de la interfaz de usuario a los componentes renderizados que devuelve el servidor.

Dado que la compilación es completamente operable, existen problemas de seguridad. En el modo Servidor, el entorno de compilación del usuario es el entorno del servidor, por lo que el usuario puede compilar dinámicamente el código para lograr la seguridad de intrusión operativa. El problema es muy grave. En serio, es no se recomienda utilizar la compilación dinámica en el servidor

Implementación Vamos a crear un proyecto WebAssembly vacío

mkdir compileRazor
cd compileRazor
dotnet new blazorwasm-empty

Use vs para abrir el proyecto y agregue Masa.Blazor.Extensions.Languages.Razor , agregue el siguiente código al archivo del proyecto

    <PackageReference Include="Masa.Blazor.Extensions.Languages.Razor" Version="0.0.1" />

Modificar Program.csel código del archivo.

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>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

var app = builder.Build();

// 初始化RazorCompile
RazorCompile.Initialized(await GetReference(app.Services), await GetRazorExtension());

await app.RunAsync();

// 添加程序集引用
async Task<List<PortableExecutableReference>?> GetReference(IServiceProvider services)
{
    #region WebAsembly

    // need to add Service
    var httpClient = services.GetService<HttpClient>();

    var portableExecutableReferences = new List<PortableExecutableReference>();
    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<List<RazorExtension>> GetRazorExtension()
{
    var razorExtension = new List<RazorExtension>();

    foreach (var asm in typeof(Program).Assembly.GetReferencedAssemblies())
    {
        razorExtension.Add(new AssemblyExtension(asm.FullName, AppDomain.CurrentDomain.Load(asm.FullName)));
    }

    return razorExtension;
}

Pages\Index.razorcódigo modificado


@page "/"
@using Masa.Blazor.Extensions.Languages.Razor;

<button class="button" @onclick="Run">刷新</button>

<div class="input-container">
    <textarea @bind="Code" type="text" class="input-box" placeholder="请输入执行代码" >
    </textarea>
</div>

@if (ComponentType != null)
{
    <DynamicComponent Type="ComponentType"></DynamicComponent>
}

@code{

    private string Code = @"<body>
    <div id='app'>
        <header>
            <h1>Doctor Who&trade; Episode Database</h1>
        </header>

        <nav>
            <a href='main-list'>Main Episode List</a>
            <a href='search'>Search</a>
            <a href='new'>Add Episode</a>
        </nav>

        <h2>Episodes</h2>

        <ul>
            <li>...</li>
            <li>...</li>
            <li>...</li>
        </ul>

        <footer>
            Doctor Who is a registered trademark of the BBC. 
            https://www.doctorwho.tv/
        </footer>
    </div>
</body>";

    private Type? ComponentType;

    private void Run()
    {
        ComponentType = RazorCompile.CompileToType(new CompileRazorOptions()
        {
            Code = Code // TODO: 在WebAssembly下保证ConcurrentBuild是false 因为Webassembly不支持多线程
        });
        StateHasChanged();
    }

}

<style>
    .button{
      
      
        width: 100%;
        font-size: 22px;
        background-color: cornflowerblue;
        border: 0px;
        margin: 5px;
        border-radius: 5px;
        height: 40px;
    }
    .input-container {
      
      
        width: 500px;
        margin: 0 auto;
        padding: 10px;
        border: 1px solid #ccc;
        border-radius: 5px;
    } 
    .input-box {
      
      
        width: 100%;
        height: 100px;
        border: 1px solid #ccc;
        border-radius: 5px;
        font-size: 14px;
    }
</style>

Entonces el efecto de iniciar el programa es como se muestra en la figura:

La primera compilación será más lenta WebAssemblyy puede atascarse debido a problemas de la computadora. Si necesita mejorar la eficiencia del desarrollo, puede usar la depuración del servidor. La depuración en el servidor es WebAssemblymucho más rápida que eso y WebAssemblyno ha hecho mucho, por lo que el rendimiento no será muy bueno.

Compartir desde token

Grupo técnico de intercambio: 737776595

Blazor UIRecomiende un componente súper fácil de usar Protocolo de código abierto MASA Blazor , MITel uso comercial no es ningún problema

Supongo que te gusta

Origin blog.csdn.net/xiaohucxy/article/details/128742415
Recomendado
Clasificación