İ. Deniz YILMAZ

System Resiliency, Application Performance & Software Engineer

C# ile Cross Platform Part II


Blazor Hybrid ve Blazor WASM ile cross-platform uygulama


Neler yapılabildiğini gösterdim. Şimdi de nasıl yapılıra geliyoruz. Yazının sonunda anlattıklarımın toparlanmış halinin reposunu bulabilirsiniz.

Giriş

Merhabalar tekrardan. Daha önceden Blazor ile neler yapıldığından bahsetmiştim. Şimdi de bu yazıda nasıl yapıldığı kısmına geliyorum. Yazının sonunda ise tek bir kod yazarak Web, MacOS, Windows, iOS ve Android için çıktı alabileceğiz.

Mobile Blazor Bindings Kurulumu

Daha önce MBB’nin deneysel olduğundan bahsetmiş miydim? Bahsetmediysem bahsedeyim. Evet arkadaşlar MBB henüz deneysel bir template. Yani bugı bilmem nesi oldukça bol. Peki bugsız ne var ki?

Deneysel olduğundan dolayı Visual Studio’yu açıp next next next diyerek oluşturabileceğimiz bir proje değil. Yani burada CLI kullanmamız gerekecek. Öncelikle sizi Terminal’e ya da Command Prompt’a (ya da her ne kullanıyorsanız) alalım. Aşağıdaki kodları yazarak MBB templatelerinin kurulumunu yapıyoruz. Repeat after me:

dotnet new -i Microsoft.MobileBlazorBindings.Templates::0.5.50-preview

Tebrikler! Artık Blazor ile mobil proje kurulumuna bir adım daha yaklaştınız. Şimdi de cd komutu ile projeyi kurmak istediğiniz directoryye gitmeniz gerekmekte.

Ara Uyarı

Proje lokasyonu çok diplerde C:/Dıdının/Dıdısının/Dıdısının Dıdısı gibi bir yerde olursa Android projesinin derlenmesinde sorun yaşama ihtimaliniz yüksek. Ben şahsen iki defa aynı hatayı yaptım. İkisinde de “Bu hata neydi ya” diye araştırma yaptım. Çünkü error log bu konuda çok yardımcı olmuyor maalesef.

Oyna Devam..

Projeyi barındıracağımız konuma gittikten sonra yeni komutumuz:

dotnet new blazorhybrid -o FirstBlazorHybridApp

Artık Visual Studio’ya devam edebiliriz.

Blazor Hybrid App template’i ile oluşturulan proje outputu.

Bu aşamada bazı kurulumlar da Visual Studio üzerinden devam etmekte tabi.

Anlatmaya gerek yok, görüyorsunuz.

Üst taraf native UI komponentleri, alt taraf ise WebUI

Hazır templateteki projeyi dümdüz çalıştırdığınızda bu şekilde karşılaştırılmalı bir UI ile karşılaşıyorsunuz. MBB projemizin kurulumu tamamladık. Şimdi de Blazor WASM uygulamamıza geçebiliriz.

Çözüme yeni bir proje ekliyoruz
Blazor WebAssembly App’i seçtikten sonra next next

Tüm kurulumları yapıp projeleri çalıştırdıktan sonra ortaya aşağıdaki gibi bir görüntü çıkmakta.

Blazor WASM ve Blazor Hybrid projeleri farklı projelerde barınmakta

“Ee şimdi tek proje cross platform dedik. Ortada iki tane UI projesi var ne iş?” dediğinizi duyar gibiyim. İşte şimdi bu iki UI projesini Razor Class Library (RCL) ile birleştireceğiz.

Razor Class Library (RCL)

Önceki yazıda bahsetmiştim ama ufak bir parantez açmakta fayda var yine. Özellikle backend yaparken, katmanları farklı projelere ayırırken kullanılan class library proje türünün bir nevi fronta uyarlanmış hali. Yani birden fazla UI projesi yapıyorsanız ve her projede aynı komponentleri kullanıyorsanız, bir RCL projesi ile kendinize tekrar tekrar kullanılabilen bir proje oluşturabilirsiniz. Şimdi de yukarıdaki Blazor WebAssembly projesi ekleme adımlarını baz alarak bir RCL projesi oluşturalım.

Burada ise bazı ayarlar yapmamız gerekiyor. Bazı işleri burada manuel halletmemiz gerekmekte. Visual Studio yeni bir RCL projesi oluştururken bize hangi .NET versiyonu ile oluşturacağımızı soruyor. Ama bize .NET yerine .Net Standard versiyonu kullanma şansı vermiyor. Eğer isimlendirmelerden dolayı aklınız biraz karıştı ise bana değil Microsoft’a teşekkürlerinizi iletebilirsiniz.

