Поддержка  •  Дневник  •  Без рекламы  •  О сайте  •  Реклама  •  Поставить баннер  •  Прислать  •  Хроника  •  Translate Гости: 7    Участники: 0 Авторизация Авторизация   Регистрация 
Метод Научного Тыка
RULVEN
Поиск  
Blackball iMag | интернет-журнал
Каталог


Начало » Разработка ПО » Компиляция и запуск C# и Blazor внутри браузера
Мне повезёт!

Компиляция и запуск C# и Blazor внутри браузера


Компиляция и запуск C# и Blazor внутри браузера
Добавлено: Пн 07.12.2020 • Sergeant
Источник: источник
Просмотров: 630
Комментарии: 0


Если вы Web-разработчик и ведете разработку для браузера, то вы точно знакомы с JS, который может исполняться внутри браузера. Существует мнение, что JS не сильно подходит для сложных вычислений и алгоритмов. И хотя в последние годы JS cделал большой рывок в производительности и широте использования, многие программисты продолжают мечтать запустить системный язык внутри браузера. В ближайшее время игра может поменяться благодаря WebAssembly.

Microsoft не стоит на месте и активно пытается портировать .NET в WebAssembly. Как один из результатов мы получили новый фреймворк для клиенской разработки — Blazor. Пока не совсем очевидно, сможет ли Blazor за счет WebAssembly быть быстрее современных JS — фреймворков типа React, Angular, Vue. Но он точно имеет большое преимущество — разработка на C#, а так же весь мир .NET Core может быть использован внутри приложения.

Компиляция и выполение C# в Blazor

Процесс компиляции и выполнения такого сложного языка как C# — это сложная и трудоемкая задача. А можно ли внутри браузера скомпилировать и выполнить С#? — Это зависит от возможностей технологии (а точнее, ядра). Однако в Microsoft, как оказалось, уже все подготовили для нас.

Для начала создадим Blazor приложение.

После этого нужно установить Nuget — пакет для анализа и компиляции C#.

Install-Package Microsoft.CodeAnalysis.CSharp

Подготовим стартовую страницу.

@page "/"
@inject CompileService service

Compile and Run C# in Browser




   

       
       
   

   
   

       

           
@ResultText

       

   

   

       

           
@CompileText

       

   



@functions
{
    string CsCode { get; set; }
    string ResultText { get; set; }
    string CompileText { get; set; }

    public async Task Run()
    {
        ResultText = await service.CompileAndRun(CsCode);
        CompileText = string.Join("\r\n", service.CompileLog);
        this.StateHasChanged();
    }
}

Для начала надо распарсить строку в абстрактное синтаксическое дерево. Так как в следующем этапе мы будем компилировать Blazor компоненты — нам нужна самая последняя (LanguageVersion.Latest) версия языка. Для этого в Roslyn для C# есть метод:

SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code, new CSharpParseOptions(LanguageVersion.Latest));

Уже на этом этапе можно обнаружить грубые ошибки компиляции, вычитав диагностику парсера.

foreach (var diagnostic in syntaxTree.GetDiagnostics())
{
    CompileLog.Add(diagnostic.ToString());
}

Далее выполняем компиляцию Assembly в бинарный поток.

CSharpCompilation compilation = CSharpCompilation.Create("CompileBlazorInBlazor.Demo", new[] {syntaxTree}, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

using (MemoryStream stream = new MemoryStream())
{
    EmitResult result = compilation.Emit(stream);
}

Следует учесть, что нужно получить references — список метаданных подключенных библиотек. Но прочитать эти файлы по пути Assembly.Location не получилось, так как в браузере файловой системы нет. Возможно, есть более эффективный способ решения этой проблемы, но цель данной статьи — концептуальная возможность, поэтому скачаем эти библиотки снова по Http и сделаем это только при первом запуске компиляции.

foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
    references.Add(
        MetadataReference.CreateFromStream(
            await this._http.GetStreamAsync("/_framework/_bin/" + assembly.Location)));
}

