Erhan Ballıeker

Microsoft Build 2019 Türkiye Etkinliği

Selamlar,

Geçtiğimiz 18 haziran günü Microsoft Türkiye’de Build 2019′ un Türkiye ayağını gerçekleştirdik. Çok değerli konuşmacı ve katılımcı dostlarımızla çok faydalı bir etkinlik olduğunu düşünüyorum. Birçok konuya değindiğimiz bu etkinlikte ben de WebAssembly ve Blazor hakkında bilgiler paylaştım.

Bir önceki yazımda WebAssembly ile alakalı yazımı bulabilirsiniz. Bunun üzerine bu yazımda da sizlere Blazor bahsetmek istiyorum.

WebAssembly’yi .Net dünyasında kullanmak için henüz official pre-relase halinde bulunan Blazor a başvuracağız. Blazor ile Visual Studio da 3 farklı şekilde geliştirme yapmak mümkün. Bunların detayından aşağıda bahsedip örnekler göstereceğim.

  1. Client-Side Blazor
  2. Asp.Net Core Hosted Blazor
  3. Server-Side Blazor

Client-Side Blazor

Bir önceki yazımda bahsettiğim gibi high-level dillerde yazılan kodun wasm a dönüşüp, browser içerisinde javascript sandbox ı içerisinde çalıştırılabilmesi mümkün. Hatta bu zaten WebAssembly nin en güçlü özelliklerinden biri.

Blazor için bu senaryo aşağıdaki şekilde gerçekleşiyor.

yazdığımız C#/Razor dosyaları compile olup .dll haline geliyor. daha sonra bu .dll dosyalarımız mono.wasm runtime ın da çalışabilir hale geliyor. mono.wasm da, javascript runtime üzerinde çalışıyor. Yani özetle şuan bir .dll dosyamız wasm olarak browserda çalışmak için mono ya biraz muhtaç. Ama bunlar arka planda olan şeyler, kullanırken mono vs uğraşmıyorsunuz. Ama yine de bu mono dan itibaren başlayan xamarin in gücünü ve arka planındaki güzelliği de bilmek açısından değerli 🙂

compiletowasm

Projemizde bir mvc projesinde kullandığımız .cshtml sayfalarına benzer olarak, Client-side Blazor da .razor uzantılı dosyaları kullanıyoruz. Bu dosyalar derlendiğinde elde ettiğmiz dll, mono-runtime ile browser içerisinde javascript runtime ın da çalışabilir bir wasm a dönüşüyor.

Tamamen javascript kadar güvenli olduğundan tekrar söz etmek istiyorum, çünkü aşağıdaki resme baktığımızda bir .net web developer ın çok da alışık olmadığı bir takım dosyaların browser tarafına yüklendiğini göreceğiz. Bir çok yazılımcının aklına, browsera a yüklenen .net dll lerini gördüğünde güvenlik ile alakalı sıkıntılar yaratıp yaratmayacağı geliyor. Ama dediğimiz gibi herşey en sonunda javascript kendisinin çalıştığı, sandbox environment ında çalıştığı için en az javascript kadar güvenli.

Capture

Yukarıda ki resme baktığınızda, C# kodumuzun browser içerisinde wasm olarak çalışması için ne kadar fazla dll in de browser a yüklendiğini görüyoruz.

Mono.Security.dll, Mono.WebAssembly.Interop.dll, mono.wasm, solutionname..dll, System.dll, System.Core.dll gibi hem mono hem de .net e bağlı birçok dll in browser a yükleniyor. Bu sayede yazdığımız C# kodları, client side tarafında çalıır hale geliyorlar.

Peki direk filmin sonunu göstermiş olduk ama biraz daha başa sararak herşeye daha detaylıca bakalım.

Öncelikle  ister Blazor ile ister diğer pre-release olan tüm yeni feature ları denemek için neler yapacağımıza bir bakalım.

Blazor .net core 3.0 ile beraber sadece Server-Side desteği ile official olarak gelecek. Client-Side ve Core Hosted taraflarının release olmasına biraz daha vari ama denemekten hatta basit projeleri bu yöntemler ile de yapmaktan çekinmenize hiçbir sebep yok.

Yeni .net core feature larını denemek için aşağıdaki yöntemleri izlemenizi tavsiye ederim.

  1. Öncelikle şuradan Visual Studio 2019 Preview ı download edin. Yeni featureları mevcut stabil VS 2019 da da aktif edebilirsiniz ama, preview ı indirip tüm yeni-henüz release olmamış özellikleri buradan daha hızlı update ler ile takip etmenizde fayda var.
  2. Sonrasında şuradan son güncel .net-core 3.0 sdk sını indirmeniz gerekiyor.

Bu adımlar aslında birçok feature ı deneminiz için yeterli ama Blazor için iki adımımız daha var.

  1. Buradan Asp.Net Core Blazor template ini download edip kurmanız gerekiyor. Oldukça basit bir işlem, bir VSIX dosyası (Visual Studio Extension) kurmaktan farklı değil
  2. Son olarak da, aşağıdaki komutu çalıştırmanı yeterli olacaktır.
    1. dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.0.0-preview6.19307.2