Biz öncelikle Visual Studio’nun bize sunmuş olduğu .NET versiyonları arasında (Ben .NET 5.0 seçtim) seçim yapıp projeyi oluşturuyoruz. Sonrasında ise projeyi unload yapmamız gerekli ki serbestçe .csproj dosyasıyla oynayabilelim.

Sonrasında ise RCL projemizin dosya konumuna gidip, csproj dosyasını elimizde bulunan herhangi bir text editörü ile açıyoruz. Sonrasında ise <PropertyGroup></PropertyGroup> tagları arasını aşağıdaki gibi değiştirmemiz gerekmekte.

TargetFramework değiştirildi ve RazorLangVersion propertysi eklendi

TargetFramework’te net5.0 (ya da ne seçti iseniz) yerine netstandard2.1 yazdıktan sonra altına da RazorLangVersion ekliyoruz (Eğer ekli değilse).

Artık projemiz Blazor’ın razor komponentlerini kullanmaya uygun hale gelmiş bulunmakta. Text editorü kaydedip kapattıktan sonra RCL projemizi reload ederek yeniden yükleyebiliriz.

Birleştirme Zamanı

Şimdi de mobil ve web projelerimizin arayüzlerini teke indiriyoruz.

Burada birleştirme olayı da yanlış anlaşılmasın. Aslında birleştirme dediğimiz şey sadece UI’ların birleştirilmesi. Entry pointler ve index.html dosyaları hala her projenin kendisinde saklı. Biz şu an sadece ekranların, komponentlerin, layoutun ve tema dosyalarının tek bir yerden alınmasını sağlıyoruz.

RCL’yi oluşturduktan sonra Hybrid App projemizin (asıl proje olan) içerisindeki razor komponentlerini direkt olarak UI projesine taşıyorum.

Taşıma öncesi görüntü
Taşıma sonrası görüntü

Görüldüğü üzere Hybrid projede App.cs, _Imports.razor ve Main.razor dosyalarını bıraktım. App.cs bizim hybrid projelerimizin entry pointi. Örnek vermek gerekirse, bir Anroid uygulaması MainActivity.cs ile başladıktan sonra Ana hybrid projesindeki App.cs classını construct etmekte.

_Imports.razor, proje dizinindeki razor komponentlerinde tek tek @using kullanmamak için topluca usingleri toplayan bir dosya.

Main.razor ise Blazor WebView’ın başlaması için gerekli dosya. Bu iki dosyayı bırakmamın sebebi, burada Xamarin ve MBB ile ilgili bazı usingler vardı. Eğer Main.razor ve _Imports’u da UI projesine taşısaydım, UI’da gereksiz yere bu nuget paketlerini yükleyecektim. Ayrıca UI projesine kendi _Imports dosyasını da verebiliyorken, böyle bir fazlalığa gerek olmadığını düşünüyorum.

Şimdi de bağımlılıkları ayarlamamız gerekiyor. Öncelikle Hybrid projemizi ve Web projemizi UI projemize bağımlı yapıyoruz.

Ana Hybrid projemizi UI ile bağlıyoruz
Web projemizi UI ile bağlıyoruz

Aşağıdaki görsele geçmeden önce uyarı yapayım. wwwroot klasörünü yanlışlıkla sildim. Sakın onu da silmeyin.

Web projesindeki gereksiz dosyaları siliyoruz

Bağımlılıklarımızı kurduk, gereksiz dosyaları sildik. Şimdi de .cs ve .razor dosyalarındaki referanslarda sorun çıkacak. Dosyaları dolaşarak onları halletmemiz gerekiyor. Mesela Web uygulamamızın Program.cs dosyasında App.razor dosyasını FirstBlazorHybridApp.Web namespace’inde arıyordu. Ama artık biz oradan değil UI projemizdeki namespace’i kullanıyoruz. Buna göre referansı da değiştirmemiz gerekiyor.

Silinen App.razor yerine UI projesindeki App.razor dosyasını göstermemiz gerekiyor.

Bunun gibi örnekler Hybrid projemizin App.cs’inde de mevcut. Oradaki referansları da FirstBlazorHybridApp.UI projesine göre ayarlamamız gerekmekte.

Bitmek Üzere

Şimdi bağımlılıkları ayarladık, referansları düzenledik. Muhtemelen derlemeyi başlattığımızda derlemeyle ilgili bir hata ile karşılaşmayacağız. Son iki şey kaldı. Önce birincisi..