Из EmitResult можно узнать была ли успешной компиляция, а так же получить диагностические ошибки.
Теперь нужно загрузить Assembly в текущий AppDomain и выполнить скомпилированный код. К сожалению, внутри браузера нет возможности создавать несколько AppDomain, поэтому безопасно загрузить и выгрузить Assembly не получится.

Assembly assemby = AppDomain.CurrentDomain.Load(stream.ToArray());
var type = assemby.GetExportedTypes().FirstOrDefault();
var methodInfo = type.GetMethod("Run");
var instance = Activator.CreateInstance(type);
return (string) methodInfo.Invoke(instance, new object[] {"my UserName", 12});
 

На данном этапе мы скомпилировали и выполнили C# код прямо в браузере. Программа может состоять из нескольких файлов и использовать другие .NET библиотеки. Разве это не здорово? Теперь идем дальше.

Компиляция и запуск Blazor компонента в браузере.

Компоненты Blazor — это модифицированные Razor шаблоны. Поэтому чтобы скомпилировать Blazor комопнент, нужно развернуть целую среду для компиляции Razor шаблонов и настроить расширения для Blazor. Нужно установить пакет Microsoft.AspNetCore.Blazor.Build из nuget. Однако, добавить его в наш проект Blazor не получится, так как потом линкер не сможет скомпилировать проект. Поэтому нужно его скачать, а потом вручную добавить 3 библиотеки.

microsoft.aspnetcore.blazor.build\0.7.0\tools\Microsoft.AspNetCore.Blazor.Razor.Extensions.dll
microsoft.aspnetcore.blazor.build\0.7.0\tools\Microsoft.AspNetCore.Razor.Language.dll
microsoft.aspnetcore.blazor.build\0.7.0\tools\Microsoft.CodeAnalysis.Razor.dll

Создадим ядро для компиляции Razor и модифицируем его для Blazor, так как по умолчанию ядро будет генерировать код Razor страниц.

var engine = RazorProjectEngine.Create(BlazorExtensionInitializer.DefaultConfiguration, fileSystem, b =>
    {
        BlazorExtensionInitializer.Register(b);
    });

Для выполнения не хватает только fileSystem — это абстракция над файловой системой. Мы реализовали пустую файловую систему, однако, если вы хотите компилировать сложные проекты с поддержкой _ViewImports.cshtml — то нужно реализовать более сложную структуру в памяти.
Теперь сгенерируем код из Blazor компонента C# код.

var file = new MemoryRazorProjectItem(code);
var doc = engine.Process(file).GetCSharpDocument();
var csCode = doc.GeneratedCode;

Из doc можно также получить диагностические сообщения о результатах генерации C# код из Blazor компонента.
Теперь мы получили код C# компонента. Нужно распарсить SyntaxTree, потом скомпилировать Assembly, загрузить её в текущий AppDomain и найти тип компонента. Так же как в предыдущем примере.

Осталось загрузить этот компонент в текущее приложение. Есть несколько способов, как это сделать, например, создав свой RenderFragment.

@inject CompileService service

   


       

            @Result
       

   


@functions
{
    RenderFragment Result = null;
    string Code { get; set; }

    public async Task Run()
    {
        var type = await service.CompileBlazor(Code);
        if (type != null)
        {
            Result = builder =>
            {
                builder.OpenComponent(0, type);
                builder.CloseComponent();
            };
        }
        else
        {
            Result = null;
        }
    }
}

Заключение

Мы скомпилировали и запустили в браузере Blazor компонент. Очевидно, что полноценная компиляция динамического кода C# прямо внутри браузера может впечатлить любого программиста.

Но тут следует учитывать такие "подводные камни":

  • Для поддержки двунаправленного биндинга bind нужны дополнительные расширения и библиотеки.
  • Для поддержки async, await, аналогично подключаем доп. библиотеки
  • Для компиляции связанных Blazor компонентов потребуется двухэтапная компиляция.

Все эти проблемы уже решены и это тема для отдельной статьи.



Мне нравится 0   Мне не нравится 0



Комментарии

Чтобы добавить видео с YouTube, нужно написать [@youtube=xxxxx] , где xxxxx – ID видео.