Yukarıdaki tüm adımları tamamladığımızda, Visual Studio 2019 Preview ı açtığımızda, File-> New Project seçip yeni bir Asp.Net Core Project seçtiğimizde karçımıza aşağıdaki gibi bir ekran çıkacak. Yeni gelen, ve gelecek olan tüm proje template lerini burada görebilirsiniz.

Captureas.PNG

yukarıdaki 4 adımı da tamamladığımızda tüm yeni Blazor template leri karçımıza çıkıyor.

Blazor dışında, gRPC service, Worker Service (eski IHostedServices veya Background Services ın yeni hali) gibi yeni templateleri de denemenizde fayda var. Bunlar ile ilgili de en kısa sürede yazmayı planlıyorum.

Şimdilik Blazor a geri dönelim. Seçeneklerden Blazor (Client-Side) seçip Create e bastığımızda karşımıza aşağıdaki gibi bir solution açılacak.

Captureasasa.PNG

Yukarıda gördüğünüz gibi, Asp.Net Core projelerinde olduğu gibi bir Startup.cs, ve Program.cs dosyalarımız mevcut. Değişik gelecek ilk şey, .razor uzantılı dosyalar.Bunlar aslında klasik MVC projelerindeki .cshtml lerden çok da farklı değil. Gerisi tamamen bildiğiniz bir ASp.Net Core proje yapısı.

App.razor dosyasının içerisine baktğımızda aşağıdaki gibi tek bir satır kod görüyoruz.

Burada bir Router tanımlı. Assembly olarak da sadece projedeki Program.cs dosyasının bulunduğu assembly gösterilmiş. Sayfalar arasındaki geçişler sırasında postback olmadan geçişler olduğunu göreceksiniz. Bu router ın tanımlandığı yer.

Router AppAssembly="typeof(Program).Assembly" 

Program.cs dosyasının içerisi de aşağıdaki gibi. Normal bir Asp.Net Core projesi geliştirmesinde bulunduysanız, burada WebHostBuilder yada, HostBuilder kullanıldığını görmüşsünüzdür. Burada fark olarak kullandığımız HostBuilder, BlazorWebAssemblyHost oluyor. Use Startup yerine de yine Blazor için olan, UseBlazorStartup extension metodunu görüyoruz.

 public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
            BlazorWebAssemblyHost.CreateDefaultBuilder()
                .UseBlazorStartup();
    }

Yukarıda ki Program.cs tarafında kullanılmasını söylediğimiz Blazor Startup dosyasıda aşağıdaki gibi. Yine klasik bir core projesinden çok farklı değil. Sadece app ismindeki component imiz, builder a ekleniyor. App.Razor tarafında ki routing tarafının eklendiği ksım. Bir çok hali hazırda yazılmış komponentler mevcut, sizler kendi component lerinizi yazabilirsiniz. Bunlara başka bir yazıda detaylıca değineceğim.

   public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
        }

        public void Configure(IComponentsApplicationBuilder app)
        {
            app.AddComponent("app");
        }
    }

Projede ki en temel kısımları gördükten sonra, .razor dosyalarının içlerine bir bakalım. Örneğin sol taraftaki Navigasyon menüsü için, proje içerisinde NavMenu.razor adında bir dosya mevcut. Bunun içeriği aşağıdaki gibi.



… @functions { bool collapseNavMenu = true; string NavMenuCssClass => collapseNavMenu ? “collapse” : null; void ToggleNavMenu() { collapseNavMenu = !collapseNavMenu; } }

Yukarıdaki gibi normal bir html içerisine, tıpkı cshtml deik gibi C# kodlarımızıda ekleyebilyoruz. Burada ekstra olarak farklı olan şey sayfanın en sonunda function section ı içerisinde yazmış olduğumuz C# kodları. İşte bunlar tam olarak javascript metodları yazar gibi C# metodlarını yazığ sayfa içerisinde kullanacağımız kısım. Counter.razor dosyasına bakarken daha dikkatli inceleyeceğiz.

sayfaların en üst tarafında route ları belirtiyoruz. Örneğin aşağıda Index.razor ı görüyoruz, ekstra bir root a sahip olmadığından direkt olarak “/” ile işaretlenmiş durumda. bu route u verirken sadece başına @page yazmamız gerekiyor.

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

Sayfalar içerisinde başka sayfaları (componentleri – .razor dosyalarını) çağırmak da çok basit. yukarıda gördüğünü gibi Index içerisinde SurveyPrompt dosyası ayrı bir html tag i gibi veriliyor sadece bu kadar. Eğer komponentler içerisine parametre geçmek de istiyorsa bunu da yukarıdaki Title attribute u ile yağtığımız gibi, componenti tanımlarken ki Property adını yazıp verebiliyoruz atamak istediğimiz değeri.

Örneğin SurveyPromt.razor dosyasının alt tarafında yazılan function sekmesi şöyle;

@functions {
      // Demonstrates how a parent component can supply parameters
       [Parameter] string Title { get; set; }
}

