WebAssembly ve Blazor Nedir ?
Selamlar,
Bu makalede, 2018 MVP Global Summit’de karşıma çıkan Microsoft teknolojiler arasında beni ençok heycanlandıran ve etkiliyen WebAssembly üzerine detaylıca konuşacağız.
Makale içindeki kodlar Blazor Version=”0.3.0″ göre güncellenmiştir.
Peki WebAssembly nedir? Aslında 2015 yılında Google, Mozilla, Apple ve Microsoft’un bir araya gelerek WebAssembly Community Group’u kurmalarıyla başlayan bir oluşumdur. Peki neden bu group kuruldu, çünkü Web uygulamarı artık çok yaygınlaştı. Güncelleme ve kullanım kolaylıklarından dolayı, Desktop uygulamalarının nerede ise yerini aldı. Hali ile beklentiler de arttı. Standart Javascript kodları ihtiyaçları karşılayamaz ya da yazılsa da içinden çıkılamaz bir hal aldı. İşte bu ihtiyaçlara yönelik WebAssembly kavramı hayatımıza girdi. Düşünün artık sunucuya gitmeden tüm işlemlerimizi browser üzerinden yapabileceğiz.
Microsoft tarafından bakarsak, .NET web uygulamalarının şu an halen üzerinde çalışılan Blazor adında bir .NET web framework’ü ile, bildiğimiz browser üzerinde çalıştırılmasıdır. Kısaca backend’e gerek kalmadan, frontend tarafta yazılan C# kodlarının browser tarafında derlenip çalıştırılmasıdır. Bir de bu işin ucundan Steven Sanderson ve Daniel Roth’un tutması, bana iyice ümit verdi. Sanırım heycanımı anladınız. Şimdi aklınıza eminim türlü türlü sorular geliyordur. Güvenlik, farklı dll’ler nasıl import olarak ekleniyor? Sonuçta gene bir dll’mi oluşuyor ? Performans. Şimdi sorulara soru ile cevap verelim :)
Browser + Razor = Blazor!
Bu Blazor kısaca nedir? WebAssembly altında çalışan, .NET’te yazılmış tarayıcı tabanlı (istemci tarafı) uygulamalar için bir frameworkdür. Biz developerlara, sunucu ve istemci arasında kullanılan tüm.Net kodlarını browser üzerede uçtan uca kullanmamıza olanak verir. Ayrıca aynı Angular ve React’da olduğu gibi SinglePageApplication(SPA) platformunun tüm avantajlarını bize sunar.
.NET tabanlı bir SPA framework oluşturmanın ilk adımı, web tarayıcısı içinde .NET kodunu çalıştırmanın bir yolunu bulmaktır. WebAssembly sayesinde, herhangi bir web tarayıcısı (eklentileri olmayan), ilgili dilleri yani yazılan kodları ve import edilen dll’leri derler. WebAssembly, mobil cihazlar da dahil olmak üzere tüm ana tarayıcılar tarafından desteklenmektedir. Performans amaçlı, minimum boyutlarda ve maksimum çalışma performansı için optimize edilmiş kompakt bir byte kod formatıdır. Client-Side’da çalışmasından dolayı, ilk akla gelen güvenlik endişelerine neden olmaz. Çünkü oluşturulan assembly kodları düzenli yani anlaşılır değildir. (ör. X86 / x64 veya benzeri). Bu aslında JavaScript ile yapılan yeni bir byte kod biçimidir.
WebAssembly ile ilgili bir diğer şey ise, Browser’ın çalıştırıldığı zaman kodlarda late-binding’e izin verilmesidir. Yani farklı modüller birleşerek bir uygulama oluşturabilir. Örneğin önceden hazırlanmış standart bir modül, başka bir modül içerisine referans verilerek kullanılabilir.
Peki bu .NET’i nasıl çalıştırıyor? Eh, Mono ekibi sağ olsun. WebAssembly’e, mono tam destek vermektedir. Mono, WebAssembly altında iki modda çalışmaktadır. Interpreted ve Ahead-of-time (AOT)
Interpreted: Mono runtime’da sadece WebAssembly için derleme işlemi yaparken, dll’leri bunun dışında bırakır. Esas .NET .dll
dosyaları, klasik .Net tooları ile harici derlenir.
Ahead-of-time (AOT) : WebAssembly çalışma zamanında doğrudan binary koda dönüştürülür. Yani, içerisine dahil olan tüm Dll’lerde WebAssembly binaries’e dönüştürülür. Kısaca yazılan kod yorumlanmadan doğrudan WebAssembly kodu olarak çalıştırılır. Bu aşamada yine de Monoya sadece (garbage collection gibi) basit yapılar için ihtiyaç vardır.
Interpreted AOT’ye göre çok daha performanslı çalışmaktadır. Çünkü Interpret(yorumlanan) dillerden farklı olarak run-timeda herhangi bir parsing işlemi yapmaz. Bu neden ile başlangıç zamanı çok daha hızlıdır. Çünkü zaten kodun parsing veya optimizasyon yapılmasına ihtiyacı yoktur. Yani yazılan ve binnary formata dönüşen kod, direkt olarak platforma en uygun en optimize machine koduna derlenebilir.
Blazor’da Esas Bileşenler:
- Layouts
- Routing
- Dependency injection
- Lazy loading
- Unit testing harness
Bu kadar PowerPoint açıklamadan sonra :) şimdi gelin bu efsane teknolojiyi nasıl kullanacağımızı hep beraber örnekler ile inceleyelim:
KURULUM: Bu makaledeki çalışma ortamı macOS işletim sistemi, .NetCore ve Ide olarak VSCode’dur.
- .NET Core 2.1 Preview 1 SDK. buradan yüklenir.
- Yeni yaratılacak olan dotnet Blazor Template‘i aşağıdaki gibi yüklenir.
1dotnet new -i Microsoft.AspNetCore.Blazor.Templates - Yeni WebAssembly projesi “BlazorToDoLiST” aşağıdaki gibi oluşturulur.
1 2 3 |
dotnet new blazor -o BlazorToDoList cd BlazorToDoList dotnet run |
Karşımıza aşağıdaki gibi bir ekran gelir:
Öncelikle Blazor ile demo amaçlı gelen default projeleri kısaca inceleyelim:
Genel Blazor Proje yapısı : Ne Nerde
Routing : App.cshtml sayfası üzerinde tanımlanır. Başlangıç dosyası olarak “Program.cs” dosyası gösterilmiştir.
1 2 3 4 5 |
<!-- Configuring this here is temporary. Later we'll move the app config into Program.cs, and it won't be necessary to specify AppAssembly. --> <Router AppAssembly=typeof(Program).Assembly /> |
Program.cs: Aşağıda görüldüğü gibi aynı bir console uygulamasında olduğu gibi :) klasik bir Main() methodu ile yaşam döngüsüne başlanmaktadır. “Index” sayfasında kullanılacak “app” tagı ile render edileceği belirtilmiştir. Ayrıca diğer tüm kullanılacak servis tanımları burada yapılır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using Microsoft.AspNetCore.Blazor.Browser.Rendering; using Microsoft.AspNetCore.Blazor.Browser.Services; using System; namespace BlazorToDoList { class Program { static void Main(string[] args) { var serviceProvider = new BrowserServiceProvider(configure => { // Add any custom services here }); new BrowserRenderer(serviceProvider).AddComponent<App>("app"); } } } |
wwwroot/index.html: Program.cs’de geçen “app” başlangıç sayfası olan “index.html”‘de kullanılır. Bu sayfada, proje içerisinde kullanılan “bootstrap” ve” blazor-boot” dosyaları include edilmesinden başka <app>Loading…</app> ile render edilecek sayfa “<body>” içerisine konur.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>BlazorToDoList</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="css/bootstrap/bootstrap-native.min.js"></script> <script type="blazor-boot"></script> </body> </html> |
_ViewImports.cshtml: Tüm sayfalarda kullanılacak .Net ve diğer kütüphaneler burada tanımlanır.
1 2 3 4 5 6 7 |
@using System.Net.Http @using Microsoft.AspNetCore.Blazor @using Microsoft.AspNetCore.Blazor.Components @using Microsoft.AspNetCore.Blazor.Layouts @using Microsoft.AspNetCore.Blazor.Routing @using BlazorToDoList @using BlazorToDoList.Shared |
Layouts
Pages/_ViewImports.cshtml: Sayfalarda kullanılcak Layout yapıları yine burada ek olarak tanımlanır. Bu projede Ana layout MainLayout dosyasıdır.
1 |
@layout MainLayout |
Shared/MainLayout: Sayfanın bir başka Interface veya sayfadan türetilmesi ==> Blazor syntax => “@implements ILayoutComponent” şeklinde yapılır.
- Sayfada kullanılacak Menu ==> “<NavMenu />” şeklinde, ana kısım “@Body” tagı ile belirlenir.
- “@functions { public RenderFragment Body { get; set; } }” : Sayfanın yüklendiğinde çalıştırılan C# kodu Blazor Syntax ==> “@function {}” içinde tanımlanır. Aşağıda “RenderFragment()” methodu ile “Body” render edilir.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@implements ILayoutComponent <div class='container-fluid'> <div class='row'> <div class='col-sm-3'> <NavMenu /> </div> <div class='col-sm-9'> @Body </div> </div> </div> @functions { public RenderFragment Body { get; set; } } |
Shared/NavMenu: Sayfanın solundaki menu, aşağıda görüldüğü gibi tanımlanmıştır. “<NavLink” ==> “/” tıklanınca herbir sayfada tanımlanan path’e gidilir. Bu şekilde bir tanımlama ==> “/” ana sayfa demektir. “/counter” Counter sayfasına git demektir. İlgili Router tanımlaması yine “counter” sayfası üzerinde belirtilmektedir. Kısaca erişilecek sayfanın fiziksel adı üzerine yazılır. Erişilmek istenen adres bu ve buna benzer şekilde tanımlanır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<div class='main-nav'> <div class='navbar navbar-inverse'> <div class='navbar-header'> <button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse'> <span class='sr-only'>Toggle navigation</span> <span class='icon-bar'></span> <span class='icon-bar'></span> <span class='icon-bar'></span> </button> <a class='navbar-brand' href='/'>BlazorToDoList</a> </div> <div class='clearfix'></div> <div class='navbar-collapse collapse'> <ul class='nav navbar-nav'> <li> <NavLink href="/" Match=NavLinkMatch.All> <span class='glyphicon glyphicon-home'></span> Home </NavLink> </li> <li> <NavLink href="/counter"> <span class='glyphicon glyphicon-education'></span> Counter </NavLink> </li> <li> <NavLink href="/fetchdata"> <span class='glyphicon glyphicon-th-list'></span> Fetch data </NavLink> </li> <li> <NavLink href="/todo"> <span class='glyphicon glyphicon-th-list'></span> ToDo List </NavLink> </li> </ul> </div> </div> </div> |
index.cshtml: @page “/”‘ile sayfaya erişim şekli tanımlanmıştır. “<SurveyPrompt Title=”Blazor ‘ı nasıl buldunuz?” />” Başka bir yerde tanımlı bir UserControl yani başka bir sayfadır. Property’si de Title’dır. Bence bu da efsane bir kullanım. Angulardaki Directivelere denk gelmektedir :)
1 2 3 4 5 6 7 |
@page "/" <h1>Hello, world!</h1> Welcome to your new app. <SurveyPrompt Title="<strong>Blazor 'ı nasıl buldunuz?</strong>" /> |
Shared/SurveyPropmt.cshtml: userControl olarak index sayfasında kullanılan bu sayfa aşağıda görüldüğü gibi “@functions{}” içerisine ilgili “Title” property’si tanımlanmıştır. Sayfa üzerinde parametre olarak girilen “@Title” değişkeni bir text ve tıklandığında gidilecek bir link bulunmaktadır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<div class="alert alert-survey" role="alert"> <span class="glyphicon glyphicon-ok-circle" aria-hidden="true"></span> <strong>@Title</strong> Please take our <a target="_blank" class="alert-link" href="https://go.microsoft.com/fwlink/?linkid=870381"> brief survey </a> and tell us what you think. </div> @functions { // This is to demonstrate how a parent component can supply parameters public string Title { get; set; } } |
Counter.cshtml: NavMenu’de “/counter” şeklinde tanımlı bir sayaç sayfasıdır. Örnek amaçlı yapılan bir değişkenin button’a tıklandığında, 1 arttırılıp o anki zamanla ekrana basıldığı sayfadır.
- @page “/counter” : Routing amaçlı sayfaya nasıl erişileceği belirtilir.
- @functions { } ilgili C# kodlarının ve hatta sınıfların tanımlandığı yerdir.
- void IncrementCount() { time=DateTime.Now; currentCount++; } Button tıklanması ile çağrılacak olan methoddur. Güncel zaman ve “currentCount” değişkeni bir arttırılır.
- <button @onclick(IncrementCount)>Tıkla Beni</button> : Button’un tıklanma eventinde çağrılacak method ==> “
@onclick(IncrementCount)” Güncellendi: “onclick=”@IncrementCount” şeklinde tanımlanır. - <p>Current count: @currentCount : @time</p> : C# tarafında tanımlı değişkenler RazorViewEngine’inden dolayı “@” ile “@currentCount : @time” şeklinde tanımlanır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@page "/counter" <h1>Counter</h1> <p>Current count: @currentCount : @time</p> <!--Eski <button @onclick(IncrementCount)>Tıkla Beni</button>--> <button class="btn btn-primary" onclick="@IncrementCount">Click me</button> @functions { int currentCount = 0; DateTime time=DateTime.Now; void IncrementCount() { time=DateTime.Now; currentCount++; } } |
FetchData.cshtml: Bir servisden ya da json’dan çekilen hava bilgisinin, ekrana basıldığı örnek bir Razor sayfadır.
- @page “/fetchdata” : Routing amaçlı sayfaya erişim bu şeklinde tanımlanmıştır.
- “@inject HttpClient Http” : Sayfa içerisinde “Http.Get()” methodunun kullanılabilmesi için ilgili kütüphane eklenir.
- @functions { WeatherForecast[] forecasts; } : @function içerisinde tanımlı C# kodlarında, “Json”‘dan çekilecek data burda tanımlı WeatherForecast[] dizisinde saklanacaktır.
- protected override async Task OnInitAsync() { forecasts = await Http.GetJsonAsync<WeatherForecast[]>(“/sample-data/weather.json”); } : Sayfa asenkron olarak yüklenirken “weather.json” datası yine asenkron çekilerek “<WeatherForecast[]>” tipinde “forecasts[ ]” değişkenine atanmaktadır. Ve işin en ilginç yanı bu kod client side tarafta yazılmakta ve browser tarafından backend’e ihtiyaç duyulmadan derlenmektedir.
- İlgili sınıf ve 4 property’si yine “@function{}” içinde tanımlanmıştır.
1234567class WeatherForecast{public DateTime Date { get; set; }public int TemperatureC { get; set; }public int TemperatureF { get; set; }public string Summary { get; set; }}
- Sayfanın yukarısında Razor ile çekilen “WeatherForecast[ ]” datası ekrana klasik yol ile basılır.
- “@if (forecasts == null) { <p><em>Loading…</em></p> }” : Asenkron olarak henüz bir kayıt çekilmemiş ise sayfaya “Loading…” yazısı konur. Bunun yerine Loading bir gif de konabilirdi.
- else{} : Kayıt var ise “@foreach (var forecast in forecasts)” json’dan çekilen tüm data tek tek gezilir.
- “@forecast.Date.ToShortDateString()” : Herbir kayıta ait tüm propertyler ekrana “@” işareti ile basılır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
@page "/fetchdata" @inject HttpClient Http <h1>Weather forecast</h1> <p>This component demonstrates fetching data from the server.</p> @if (forecasts == null) { <p><em>Loading...</em></p> } else { <table class='table'> <thead> <tr> <th>Date</th> <th>Temp. (C)</th> <th>Temp. (F)</th> <th>Summary</th> </tr> </thead> <tbody> @foreach (var forecast in forecasts) { <tr> <td>@forecast.Date.ToShortDateString()</td> <td>@forecast.TemperatureC</td> <td>@forecast.TemperatureF</td> <td>@forecast.Summary</td> </tr> } </tbody> </table> } @functions { WeatherForecast[] forecasts; protected override async Task OnInitAsync() { forecasts = await Http.GetJsonAsync<WeatherForecast[]>("/sample-data/weather.json"); } class WeatherForecast { public DateTime Date { get; set; } public int TemperatureC { get; set; } public int TemperatureF { get; set; } public string Summary { get; set; } } } |
wwwroot/sample-data/weather.json: Örnek dummy Weather Json data.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
[ { "Date": "2018-05-06", "TemperatureC": 1, "Summary": "Freezing", "TemperatureF": 33 }, { "Date": "2018-05-07", "TemperatureC": 14, "Summary": "Bracing", "TemperatureF": 57 }, { "Date": "2018-05-08", "TemperatureC": -13, "Summary": "Freezing", "TemperatureF": 9 }, { "Date": "2018-05-09", "TemperatureC": -16, "Summary": "Balmy", "TemperatureF": 4 }, { "Date": "2018-05-10", "TemperatureC": -2, "Summary": "Chilly", "TemperatureF": 29 } ] |
Son ve en önemli örnek olarak gelin bir ToDo sayfası yapalım. Böylece (SAP) application nasıl WebAssembly ile kullanılıyormuş hep beraber inceleyelim.
ToDo.cshtml :
- Önce Navbar.cshtml’e yani menüye, ilgili sayfa link’ini aşağıdaki gibi eklenir:
12345<li><NavLink href="/todo"><span class='glyphicon glyphicon-th-list'></span> ToDo</NavLink></li> - Pages/ToDo.cshtml oluşturulur.
- Sayfa yolu(Routing) ve başlık aşağıdaki gibi tanımlanır.
123@page "/todo"<h1>ToDo</h1>- “function{}” altına TodoItem class’ı, yani yapılacak işler sınıfı aşağıdaki gibi tanımlanır. 2 property’si var. 1 Title (adı), 2 IsDone (yapıldı mı).
1234567function {public class TodoItem{public string Title { get; set; }public bool IsDone { get; set; }}}
- “function{}” altına TodoItem class’ı, yani yapılacak işler sınıfı aşağıdaki gibi tanımlanır. 2 property’si var. 1 Title (adı), 2 IsDone (yapıldı mı).
- function içerisine, yapılacak işlerin tutulacağı “todos[ ]” dizisi aşağıdaki gibi tanımlanır.
1IList<TodoItem> todos = new List<TodoItem>(); - Yeni eklenecek işe karşılık gelen değişken “newTodo” ve bir buttona tıklanınca eğer yeni iş adı null değil ise, “todos [ ]” dizisine ekleyen “AddTodo()” methodu aşağıdaki gibi tanımlanmıştır.
12345678910string newTodo;void AddTodo(){if (!String.IsNullOrWhiteSpace(newTodo)){todos.Add(new TodoItem { Title = newTodo });newTodo = "";}}- Geldik Html tarafa. Sayfa üzerine yapılan işleri gezerek ekrana basan rapor kod parçacığı aşağıdaki gibidir: “@foreach” ile tüm yapı gezilirken. <checkbox>’a “
@bind(todo.IsDone)” Güncellendi: “bind=”@todo.IsDone”” property’si “@bind” “bind=” ile bağlanmıştır. Böylece checkbox tıklandığı zaman sıradaki yani buna bağlı todo sınıfına ait IsDone”‘property’si otomatik olarak değişmektedir. ” Ayrıca “<input>” alana “@bind(todo.Title)” “bind=”@todo.Title”” ile atanması gene ilgili todo item’ın Title propertysi otomatik olarak değişmektedir.
1234567891011<ul>@foreach (var todo in todos){<li><!-- Güncellendi <input type="checkbox" @bind(todo.IsDone) /><input @bind(todo.Title) />--><input type="checkbox" bind="@todo.IsDone" /><input bind="@todo.Title" /></li>}</ul>
- Geldik Html tarafa. Sayfa üzerine yapılan işleri gezerek ekrana basan rapor kod parçacığı aşağıdaki gibidir: “@foreach” ile tüm yapı gezilirken. <checkbox>’a “
- Son olarak listenin sonuna, yeni görev textbox’ı ve bir de Ekle buttonu konulmuştur. Aşağıdaki button’un “
@onclick()” “onclick” methodu ile textbox’a yazılan yeni yapılacak iş değeri, AddTodo() methodu ile ilgili todos[ ] dizisine eklenmekte ve sayfa yeniden render edilmektedir. Oluşan yeni string yapıda, değişen alanlar güncellenerek sayfanın render işlemi sadece değişen bu alanlar için tekrardan yapılmaktadır.
1234<!-- Güncellendi <input placeholder="Yapılacak İş" @bind(newTodo) />--><input placeholder="Yapılacak İş" bind="@newTodo" /><!-- Güncellendi <button @onclick(AddTodo)>Görev Ata</button>--><button onclick="@AddTodo">Görev Ata</button> - Sayfanın başına yapılacak işlerin sayısı: Aşağıdaki gibi Linq kullanılarak yazdırılmıştır. Böylece listeye her eklenen iş için, bu değer henüz tamamlanmadığı için 1 artmaktadır. Ayrıca tamamlandı şeklindeki checkbox’ın, işaretlenmesi durumunda bu sayı aynı (SPA) olduğu gibi otomatik olarak 1 azalmaktadır.
1<h1>Kalan İş Sayısı (@todos.Where(todo=>!todo.IsDone).Count())</h1>
ToDo.cshtml (Full):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
@page "/todo" <h1>Kalan İş Sayısı (@todos.Where(todo=>!todo.IsDone).Count())</h1> <ul> @foreach (var todo in todos) { <li> <!-- Güncellendi <input type="checkbox" @bind(todo.IsDone) /> <input @bind(todo.Title) />--> <input type="checkbox" bind="@todo.IsDone" /> <input bind="@todo.Title" /> </li> } <!-- Güncellendi <input placeholder="Yapılacak İş" @bind(newTodo) /> <button @onclick(AddTodo)>Görev Ata</button>--> <input placeholder="Yapılacak İş" bind=@newTodo" /> <button onclick="@AddTodo">Görev Ata</button> </ul> @functions { IList<TodoItem> todos = new List<TodoItem>(); string newTodo; void AddTodo() { if (!String.IsNullOrWhiteSpace(newTodo)) { todos.Add(new TodoItem { Title = newTodo }); newTodo = ""; } } public class TodoItem { public string Title { get; set; } public bool IsDone { get; set; } } } |
Browser üzerinde backend taraflı herşeyi yapamazsınız. Mesela browser üzerinden TCP socket’i dinleyemessiniz. “System.Net.Sockets.TcpListener” bu durumda hiçbir işe yaramaz. Ya da “System.Data.SqlClien”‘ın doğrudan browser üzerinden kullanılması doğru değildir. Aksi halde “PlatformNotSupported exception” hatası alırsınız. Kısa vadede karşımıza, WebAssembly’nin uygun olmadı daha birçok durum çıkacaktır. Fakat NuGet package geliştiricileri ilerde bunlara da izin vericek düzenlemeler yapacaklardır.
Benim aklıma gelen bir diğer sorun ise var olan javascript kodlarının .Net kodları tarafından çağrılması idi. Ama bununda üzerinde aşağıdaki gibi halen çalışılmakta ve Javascript kodları C# içerisinden çağrılabilmektedir.
1 2 3 4 5 6 7 8 9 10 11 |
// JavaScript kodu Blazor.registerFunction('doPrompt', message => { return prompt(message); }); //.NET üzerinden çağrılması: // C# kodu public static bool DoPrompt(string message) { return RegisteredFunction.Invoke<bool>("doPrompt", message); } |
Sayfa içerisinde render işleminden sonra oluşan düz string değerin örneğin 20mb, 30mb gibi değerlere gelmesi, sonrasında cache’e alınsa da ilk çalışma anında performans kaybının yaşanmasına neden olucaktır. Halen üzerinde çalışılan ve şu an için 3 farklı yol ile çözüm aranan bu sorun, WebAssembly’nin üzerinden atlaması gereken en büyük basamaklardan biridir.
Değişiklik yapıldığı zaman, hızlıca tekrar derleme işleminin yapılıp sonuçlarının görülememesi, bunun için uygulamanın durdurulup yeniden derlenmesinin gereksinimi ve debug işlemlerinin henüz eklenmemesi, ilk göze çarpan eksikler olarak görülebilir. Ama bunlar aşılamayacak sorunlar değildir. Server Side kodların ClientSide tarafda, browserların gücü kullanılarak derleme işleminin yapılması, sayfadaki değişkenlerin Html nesnelere @bind edilerek basılması ve ilgili nesnelerin propertylerinin değişmesi durumunda, sayfanın (SPA) tekrar render edilerek değişimin direk görülmesi gerçekten muazzam. Unutulmamalıdır ki Blazor halen deneysel olarak geliştirilen bir .NET web frameworküdür. Ve bence webassembly web teknolojilerinin gelecekteki mihenk taşıdır. Çünkü browser istenen her dili derlemektedir. Bu da Javascript’e büyük bir destek sağlamakta ve front tarafı da dilden bağımsız bir hale getirmektedir.
Geldik bir makalenin daha sonuna. Yeni bir makalede görüşmek üzere hoşçakalın.
Source Code : https://github.com/borakasmer/WebAssemblyWithBlazor
Kaynaklar:
Ellerinize sağlık.Bu konudaki makalelerinizi sabırsızlıkla bekliyorum.
Teşekkürler,
Yeni şeyler öğrendikçe sizler ile paylaşacağım.
Eline saglik abi. Cok guzel bir yazi olmus. Sanirim webin gelecegi cok farkli bir hal alacak gibi.
Teşekkürler,
Bence ilerde hem web hem de mobile Applicationlar baya bir değişecek:)
Böyle bir mükemmel mekaleyi okuduğum için size teşekkür ederim.Bu kadar tecrübeli insandan ancak bu kadar müthiş bir yazı gele bilirdi
Çok teşekkür ederim. Beni onure ettiniz :)
Ellerinize sağlık çok güzel bir makale olmuş.
Teşekkürler Oğuz..
Yine her zamanki gibi Türkçe kaynak sıkıntısı olan bir makale hazırlamışsınız. Emeğinize sağlık hocam. Devamını bekliyoruz.
Ben teşekkür ederim Mehmet.
0.4.0 ile neler değişti acaba?
Merhaba, Blazor’da bu yıl sonunda değişimler olabileceğini duydum. Webasamly tarafında değil de server tarafında geliştirebilirsin tavsiyesi aldım. 2021 kasım ayında .net maui’nin çıkacağını duydum. Türkçe kaynak bulamadım çok fazla olanlarda yüzeysel anlatıyorlar. Bu konuda sizin ön görünüz nedir ? Proje geliştirirken Blazor webasamly kullanmaya devam etmeli miyiz ? Yoksa blazor server app üzerinde mi geliştirelim ? Ya da MVC core kullanmaya devam mı edelim ? Siz bu konuda ne düşünüyorsunuz. Ayrıca Maui hakkında makale yazmayıda düşünüyor musunuz ? Teşekkür ederim.