Комментарии: 0
Нет ни одного комментария.
RSS-лента
Поделиться ссылкой:
Рекомендации и полезные советы по правильному натуральному кормлению кошки Рекомендации и полезные советы по правильному натуральному кормлению кошки
65 фактов о кошках 65 фактов о кошках
Коктейль виски со Швепсом – оригинальные и согревающие рецепты Коктейль виски со Швепсом – оригинальные и согревающие рецепты
Как наступает оргазм и как вести себя при оргазме?
24 популярных экзотических домашних питомца 24 популярных экзотических домашних питомца
Сравнительный возраст кошки и человека Сравнительный возраст кошки и человека
40 способов развлечь кота 40 способов развлечь кота
Корпоративный туалетный этикет
300+ вопросов по JavaScript на собеседовании 300+ вопросов по JavaScript на собеседовании
Эротика прикосновений Эротика прикосновений

csharp
Delegates in C#: A comprehensive guide Ср 27.03.2024
Delegates in C#: A comprehensive guide
C# и .NET: Blazor Пн 25.03.2024
C# и .NET: Blazor
Ср 20.03.2024
Creating functions that return multiple values in C#
Задача по языку C#: Игра «Крестики Нолики» в консоли Пн 26.02.2024
Задача по языку C#: Игра «Крестики Нолики» в консоли
Pagination in a .NET Web API with EF Core Ср 21.02.2024
Pagination in a .NET Web API with EF Core
Зачем нужен MediatR? Пн 24.04.2023
Зачем нужен MediatR?
C# 8.0 and .NET Core 3.0 – Modern Cross-Platform Development Build applications with C# NET Core, Entity Framework Чт 02.02.2023
C# 8.0 and .NET Core 3.0 – Modern Cross-Platform Development Build applications with C# NET Core, Entity Framework
Год: 2019
C# 6 and .NET Core 1.0 Modern Cross-Platform Development Чт 26.01.2023
C# 6 and .NET Core 1.0 Modern Cross-Platform Development
Год: 2016
Concurrency in C# Cookbook Чт 12.01.2023
Concurrency in C# Cookbook
Год: 2019
C# 7 and .NET Core: Modern Cross-Platform Development, 2nd Edition Вт 04.01.2022
C# 7 and .NET Core: Modern Cross-Platform Development, 2nd Edition
Год: 2017
Effective C# (Covers C# 6.0): 50 Specific Ways to Improve Your C#, 3rd Edition Вт 21.12.2021
Effective C# (Covers C# 6.0): 50 Specific Ways to Improve Your C#, 3rd Edition
Год: 2017
C# and XML Primer Чт 09.12.2021
C# and XML Primer
Год: 2017
More Effective C#: 50 Specific Ways to Improve Your C#, 2nd Edition Вт 16.11.2021
More Effective C#: 50 Specific Ways to Improve Your C#, 2nd Edition
Год: 2017
Разработка обслуживаемых программ на языке C# Чт 28.10.2021
Разработка обслуживаемых программ на языке C#
Год: 2017
C# 7 and .NET Core Cookbook Вт 05.10.2021
C# 7 and .NET Core Cookbook
Год: 2017
C# для профессионалов. Тонкости программирования, 3-е издание Вт 11.05.2021
C# для профессионалов. Тонкости программирования, 3-е издание
Год: 2014
C# 6.0 in a Nutshell, 6th Edition Чт 29.04.2021
C# 6.0 in a Nutshell, 6th Edition
Год: 2015
CLR via C#, 4th Edition Вт 30.03.2021
CLR via C#, 4th Edition
Год: 2012
.NET Domain-Driven Design with C# Вт 16.03.2021
.NET Domain-Driven Design with C#
Год: 2008
Pro LINQ: Language Integrated Query in C# 2010 Чт 25.02.2021
Pro LINQ: Language Integrated Query in C# 2010
Год: 2010
Pro LINQ: Language Integrated Query in C# 2008 Вт 23.02.2021
Pro LINQ: Language Integrated Query in C# 2008
Год: 2007
Software Architecture with C# 9 and .NET 5, Second Edition Сб 13.02.2021
Software Architecture with C# 9 and .NET 5, Second Edition
Год: 2020
C# 9 and .NET 5 Сб 13.02.2021
C# 9 and .NET 5
Год: 2020
Компиляция и запуск C# и Blazor внутри браузера Пн 07.12.2020
Компиляция и запуск C# и Blazor внутри браузера
C# 7.0. Карманный справочник Вт 24.11.2020
C# 7.0. Карманный справочник
Год: 2017
Professional C# 6 and .NET Core 1.0 Вт 17.11.2020
Professional C# 6 and .NET Core 1.0
Год: 2016
Пн 16.11.2020
Develop and Install a Windows Service in C#
C# 7.1 and .NET Core 2.0 – Modern Cross-Platform Development Вт 10.11.2020
C# 7.1 and .NET Core 2.0 – Modern Cross-Platform Development
Год: 2017
C# 8 Quick Syntax Reference Вт 03.11.2020
C# 8 Quick Syntax Reference
Год: 2020
Problem Solving in Data Structures and Algorithms Using C# Вт 27.10.2020
Problem Solving in Data Structures and Algorithms Using C#
Год: 2018
C# 7 и .NET Core. Кросс-платформенная разработка для профессионалов Вт 01.09.2020
C# 7 и .NET Core. Кросс-платформенная разработка для профессионалов
Год: 2018
Язык программирования C# 7 и платформы .NET и .NET Core Вт 25.08.2020
Язык программирования C# 7 и платформы .NET и .NET Core
Год: 2018
The C# Player’s Guide, 3rd Edition Вт 31.12.2019
The C# Player’s Guide, 3rd Edition
Год: 2016
Design Patterns in C# Пн 09.01.2017
Design Patterns in C#
Год: 2012
Язык программирования C# 5.0 и платформа .NET 4.5 Пн 02.01.2017
Язык программирования C# 5.0 и платформа .NET 4.5
Год: 2013
The C# Player's Guide, 2nd Edition Пн 12.12.2016
The C# Player's Guide, 2nd Edition
Год: 2015
C# Programming Yellow Book Пн 21.11.2016
C# Programming Yellow Book
Год: 2015
Pro WPF 4.5 in C#, 4th Edition Пн 11.04.2016
Pro WPF 4.5 in C#, 4th Edition
Год: 2012
Pro Silverlight 5 in C#, 4th Edition Ср 06.04.2016
Pro Silverlight 5 in C#, 4th Edition
Год: 2012
Pro C# 5.0 and the .NET 4.5 Framework, 6th Edition Пн 21.03.2016
Pro C# 5.0 and the .NET 4.5 Framework, 6th Edition
Год: 2012
Pro ASP.NET 4 in C# 2010, 4th Edition Ср 16.03.2016
Pro ASP.NET 4 in C# 2010, 4th Edition
Год: 2010
Pro .NET 4 Parallel Programming in C# Ср 09.03.2016
Pro .NET 4 Parallel Programming in C#
Год: 2010
A Programmer's Guide to C# 5.0, 4th Edition Ср 24.02.2016
A Programmer's Guide to C# 5.0, 4th Edition
Год: 2012
CLR via C#, 3rd Edition Сб 27.10.2012
CLR via C#, 3rd Edition
Год: 2009
Книги
Fundamentals of Software Architecture вчера, 10:13
Fundamentals of Software Architecture
Год: 2020
Refactoring with C# Вт 23.04.2024
Refactoring with C#
Год: 2023
Building IoT Visualizations using Grafana Вт 09.04.2024
Building IoT Visualizations using Grafana
Год: 2022

Разработано на основе BlackNight CMS
Release v.2024-05-05
© 2000–2024 Blackball
Дизайн & программирование:
О сайтеРеклама
Visitors
Web-site performed by Sergey Drozdov
BlackballРекламаСтатистикаПоддержка | МузыкаПлейлистыКиноВидеоИгрыАудиоПрограммыСтатьиКартинкиЮморФорумДневник сайтаПрислать контент