Başında [Parameter] attribute ile işaretlenmiş bir Property mevcut. Bu parametreyide aynı isimle başka bir component içerisinden çağırırıken yukarı da index sayfasında yaptığımız gibi, bir html element ine attribute atarmış gibi tanımlıyoruz bu kadar.

Aşağıda bir de counter dosyasına bakalım. basit bir IncrementCount metodu tanımlanmış, currentCOunt değerini bir arttırıyor. Bu metodu html elementine atamak da sadece başına bir @ işareti koyup adını yazmak kadar basit. herşey normal cshtml dosyalarında razor engine kullanırken ki syntax gibi aslında. ama yapabildiklerimiz çok çok daha fazla =)

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" onclick="@IncrementCount">Click me</button>

@functions {
    int currentCount = 0;

    void IncrementCount()
    {
        currentCount++;
    }
}

Bu projeyi çalışıtırığp çıktısına baktığımızda da en üstte gösterdiğim gibi bir çok dll in browser tarafına yüklendiğini görüyoruz. Mono runtime ı sayesinde de dll lerimiz javascript runtime ında çalışabilen wasm a dönüşüyor. Benim gibi javascript i çok seven biri değilseniz, WebAssembly ve Blazor ın yeri sizde de bambaşka olacaktır. =)

Bir sonraki yazımda Server-Side ve Core-Hosted seçeneklerini inceleyeceğiz.

Bir sonraki yazımda görüşmek üzere.

Microsoft Xamarin Türkiye Meetup – Xamarin Forms Shell

Selamlar,

Dün Microsoft Türkiye’de gerçekleştirmiş olduğumuz etkinlikte katılımcılara yeni gelen Xamarin Forms Shell den bahsetmişim. Bu yazımda buna değinmek istedim.

Öncelikle şunu belirtmek isterim ki Xamarin.Forms Shell şuan production da kullanılmaya hazır değil diye düşünüyorum. Geliştirmeler halen devam ediyor, üzerinde daha birçok değişiklik olacaktır. Ama tanımaktan denemekten zarar gelmez. Değişiklikleride hepberaber takip ederiz.

Xamarin Forms Shell i eğer VisualStudio 2019 kurduysanız bir extension paketi kurarak File-> NewProject dediğinizde Template olarak görebilirsiniz.

Template i şuradan indirebilirsiniz.

Bu visual studio extension paketini kurduğunuz da Yeni bir xamarin forms projesi açtığınızda aşağıdaki gibi karşınıza Shell Template i gelecektir.

Capture.PNG

Bunu seçip devam ettiğiniz deki kısma geleceğiz. Ama önce hali hazırda Visual Studio 2019 kurmamış olanların Shell i nasıl deneyeceklerine gelelim.

Visual Studio 2017 de yine bir xamarin forms projesi açıp başlayın.

Sonrasında yapmanız gereken ilk şey platform spesifik projelere gidip Xamarin.Forms.Forms.Init.. den önce

  • global::Xamarin.Forms.Forms.SetFlags(“Shell_Experimental”, “Visual_Experimental”, “CollectionView_Experimental”, “FastRenderers_Experimental”);

kodunu eklemeniz. Bu kod sayesinde şuan experimental olarak geçen tüm diğer özellikleri de test etmeye başlayabilirsiniz. Örneğin CollectionView uzun zamandır beklenen bir Layout idi, FlexLayout ile kısmen sorunlarımız çözüyorduk ama bunu da denemekte fayda olacaktır şimdiden.

Bundan sonra projesine bir Xaml sayfası ekleyip onu Shell sınıfından türetmeniz yeterli olacaktır. Artık sizde bu Shell dosyası üzerinde oynayabilir, çıktıları gözlemleyebilirsiniz.

Gelelim Shell in özelliklerine;

Shell in başlıca amacı şu;

  • Tüm uygulama genelindeki navigasyonları tek bir çatı altında toplayıp, sanki bir storyboard hazırlar gibi hazırlayabilmeniz.

Shell ile beraber web e yakın bir routing mekanizması da geldi. Ama varolan tüm navigaston mekanizması yani Navigaion.Push..Pop.. vs hepsi halen geçerli tabi

Şuanda temel 4 farklı tag imiz var.

Bunlar şunlar;

  • ShellItem
  • ShellSection
  • ShellContent
  • MenuItem

Bınların uygulamaya etkileri  şöyle oluyor.

Temel menülerin dizilimi yukarıda kullanacağınız tag lara göre 3 e ayrılıyor.

  • Her bir ShellItem Sol menüde ki bir Link e karşılık geliyor.
  • Bunların içinde tanımlanmış Herbir Shell Section bottombar olarak karşımıza çıkıyor.
  • Bunun da içerisinde bir yada birden çok Shell Content tanımlarsak bunlar da topbar olarak karşımıza geliyor.

Yani aşağıdaki gibi bir xaml ın menü hiyerarşisi şu şekilde oluyor.

 
<Shell xmlns="http://xamarin.com/schemas/2014/forms" 	
	   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 	
	   xmlns:local="clr-namespace:TailwindTraders.Mobile.Features.Shell" 	
	   x:Class="TailwindTraders.Mobile.Features.Shell.TheShell" 	
	   Title="TailwindTraders"> 