CSS’ler ve varsa eğer JS’ler. Tüm executable projelerimizin içerisinde wwwroot diye bir klasör bulunmakta. Apple projelerinde Resources klasörü altında, diğerlerinde ise ana dizinde. Bu wwwroot klasörleri içerisinde de index.html bulunmaktadır. Yani Blazor aslında SPA mantığında çalışıyor. Şimdi bu index.html dosyaları içerisinde de css dosyalarının yolları bulunmakta. Web projesinde cssler sanki aynı klasörün içindeymiş gibi, Hybridlerde ise sanki ana hybrid projesinin içinde bir wwwroot varmış gibi rotalar yazılmış. Ancak csslerimiz ikisinde de değiller. Hepsi UI projemizin içerisinde bulunuyor ve bu da elbette belirtilen dosya yolunda cssleri bulamayacağı anlamına geliyor. Bunları da değiştirmemiz gerekiyor.

Üstte MacOS ortamındaki index.html’in css dosya yolu değiştirildi. Alttaki ise eski hali.

Tüm index.html dosyalarının yollarını yukarıdaki gibi düzelttikten sonra (çünkü assetleri tekrar tekrar eklememek için hepsini UI projemizde wwwroot klasörüne koyuyoruz.) ikinci aşamaya geçebiliriz.

Hybrid projelerde bir sıkıntı var. MacOS, Android ve iOS projelerinde (Evet Windows bu listede yok), bağımlı olduğumun bağımlı olduğuna bağlıyım mentalitesi maalesef işlemiyor. Yani bağımlılık şöyle ilerlerken:

MacOS -> Hybrid -> UI

kod açısından hiçbir sıkıntı yok. Mesela MacOS’tan UI’daki bir classı kullanabiliyoruz. Ama konu assetlere gelince (CSS ve JS dosyalarımız) MacOS projesi UI projesini hiç tanımamış gibi davranıyor.

Bundan dolayı da MacOS, iOS ve Android projelerinde UI projesine direkt referans da vermek zorundayız.

Windows haricindeki Hybrid projelerden UI projesine referans verilmesi gerekiyor.

Bu da yapmamız gereken son işlemdi. Bunca işlemden sonra hadi bir de çıktısına bakalım.

Web, MacOS ve iOS görünümleri

Gel Gelelim Sorunlara

Şimdiki bölüm ise muhtemelen sizin de karşılaşacağınız, benim de bu yazıyı yazarken arka planda (size göstermesem de) kafayı yediğim kısımlarla ve geçmişteki tecrübelerimle ilgili.

  • MacOS’te Android emülatörünü çalıştırmak. Aslında çalışıyor. Çalışmıyor değil. Ama bir dll exception veriyor ve Mac’te bu exceptionı göremedim bir türlü. Ancak Windows’ta bu exceptionı vermiyor. Gerçek cihazda deneyeyim dedim. Yok olmuyor. Eğer Mac kullanıyorsanız Blazor Hybrid sizi Android konusunda cezalandırıyor bir nevi. Bununla ilgili ise MBB reposunda hala açık duran bir issue da bulunmakta.
  • Dosya yolunun çok uzun olması. Aslında yukarıda da bahsetmiştim. Windowsta çalışıyorsanız ve dosya yolunu çok uzun tutarsanız, Android cihaza deploy atamıyorsunuz. C:/Projects’in altına atın geçin zaten. Niye uğraşasınız ki?
  • CSS hatası. Aslında bu bir sorun değil. Ben bu ufak gösterimde karşılaştığım için yazıyorum. Normalde ben tüm /Pages ve /Shared klasörlerini siler ve kendi komponentlerimi yazmaya başlardım. Ama burada hazır template üzerinden hızlıca bir örnek göstermek istediğim için çok detaya inmedim orada. Direkt MBB templateini alıp UI projesine attım. Web’in de içeriğini sildim. Bu da şuna neden oldu. Webin index.html’inde, tüm içeriğimiz <div id=“app”></div> içerisine yansıtılıyor. Ancak MBB’de direkt <app></app> içerisine yansıtılıyor. E tabi hybridin CSS’leri de #app yerine app olarak ayarlı. Bu hatadan dolayı webde ekranı göremiyodum. Ekranı göremememin sebebinin cssten ötürü kaymış olduğunu anlamam zaman aldı.

Benim gerek bu yazıyı yazarken, gerekse de bir kaç aydır deneyimlediğim haliyle MBB ve Blazor Wasm birleşimi ve sorunları bu şekildeydi. Eğer sizin de başka sorunlarınız olursa buraya yorum yazabilir ya da bana ulaşabilirsiniz. Gerekirse burayı da güncellerim yeni sorunlar için.

Kaynaklar

MBB Reposu

dotnet/MobileBlazorBindings
Check out the documentation for how to build your first app: https://docs.microsoft.com/mobile-blazor-bindings Mobile…github.com

MBB Hakkında Detaylı Dökümantasyon Ve Örnek App

Experimental Mobile Blazor Bindings
Experimental Mobile Blazor Bindings enable developers to build native and hybrid mobile apps using C# and .NET for…docs.microsoft.com

Leave a Reply

Your email address will not be published. Required fields are marked *.

*
*