<ShellItem Title="Home“ Route=“Home”> 
	<ShellSection Route=“Section1“>  
		<ShellContent Route=“index”> 
			<local:HomePage1 /> 
		</ShellContent>
		<ShellContent Route=“index”> 
			<local:HomePage2 /> 
		</ShellContent>
	 </ShellSection> 
	 	<ShellSection Route=“Section2“>  
		<ShellContent Route=“index”> 
			<local:HomePage3 /> 
		</ShellContent>
	 </ShellSection> 
</ShellItem> 
</Shell>

Sol tarafta tek bir menü linki. Buna tıkladığımızda, bu sayfada altta iki tab ı olan bir bottom tab. çünkü iki adet ShellSection konulmuş. İlk taba tıkladığımızda da yukarıda 2 tane tab ı olan topbar göreceğiz çünkü bunun içerisine de iki tane shell content konulmuş.

Bunun yanı sıra Flyout dediğimiz tag in Header ve Footer ile istediğimiz gibi oynayıp sol menünün görünümünü düzenleyebiliyoruz.

Routing mekanizması şu şekilde değişiyor.

RouteScheme: Url scheme such as “http” or “app”

RouteHost: The Domain portion of the URI

Route: The base segment of your application’s URI

▪Exp: “app://microsoft.com/myapp/home/section/index”

▪(App.Current.MainPage as Shell).GoToAsync(“app:///newapp/greeting?msg=Hello”);

İstersek sayfalar arasında data taşımak için querystring bile kullanabiliyoruz 🙂

[QueryProperty("Message", "msg"]
    public partial class GreetingPage : ContentPage
    {
        public GreetingPage()
        {
            InitializeComponent();
        }
 
        string _message;
        public string Message
        {
            get { return _message; }
            set
            {
                _message = value;
            }
        }
    }

Dediğim gibi şuan için yeni başlayan projelerinizde asla başlamamanızla birlikte deneysel olarak alışmanızda fayda olduğunu düşündüğümden çok fazla detaylarına girmeden Shell den bahsetmek istedim.

Daha fazla detaylara şuradan ulaşabilirsiniz.

Bir sonraki yazımda görüşmek üzere.

Asp.Net Core 2.1 İle Gelen HttpClientFactory ve HttpClient İle Kıyaslama.

Selamlar,

Üzerinden 3 ay kadar geçmiş olsa da, Eylül 2018 de Microsoft Türkiye tarafından düzenlenen etlinlikte bahsettiğim ve uzunca zamandır, hakkında konuşmak istediğim HttpClientFactory ve HttpClient hakkında yazmaya henüz başlayabiliyorum.

Öncelikle HttpClient dan, yanlış kullanımlarından ve doğru kullanım olsa dahi handikapları nelerdi bunlardan bahsedip, sonrasında HttpClientFactory hakkında yazacağım.

Özellikle uygulamalar arasındaki haberleşme konuları, ve bu alanda kullanılabilecek yeni teknolojiler ilgi alanımda olduğu için, (Resilient network services hakkında yazılarımı buradan başlayarak okumanızı öneririm) bu konuda yazmak istediğim çok şey var.

Önce kısa bir özet geçelim. Eğer bir .net developer iseniz ve dış dünya ile haberleşecek mekanizmalar yazmanız gerekiyor ise (http üzerinden), sırası ile .netframework tarafından bize sunulan API lar şu şekilde idi;

  • HttpWebRequest
  • WebClient
  • HttpClient

Özellikle son senelerde uygulamamlarımızda bir haberleşme olacak ise dış dünya ile(http protokolü ile), kolay kullanımı ve birçok isteri yerine getirebilmesinden, async desteğinden vs çokça sebepten ilk seçenek hemen hemen herkes için HttpClient oluyor.

Aşağıda yanlışları ile birlikte kolay kullanımıına bir örnek görüyoruz. Bir for döngüsü içerisinde, tıpkı microsoft un best-practice lerinde söylediği gibi using bloğu içerisinde bir endpoint e request atıyoruz. Burada diyebilirsiniz ki, – Client ı neden for un içerisinde yazdık dışında yazalım –  doğru diyorsunuz derim. Ama gelmek istediğim nokta başka.


for (int i = 0; i < 13; i++)
{
     using (var httpClient = new HttpClient())
      {
            var result = await httpClient.GetAsync("https://randomuser.me/api?results=5");
            Console.WriteLine($"{result.StatusCode} - {result.IsSuccessStatusCode}");
      }
}

Microsoft der ki;

“Eğer bir api IDisposable dan miras alıyor ise, onu using bloğu içerisinde kullanın”

Aşağıdaki resimde görmüş olduğunuz gibi, HttpClient, HttpMessageInvoker dan o da, IDisposable dan türüyen bir sınıf. Bu durumda bu HttpClient objesini using bloğu içerisinde kullanmakta bir sıkıntı yok gibi düşünebiliriz.

Capture

Lakin ki durum öyle değildir 🙂

Netstat.exe komutunu çalıştırarak pc mizden dış dünyaya açılan Socket lerin durumuna bir bakalım.

Bu arada socket dediğimiz de anlayacağımız şudur. İki bilgisayarın birbiri ile haberleşmesi sırasında birbirlerine verdikleri adres. Sadece IP adresi yeterli değildir bunun yanında bir de port numarası önemlidir.

Ör: browser dan google.com u açtınız. Client tarafındaki socket adresi:ClientIP+60432(dynamic port number)

Aradaki bağlantı ise : ClientIP+dynamicPort —- GoogleIP+80(standart port) şeklinde olucaktır. Session bittikten sonra aynı port yeniden kullanılabilir.

Peki dönelim netstat.exe nin sonuçlarına. Aşağıda ki resimde görebileceğiniz gibi. Ben Console uygulamamı durdurmuş olsam bile yine de HttpClient objelerinin dışarıya açmış olduğu socket lerin TIME_WAIT state inde bekliyor olduklarını görüyorum.

Capture.PNG

Yani aslında client tarafı connection ı kapamış ama eksik kalan paketler olabilmesi vs adına halen socket ler açık.Windows için global olarak bu bekleme süresi 240 sn.

Bu değeri değiştirmemiz mümkün;

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay

ile yeni istediğimiz değeri set edebiliriz.Peki bu şekilde bir kullanım sonunda uygulamanın herhangi bir t anında alabileceğimiz muhtemelen hata nedir?

System.Net.Sockets.SocketException

Peki önce bu genel HttpClient kullanım hatasının çözümüne gelelim. Çözüm aslında basit. Singleton bir HttpClient kullanmak.

private static HttpClient client = new HttpClient();

for (int i = 0; i < 13; i++)
{
	var result = await client.GetAsync("https://randomuser.me/api?results=5");
       Console.WriteLine($"{result.StatusCode} - {result.IsSuccessStatusCode}");
}

Peki client ı singleton yaparak farklı farklı httpclient objeleri oluşturmaktan ve dolayısı ile aslında kapanmış olan connectionların açtığı boşuna bekleyen açık socket israfından kurtulmuş oluyoruz. Fakat bu da beraberinde farklı sorunlar getiriyor.

Bu durumda longlived HttpClient lar yüzünden DNS değişikliği veya Azure tarafında otomatize edilmiş Staging-Production ortamları arasındaki geçişlerde halen eski adreslere gitme vs vs gibi farklı sorunlar karşımıza çıkıyor.

Bunlara da çözüm olarak; DefaultRequestHeaders. ConnectionClose true diyerek http keep-alive-header = false göndermek ve ya ServicePointManager api sini kullanarak kuracağımız bağlantı üzerinde daha low level ayarlar yapmak da mümkün. Fakat herkes tarafında net olarak evet çözüm budur denen bir durum yok.

Client.DefaultRequestHeaders.ConnectionClose = true;

var sp = ServicePointManager.FindServicePoint(new Uri(” https://randomuser.me/api?results=5 “)); 

sp.ConnectionLeaseTimeout = 60*1000;

aşağıdaki github issue sunda konuşulan sıkıntıları fikir sahibi olmanız açısında okumanızı öneririm

https://github.com/dotnet/corefx/issues/11224

Peki gelelim HttpClientFactory e. Bu Asp.net core 2.1 ile gelen api bize neler sunuyor bir bakalım.

HttpClientFactory

Bu api aslında şuan .net dünyasında bir haberleşme durumunda kullanmanız gereken en taze iyi api diyebilirim. Yani henüz başlamadı iseniz kullanmaya, bundan sonraki tüm Asp.Net Core projelerinizde kullanmaya başlamanızı şiddetle tavsiye ederim.

4 temel özelliğinden bahsedebiliriz;

  1. Tüm haberleşmenin merkezi bir şekilde tanımlanma ve konfigüre edilmesi imkanını sunuyor bize
  2. Refit, polly gibi .net foundation dünyasında önemli yeri olan kütüphanelerin extensionları yazıldı bile. Poly-based middleware extensionlar ve delegating handler lar ile request ve responselar üzerinde istediğimiz oynamaları yapabiliyoruz. Bir çeşit interceptor gibi düşünebilirsiniz.
  3. Yukarıd da bahsettiğim HttpClient görünümlü sıkıntıların asıl sebebi aslında HttpClientHandler.  HttpClienFactory de bu HttpClientHandler ın lifetime ını pooling mekanizması sayesinde daha doğru yönettiği için yukarıdaki sıkıntılardan da kurtulmuş oluyoruz.
  4. Kendi Factorysi tarafından oluşturulmuş tüm request ve responların loglanması otomatik olarak sağlanıyor.

 

Peki HttpClientFactory bu sorunlara nasıl çözüm getiriyor?

Şöyleki;

  • HttpClientHandler instance ları pool a alınır ve lifetime ları yönetilir. Default 2 dakika süre ile bu pool da yeni oluşturulmuş olan HttpClient instancelarının kullanımına hazır halde beklerler.HttpClient instance ları yaşadığı sürece, HttpClientHandler da yaşar.
  • 2 dakika sonra expired olarak işaretlenirler. Dolayısı ile, CreateClient ile yeni bir HttpClient instance I oluşturulduğunda, onun kullanabileceği durumda olmaz. Hemen dispose olmaz, çünkü başka dispose olmamış HttpClient ların önceden kullanımına alınmış olabilir.
  • HttpClientFactory, arkada bir background service kullanır ve expire olarak işaretlenmiş ClientHandler I takip eder. Artık referans edilmediklerinde de dispose eder ve connectionları kapar.
  • Pooling feature sayesinde, Socket exhaustion riskini azaltır. Refreshleme mekanizması da DNS update I gibi problemlere (long lived httpclienthandler lar yok artık =) ) çözüm getirir.

HttpClientFactory nin 4 farklı kullanım şekli mevcut.

  • Basic Usage
  • Named Clients
  • Typed Clients
  • Generated Clients

 

Teoril olarak HttpClient ve HttpClientFactory hakkında biraz bahsettikten sonra bundan sonraki yazılarımda bu farklı kullanım şekillerini göreceğiz.

Bir sonraki yazımda görüşmek üzere.

Microsoft Xamarin Istanbul Development Meetup “Xamarin Resilient Network Services Bölüm 1”

Herkese Selamlar,  biraz geç olsa da 25 ekim günü Microsoft Türkiye‘de yaptığımız etkinlikteki konuyla ilgili yazma fırsatı ancak bulabiliyorum. Güzel bir etkinlik günü geçirdik, 3 farklı değerli arkadaşımla beraber aşağıdaki konulara değinmiştik.

• .Net Core ile Dependency Injection (Özgür Kaplan)
Xamarin ile Dependency Injection (Yiğit Özaksüt)
Xamarin ile Resilient Network Services (bunu ben anlattım ve burada da uzunca değineceğim detaylarına.)
C# hakkında doğru bilinen yanlışlar ve performans ipuçları (Cihan Yakar)

Benim anlattığım Xamarin ile Resilient Network Services sunumum ile ilgili proje ve dosyaları buradan inceleyebilirsiniz.

Katılan dinleyici ve konuşmacı tüm arkadaşlara teşekkür ederek kendi konumun detaylarına giriş yapıyorum.

Bu konu ile ilgili aslında yazmak istediğim birkaç blog serisi var. Aslında genel bakış açısını burada belirtip detaylarına diğer blog postlarımda değineceğim.

İlk olarak şu Resilient(Esnek) kelimesinden başlayalım. Ne demek bir yapının esnek olması. Bu aslında şu demek;

  • Kurduğumuz yapı, belli hatalar karşısında nasıl davranacığını önceden bilen, öncelikleri belli ve değiştirilebilir esnek kırılmaz bir yapı olmalı.

Bu yapı, diğer tüm yazılım projelerinde, uygulamayı mümkün olduğunca sağlıklı bir şekilde ayakta tutmak için kullanılan mimari bölümlerin(Ölçeklenebilir olması, esnek olması, hızlı olması, güvenilir olması vs vs..) küçük bir parçası aslında.  Bu sistemin ben yazılım projelerinin olmaz ise olması Networking üzerinde anlattım, çünkü danışmanlıklarımda gördüğüm ve eğitimler de hissettiğim en büyük açık burada mevcut idi.


  using (var client = new HttpClient())
  {
    client.BaseAddress = new Uri("https://randomuser.me/api/");
    var content = await client.GetStringAsync("?results=10&page=1");
    var result = JsonConvert.DeserializeObject<ResponseModel>(content);
  }

Yıkarıda ki kod bloğunu bir bakalım. Birçok projede bir API haberleşmesi için gördüğüm kod bu kadar da kalıyor. Daha üzerine düşünülmüş olanlarda ise bu şekilde bir kullanım generic bir class içerisine yerleştirilmiş ve onun içerisinden haberleşme çağırılıyor oluyor. Fakat içeriği pek de değişmiyor. Peki bu koddaki yanlış nedir? Yada var mıdır?

Benim gördüğüm kadarı ile şöyle;

Koda ilk bakışta bir yanlış gözükmüyor olabilir. Evet derlenir ve çalışır da, hatta herşey iyi giderse response u alıp gerekli çevirme işlemlerini de yapar. Ama işte bu kod bloğunda birçok şey yolunda gider varsayılmış. Http client objesinin static tanımlanmamış olması ve bunun sıkıntılarına başka zaman değineceğim bunu şimdilik göz ardı edelim diğer konulara bakalım.

  • Internette bir sorun olduğunda bu request ne olacak
  • Server dan 500 aldığında request im ne yapmalı,  503 olduğunda ne olmalı.
  • Time out yersem ne yapmalıyım? yeniden göndermeli miyim requesti? Eğer gönderecek isem kaç kere göndermeliyim, ne kadar ara vermeliyim?
  • Response cachlenebilir bir response mu eğer öyle ise bunu da devreye koysam güzel olmaz mı?
  • Bu request uygulama içerisinde gidecek olan diğer requestlere göre bir farkı önceliği var mı?

gibi gibi sorular aklıma geliyor. İşte tüm bu konular üzerinden bir xamarin projesinde kullanmamız ve güzel bir networking altyapısı kurmanız için size 5 farklı ve değerli kütüphaneden bahsedeceğim. Ve bunların hepbirden nasıl uyumlu olarak kullanabiliriz buna değineceğim.

Kütpühaneleri şunlar;

  • Refit: The automatic type-safe REST library for .NET Core, Xamarin and .Net
  • Fusillade: An opinionated Http library for mobile development
  • ModernHttpClientPlatform spesific networking libraries to Xamarin applications
  • Akavache: An Asynchronous Key-Value Store for Native Applications
  • Polly: .Net resilience and transient-fault-handling  library

kısaca açıklamlarını direk kendi github adreslerindeki gibi yazdım kenarlarına. Detaylarına ve örneklerine sırası ile diğer postlarımda başlayacağım. Hepsinden bahsettikten sonra da bir arada bir xamarin projesinde nasıl kullanılırız buna bakacağız.

Bir sonraki yazımda görüşmek üzere.

 

UrhoSharp’a Giriş

Herkese Merhaba,

Bu yazımda 29 Eylül 2017 Cuma akşamı Yiğit Özaksüt  ve Cihan Yakar ile gerçekleştirdiğimiz Xamarin Istanbul Development Meetup etkinliğinde anlattığım UrhoSharp’tan bahsedeceğim.

Meetup’taki sunumumu şuradan indirebilirsiniz.

Şimdi UrhoSharp konusuna gelelim. UrhoSharp, Urho3D adıyla hayata geçmiş ve başarılı bir 3D grafik ve oyun motoru olan Cross-Platform çalışabilen ve C++ API’a sahip projenin, tam olarak Xamarin ve diğer Microsoft ortamlarında çalışabilecek C# / .NET wrappers ile yeniden yazılmış halidir.

urho1

3D konusuna daha önceden hiç bulaşmamış olanlar için öncelikle UrhoSharp’ı kullanırken fazlaca kullanacağımız birkaç  terimden bahsetmek istiyorum.

  • Vertex / Vertices
  • VertexBuffer
  • Geometry
  • Model
  • Material
  • StaticModel
  • Node
  • Light
  • Camera
  • Scene

Bunların neler olduğundan bahsedelim. Boş uzaydaki tek bir noktayı düşünün, bu noktayı UrhoSharp’ta tanımlamak için kullandığımız nesne Vertex ama kendisini tam olarak bu isim ile değil de VertexBuffer nesnesi içine tanımlanmış public structure’lar olarak göreceğiz. Birazdan detaya ineceğim ama öncesinde, boş uzaydaki bu noktanın (yani Vertex in) sahip olduğu özelliklerden bahsetmek istiyorum. Hepinizin tahmin edeceği üzere olmazsa olmaz ilk özellik bu Vertex‘in uzaydaki koordinatı (Position). Bu özelliği UrhoSharp içerisinde yine bolca kullanacak olduğumuz Vector3 nesnesi ile belirtiyoruz. Bu Vector3 nesnesi bizden x, y ve z koordinatlarını isteyen constructure’a sahiptir. Mesela basit bir Vector3 nesnesini şu şekilde tanımlayabilirsiniz:

var coordinate = new Vector3(0,0,0);

(Bu kod ile 3D uzayda, tam orijinde duran,  x, y ve z değerleri 0 olan bir Vector3 tanımlamış olduk)

Vertex‘ in önemli 3 diğer özelliği daha vardır:

  1. Normal: Vertex’in bulunduğu yüzeye dik olan vektördür. Bu özellik öncelikle bize ışık ile etkileşime girme konusunda çok fayda sağlayacak.
  2. Color: Vertex in sahip olacağı renk.
  3. Texture: Vertex in bulunduğu yüzeyi kaplayacak olan dokunun, bu vertex için olan 2 boyutlu koordinatıdır. Vector2 ile tanımlıyor olacağız.

Boş uzayda tanımadığımız bu noktaları, bir araya getirmek için kullanacağımız nesnemiz ise VertexBuffer olacaktır. Yukarıda söylediğim gibi Vertex UrhoSharp’ta programatik olarak birşeyler çizebilmemiz için gerekli olan en küçük parça ama onu bu isimle görmeyeceğiz demiştim. İşte ilgili özellikleri ile bu vertex’i, VertexBuffer altındaki public structure’lar ile şu şekilde tanımlayabilirsiniz:

var VertexBuffer.PositionNormal = new VertexBuffer.PositionNormal {…}

var VertexBuffer.PositionNormalColor = new VertexBuffer.PositionNormalColor {…}

var VertexBuffer.PositionNormalColorTextcoord = new VertexBuffer.PositionNormalColorTextcoord {…}

Position özelliği dışında, diğer özelliklerini boş geçerek bir Vertex tanımlaması yapabilirsiniz. Bir de çokça duyacağınız Vertices adından bahsedeyim. Bu aslında birden fazla Vertex için duyacağınız isimdir yani bir üçgen oluşturmak için 3 adet Vertex tanımladınız diyelim, bu arkadaşları hep beraber çağırmak için Vertices adını kullanacaksınız, bilginiz olsun.

Peki, devam edelim. Noktaları oluşturdunuz ve VertexBuffer içinde bunları topladınız, bu noktaların ne şekilde birleşeceklerini nasıl söylüyoruz?

Geometry: Bu sınıfı aynı ismiyle UrhoSharp’ta yine çokça kullanmanız gerekecek. Geometry, bir veya birden fazla VertexBuffer nesnesinin ne şekilde birleşeceklerini ve nasıl yorumlanacaklarını söylemek için kullanacağımız bir nesnedir.

Vertices hazır, VertexBuffer’lar hazır, Geometry ‘er hazır. Tüm bunlardan sonra bu Geometry nesnelerini bir araya getirip bir görsel tanımlama işine bizi yaklaştıran önemli sınıflardan biri ise Model sınıfı olacak. Model sınıfı ile bir veya birden çok geometry objesini bir araya getirip bir model yaratmış olacağız. Bunu projemize önceden tanımlanmış haliyle, “.mdl” uzantılı dosya olarak ekleyebiliriz ya da programatik olarak bunu başarabiliriz.

Material: Oluşturduğumuz bu model nesnesinin, 3 boyutlu görselliği ile alakalı bileşenlerini Material nesnesi ile tanımlıyoruz. İstersek sadece bir renk verebiliriz (ki bu durumda Vertex’i tanımlarken verdiğimiz Color değerlerini ezmiş oluruz, ama ezmemenin de yolları var tabii.) istersek de bir bitmap vb şekilde yüzeyi kaplayacak olduğumuz dokuyu verebiliriz.

Bu Model  ve Material nesnelerini biraraya getirip, nihai bir görsellik sağlamak için kullancağımız sınıf ise StaticModel component’i olacaktır. Hazır Component demişken, hemen ondan da kısaca bahsedelim. Component nesnesi ile artık hali hazırda olan modelimizi hayata geçirebiliyoruz. Hayata geçirmekten kastım, öylece duran modellerimize, eklediğimiz Component’ler sayesinde, ses yaymalarını, fizik kurallarından etkilenmelerini ve birbirleri ile etkileşime geçmeleri gibi birçok özelliği vermek.

Peki artık modellerimiz hazır, belli componentler ile belli özellikler de aldılar peki bunları ekranda nasıl gösteriyor olacağız?

Son 3 önemli terimden bahsetmek istiyorum,

  1. Camera: 3D ekranımızda Camera nesnesi kendi görüş alanında kalan herşeyi bize gösteriyor olacak. Camera objesininde tabii ki, uzayda bir Position‘ı ışık yayma şekli ve bir görüş alanı olacaktır. Bu görüş alanını FOV (Field Of View) dediğimiz özelliği ile belirteceğiz. (Default hali 45 derecedir.)
  2. Light: UrhoSharp’ ta 3 tip ışık var. Bu ışıkları sahnemizi aydınlatmak ve tüm objelerimizin ne şekilde görüneceğini belirlemek için kullanıyoruz. Tam burada şunu söylemek isterim ki 3D Grafikte Curve (eğri) yüzey diye bir tanım yoktur aslında. Eğim olarak gördüğümüz şey, ışığın geliş şekli ve o yüzeyi oluşturan Vertices’in Normal vektörleri ile yaptıkları açıların etkileşiminden başka bir şey değildir.
    1. Directional: Belli bir yönden gelen ve o doğrultuda ilerleyen sonsuz ışındır. Güneş ışını gibi düşünebilirsiniz.
    2. Point: Belli bir noktadan gelen ve tüm doğrultularda yayılan ışındır. Bir ampulün yaydığı ışın olarak düşünebilirsiniz.
    3. Spot: Belli bir noktadan gelen ve belli bir doğrultuda görülecek ışındır. El feneri gibi düşünebilirsiniz.
  3. Scene: Tüm modellerimiz ve kamera ile ışık sayesinde oluşturduğumuz sahneyi temsil etmektedir.

Bu kadar fazla terimden bahsettikten sonra örnek yapmadan olmayacaktır tabii ki. Bir sonraki yazımda, tüm anlattıklarımı içeren, güzel örnekler ile karşınızda olacağım. O zamana kadar, bu terimleri sindirmenizi, UrhoSharp ile ilgili bulduğunuz yazıları okumanızı öneririm. Birkaç yardımcı link vermek isterim:

  • Xamarin.com da buradaki linkten başlayarak ilgili tüm UrhoSharp yazılarını okumanızı öneririm. UrhoSharp’ı Xamarin.Forms ile kullanabileceğimiz gibi, tabii ki Xamarin.iOS yada Xamarin.Android ile de kullanabiliriz. Hatta Xamarin dışındaki diğer Microsoft yazılım platformalarında da rahatça kullanabilirsiniz. En nihayetinde başarılı bir  C++ API ile yazılmış kütüphanenin C# ve .NET wrapper ile devşirilmiş halini kullanıyorsunuz.
  • Bu temelleri anlamadan biraz sert kaçar ama, geçenlerde Charles Petzold abimizin yaptığı webiner ı izlemenin de ilerideki aşamalarda faydası olacaktır. Kendisi kod ile mobiusstrip yaptı, izlemeye kesinlikle değer.