İlkay İlknur

just a developer...

Portable Class Library mi ? Universal App Shared Projects mi ?

Microsoft'un son zamanlarda cross-platform uygulama ve kütüphane geliştirme tarafına yaptığı yatırım oldukça fazla. Gerek Xamarin desteğiyle beraber IOS ve Android tarafında olsun gerekse Windows Store ve Windows Phone tarafında yarattığı teknolojilerle olsun tek bir kod yazarak bu kodun farklı platformlarda çalışan uygulamalar arasında paylaştırılması şu anda bir şekilde sağlanmakta. Aslında bakarsanız bu yöntemlerin hiçbiri tam anlamda süper çözümler olmasa da gerektiği noktalarda doğru şekilde kullanıldığında kod paylaşımı konusunda çektiğimiz acıları oldukça azaltmakta. Peki hangisini ne zaman kullanmalıyız ?

Portable Class Libraries

Portable class libraryler aslında uzun zamandır hayatımızda bulunan ve farklı platformlar üzerinde çalışacak kod yazmak istediğimizde kullandığımız yapılardan ilk akla geleni.

PortableSelect

Portable class librarylerin kısıtlarında bir tanesi de içerisinde platform spesifik kod yazmanın mümkün olmaması. Bu yüzden de portable class librarylerde sadece seçtiğiniz platformlar içerisinde ortak olarak kullanılan kütüphanelere erişiminiz var.

 PortableIntersection

Yukarıda gördüğünüz gibi hangi platformları hedef olarak seçerseniz o platformların kesişiminde bulunan kütüphaneleri kullanabiliyorsunuz.

Eğer kütüphaneniz içerisinde platforma özel bir kod çalıştırmak isterseniz o kodun dışarıdan sizin kodunuz içerisine verilmesini sağlamak zorundasınız. Yani dependency injection vb.. yapıları kullanmak zorundasınız. Örneğin, bir ekran açarak dosya seçme işlemi yaptırmak isterseniz şu şekilde bir çözüm geliştirmeniz gerek.

public class MyLibrary
{
    public async Task Foo(IFileProvider provider)
    {
        var file = await provider.SelectFileAsync(); 
        // Dosya uzerinde islemler
    }
}
 
public interface IFileProvider
{
    Task<string> SelectFileAsync();
}
Portable class libraryi yazdıktan sonra bu kütüphaneyi kullanan Windows 8 uygulaması da portable classın belirlediği interface'te bir file provider yaratacak ve bu providerı portable class library içerisine Foo metodunu çağırırken parametre olarak geçecek.
public class WindowsFileProvider : IFileProvider
{
    public async System.Threading.Tasks.Task<string> SelectFileAsync()
    {
        FileOpenPicker picker = new FileOpenPicker();
        var file = await picker.PickSingleFileAsync();
        return file.Path;
    }
}
 
public class MyApp
{
    WindowsFileProvider fileProvider = new WindowsFileProvider();
 
    public async Task ExecuteAsync()
    {
        MyLibrary library = new MyLibrary();
        await library.Foo(fileProvider);
    }
}

Şimdi gelelim shared projects tarafına. Bakalım o tarafta işler nasıl yürüyor.

Universal App Shared Projects

Visual Studio 2013 Update 2 ile beraber gelen Universal App konsepti ve Shared projectler aslında portable class librarylerde bulunan bazı sıkıntıları çözüyorlar.

Aslında öncelikli olarak belirtmem lazım ki portable class library ile shared projectler tamamen ayrı konseptler. Shared projectler aslında universal app içerisinde bulunan ve universal app'in farklı platformlarda çalışacak uygulamaları arasında paylaştırılacak olan assetleri ve kodları bulunduran kısım.

Shared projectleri aslında biraz daha açarsak temel anlamda Visual Studio içerisinde uzun zamandan beri bulunan file link kavramına benziyorlar. Aslında daha yukarı çıkarak bakarsak file link yapısının biraz daha gelişmiş, derlenmiş toparlanmış hali. Yani siz bir dosyayı birden fazla projede de kullanılacak şekilde saklıyorsunuz. Ancak dosyanın fiziksel olarak tek bir kopyası tutuluyor.

Şimdi gelelim shared code içerisinde platform spesifik kod yazma kısmına. Peki biz yukarıdaki dosya açma işlemini shared code içerisinde yapmak isteseydik nasıl yapacaktık ?

Shared project içerisinde platform spesifik kod yazmak istediğimizde #if directivelerini kullanarak olarak platform spesifik kodları yazabiliyoruz. Örneğin,

public class MyLib
{
    public async Task Foo()
    {
        string filePath = String.Empty;
#if WINDOWS_APP
        FileOpenPicker picker = new FileOpenPicker();
        var file = await picker.PickSingleFileAsync();
        filePath = file.Path;
#endif
#if WINDOWS_PHONE_APP
        //Windows Phone spesfik kodlar
#endif
 
        // Dosya uzerinde ortak islemler
    }
}

Gördüğünüz gibi platform spesifik kodları if directiveleri içerisinde yazdık. Yani bizim kodumuz Windows Store App için derlendiğine #if WINDOWS_APP directive içerisinde olan kodlar kodumuzun içerisinde olacak. Aynı şekilde Windows Phone için derlediğinde de #if WINDOWS_PHONE_APP directive'i içerisinde bulunan kodlar yine source kod içerisinde olacak.

Ancak gördüğünüz gibi uygulamanız büyükdükçe #if directive 'leriniz artacak ve kodunuzun yönetimi de oldukça zorlaşacaktır. Şimdi isterseniz ortalığı toparlayalım ve bu iki çözümünde avantajlarına ve dezavantajlarına kısaca bir bakalım.

Portable Class Libraries vs Universal App Shared Projects

Portable class librarylere baktığımızda yapılarının oldukça basit olduğunu görüyoruz. Yani sadece desteklediğiniz platformlardaki kesişen kütüphaneleri kullanabiliyorsunuz ve ötesi yok. Bu kadar basit. Elinizdeki imkanlarla ilerlemek zorundasınız. Bu da aslında bir anlamda size basitlik sağlıyor. Yani kodunuz içerisinde platform spesifik kod yazmıyorsunuz. Ancak platform spesifik kod yazmak istediğinizde de abstraction yaparak dependency injection, IoC container kullanmanız gerekiyor. Bu nedenle portable class libraryler birden fazla platformu destekleyen algoritmalar veya kütüphaneler(SDK) için ideal ortam.

Shared projects tarafında ise portable class library tarafındaki platform spesifik kod yazamama sıkıntısı çözülüyor. Ancak bu çözüm de hoş bir çözüm değil. En azından bana göre :) Uygulamanız büyüdükçe platform spesifik kodlar da büyüyebilir ve karışabilir. Böylece kodunuzun bakımı da zorlaşır. Ancak bir yandan da aynı işlemleri portable class libraries ile yaptığınızda da hem abstraction vs.. derken işiniz daha da uzuyor hem de kodunuz yine karmaşıklaşıyor. Bu nedenle en basit çözüm Universal App geliştirirken shared projectlerle ilerlemek.

Ancak gördüğünüz gibi cross platform uygulama geliştirme konusunda kod paylaşımı hala  daha tam anlamıyla süper bir çözümle başarılmış değil. Şu anki çözümler sadece acımızı bir nebze hafifletiyor.

Umarım faydalı olmuştur.



.NET Native

2015 yılında .NET Framework vNext ile beraber adını daha sık duymaya başlayacağımız projelerden biri de .NET Native projesi. .NET Native projesi ile amaçlanan C# ile geliştirdiğimiz .NET Framework uygulamalarına C++ ile yazılmış uygulama performansı ve kaynak kullanımı avantajlarını getirmek. Bunu yaparken de developerların elinden sahip oldukları güzellikleri, avantajları almamak.

En Başa Dönersek...

.NET Framework'ü target eden uygulamalar derlendiğinde arka planda IL(Intermediate Language) kodu oluşturulur. Çalışma esnasında da bu oluşturulan IL kodu JIT(Just-In-Time) Compiler'ı tarafında native koda çevrilir. .NET Native projesi de en basit anlamda yazdığınız kodun derlenirken IL'e değilde doğrudan native koda çevrilmesini sağlıyor.

Avantajlar Neler ?

.NET Native'in getirdiği en büyük 3 avantaj uygulamaların daha hızlı açılması, daha hızlı çalışması ve daha optimize memory kullanması. Şimdiye kadar yapılan ölçümlere göre de .NET Native ile beraber Windows Store uygulamaları %60 oranında daha hızlı açılmakta ve %25 oranında da daha az memory kullanmakta.

.NET Native'in getirdiği bir diğer büyük avantaj da .NET Native ile derlenen uygulamanın çalışacağı makinada .NET Framework'ün kurulu olma zorunluluğunun olmaması. Çünkü derleme sırasında .NET Native uygulama içerisinde .NET Framework'te kullandığınız kısımları alıp uygulamanızın native kodu içerisine ekliyor ve böylece .NET Framework bağımlılığından da kurtuluyorsunuz.

C++ tarafinda sahip olduğumuz yukarıdaki avantajlara gördüğünüz gibi .NET Native ile C# tarafinda da sahip olabiliyoruz. Üstelik exception handling, memory management ve garbage collection gibi C++'da bizim düşünmemiz gereken noktalardan da yine soyutlanmış olarak  C# ve .NET Framework'ün getirdiği avantajları da kullanmaya devam edebiliyoruz.

Nasıl Deneriz ?

.NET Native, Visual Studio 14 CTP 3 ile Visual Studio 14 içerisine eklendi. Ancak .NET Native compilerı default olarak aktif değil. Bizim manuel olarak .NET Native compilerını aktifleştirmemiz gerekiyor. Bunun için ilk olarak Windows Store projemizin olduğu solution'ın properties'inden "Active Config"'i Any CPU'dan çıkarıp belirli bir mimariye(x86, x64 veya ARM) çekmemiz gerekiyor.

Active Config Değiştirme

Sonrasında ise Windows Store projesine sağ tıklayıp "Enable for .NET Native"  seçeneğine tıklıyoruz. Bu işlemle birlikte projemiz içerisine default.rd.xml dosyası ekleniyor. Bu dosya içerisinde .NET Native'in kullandığı runtime directive'ler bulunuyor. Ayrıca yine bu aşamada projemiz .NET Native compilerı tarafından analiz edilerek projenin .NET Native compilerı kullanmaya uygun olup olmadığı denetleniyor ve bir rapor çıkarılıyor.

Enable .NET Native Compiler

Son adımda ise artık projenin .NET Native app olarak derlenebilmesi için Windows Store projesine sağ tıklayarak projenin properties'ine gidiyoruz ve Build sekmesini açıyoruz. Build özellikleri içerisindeki "Compile with .NET Native tool chain" seçeneğini seçtikten sonra artık uygulamamız .NET Native compilerı tarafından derlenebilir duruma geliyor.

Enable :Net Native tool chain

Sorular sorular...

Bu yazıyı okuduktan sonra eminim ki aklınıza bazı sorular takılacaktır. Aşağıda aklınıza takılabilecek soruları tahmin edip cevaplamaya çalıştım :)

Soru : .NET Native sadece C# mı destekleyecek ?

.NET Native şuan sadece C#'ı destekliyor. Ancak ilerleyen zamanlarda RTM olmadan VB'de desteklenecektir.

Soru : .NET Native ile sadece Windows Store uygulamalarını mı derleyebiliyoruz ? WPF gibi desktop uygulamalarını derlemek mümkün mü ?

.NET Native'in temel çıkış noktası Windows Store uygulamaları. Universal App'ler de .NET Native tarafından desteklenmekte. Kişisel düşüncem .NET Native'in sadece Windows Store ve Windows Phone uygulamalarını destekleyerek ilk versiyona çıkacağı. Her ne kadar desktop ve server uygulamaları için de çok sayıda talep alsalar da ilk aşamada bu talebi karşılamayacaklarını düşünüyorum.

Soru : .NET Native ile derlenen uygulamalarda reflection kullanabiliyor muyuz ? 

.NET Native uygulamalarında reflection kullanmak mümkün. Ancak reflection için gereken metadataların büyük bir kısmı proje derlenirken compiler tarafından daha optimize bir kod yaratmak amacıyla siliniyor. Bu yüzden metadatasını kullanacağınız tipler için ek olarak default.rd.xml dosyasında tanımlama yapmak gerekiyor. Reflection konusu .NET Native tarafında ilginç bir konu. Bunun için ayrı bir makale yazmayı planlıyorum. :)



Build 2014 1.Gün'de Neler Oldu

Merakla bekledigimiz Build 2014 konferansinda 1. gün sona erdi. Açikca itiraf etmem gerekirse keynote ile beraber bugün beklentilerimin oldukça üzerine çikti. Keynote'un 3 saat olacagi açiklandiginda aklimda o kadar süre nasil oturacagiz sorusu vardi açikcasi. Ancak keynote o kadar güzel planlanmisti ki açikcasi 3 saatin nasil geçtigini anlamadim.

Gelelim birinci günün gelismelerine. Anlatacak çok seyimiz var...

Not : Yazinin giris kismi Windows Phone 8.1 ve Windows 8.1 Update ile gelen son kullanici yeniliklerini içeriyor. Eger son kullanici yenilikleri beni ilgilendirmez developer yenilikleri neler diyorsaniz buradan developer haberlerine ziplayabilirsiniz :)

Windows Phone 8.1

Build konferansinda herkesin bekledigi ilk duyuru hiç süphesiz ki Windows Phone 8.1'in duyurusuydu. Nitekim keynote Windows Phone 8.1'in duyurusuyla basladi. Windows Phone 8.1 ile beraber gelen pek çok güzel özellik var. Ayrica Windows Phone 8'de olan bazi eksikliklerde bu versiyonla beraber giderilmis.

Cortana Personal Assistant

Microsoft'un uzun süredir üzerinde çalistigini bildigimiz personal assistant'i Cortana'yi sonunda görebilme sansimiz oldu. Cortana'nin en büyük rakibi malumunuz Apple tarafindaki Siri. Ancak gördügüm kadariyla Cortana su an kadar Siri'den oldukça önde.

Cortana ile yapabileceklerinizin açikcasi ucu bucagi yok :) Hemen bir örnek vermem gerekirse sesli olarak hava durumunu sorup istediginiz yerin hava durumunu hemen görebiliyorsunuz.

Ya da diyelim ki bugün hangi toplantilariniz var görmek istiyorsunuz. Hemen Cortana'ya sorup ögrenebilirsiniz.

Cortana açikcasi sizin telefonunuzdaki sekreteriniz :) Istediginiz her seyi ona sorabilir, istediginiz seyleri zamani geldiginde ondan size hatirlatmasini istiyebilirsiniz. Hatta bazi seyleri siz söylemeden onun yapmasini da saglayabilirsiniz. Bunun için Cortana'nin bir not defteri var :) Not defterine ilgi duydugunuz alanlari yazarsaniz Cortana düzenli olarak ilgi duydugunuz alanlari takip edip size gerektigi zaman ilgili uyarilari yapabiliyor. Beni en çok etkileyen demo Cortana'nin telefondaki mailleri tarayarak mail içerisindeki uçus bilgilerini bulmasi ve uçusla ilgili detaylari takip etmesi oldu.

Cortana su anda Beta durumda ve Türkçe'yi desteklemiyor. Ne zaman desteklenmeye baslar konusunu ise allah bilir :)

Notification Center

Windows Phone 8.1 ile beraber tipki IPhone ve Android'de oldugu gibi bir notification center'in gelecegi konusuluyordu. Nitekim haberler dogru çikti ve notification center'in Windows Phone 8.1 ile beraber gelecegi açiklandi.

Özellestirilebilir Lock Screen

Itiraf etmem gerekirse Windows Phone 8.1 ile beraber gelen ve beni en çok etkileyen özellik bu :) Daha önceki Windows Phone versiyonlarinda uygulamalar kendi resimlerini lock screen'e background image olarak koyabiliyordu. Ancak Windows Phone 8.1 ile beraber lock screen üzerindeki yazilarin ve lock screen açilis animasyonlarinin da özellestirilmesinin önü açilmis. Gördügüm 2 demoda da daha çok güzel tasarimlar vardi. Ilerleyen zamanlarda çok daha yaratici tasarimlarin çikacagina eminim.

Start Screen'de Daha Fazla Tile

Daha önce 5 inch'den büyük ekranlarda kullanilabilecegi duyurulan orta büyüklükteki 3 tile'in sigabilecegi start screen görünümü Windows Phone 8.1 ile beraber artik tüm Windows Phone'larda kullanilabilir durumda olacak. Windows Phone'larda bu görünümü açmak için settinglerden ilgili ayari enable etmek yeterli olacak.

Degisen Calendar Uygulamasi

Windows Phone 8.1 ile beraber Calendar uygulamasi yeniden yazilmis. Yeni calendar görünümü ile beraber artik haftalik olarak planlariniza çok daha rahat bir sekilde bakabiliyorsunuz.

Storage Sense, Wifi Sense, Battery Sense Uygulamalar

Windows Phone 8.1 ile beraber 3 tane yeni uygulama geliyor. Bunlardan ilki Storage Sense. Bu uygulama ile telefonunuzun ve telefona takili olan SD Card'in hafiza durumunu görebiliyorsunuz. Bunun yaninda uygulamalarinizin SD kart üzerine kurulmasi gibi ayarlari da bu uygulama ile yapmaniz mümkün.

Wifi Sense uygulamasi ise sizi hizli bir sekilde public networklere baglayabiliyor. Normalde bir kafeye gittiginizde internete baglanmaya çalistigimizda bir web sayfasi açilir ve sözlesmeyi kabul ettigimiz belirten butona tiklamamiz istenir. Iste Wifi Sense uygulamasi bunlari dogrudan kendisi arka planda hallediyor.

Battery Saver uygulamasi ile ise telefonunuzun sarj durumunu görebiliyorsunuz. Bunun yaninda hangi uygulama daha fazla batarya kullaniyor gibi verilere de bu uygulamadan ulasabiliyorsunuz. Ayrica herkesin uzun süredir bekledigi kalan sarj yüzdesinin ekranda gözükmesi özelligide en sonunda Windows Phone 8.1 ile geliyor.

Word Flow Keyboard Shape Writing

Windows Phone 8.1 ile beraber klavyeden elimizi kaldirmadan hizli bir sekilde yazi yazmamizi saglayan shape writing özelligi geliyor. Bu yeni klavye ile  beraber Windows Phone, en hizli mesaj yazma konusunda birinciligi Samsung Galaxy S4'den devralmis.

Windows Phone 8.1 çok daha fazlasi...

Yukaridaki özellikler Windows Phone 8.1 ile beraber gelen en dikkat çekici özellikler.  Windows Phone 8.1 ile beraber gelen daha pek çok güzel yenilik var. Windows Phone son kullanicilara yaz aylarinda sunulmaya baslanacak. Daha fazla detay için resmi blogdaki yaziyi okuyabilirsiniz.

Windows 8.1 Update

Günün ikinci beklenen haberi ise Windows 8.1'e çikacak olan ve özellikle mouse ve keyboard kullanan kullanicilara yönelik olan update'di. Bu update ile beraber mouse ve keyboard kullanan Windows kullanicilarin sikinti çektigi konulara çesitli çözümler üretilmeye çalisilmis.

Windows 8 çiktiginda beri mouse ve keyboard kullanan kullanicilarin ekranin sag tarafindaki charmlarla arasinin iyi olmadigi bilinen bir gerçek :) Bu yüzden bu update ile beraber start screen'in sag üst kösesine power ve search butonlari ekleniyor. Böylece artik ekrann sag alt kismina gidip charmi açip bilgisayari kapatmak zorunda kalmayacagiz :)

Windows 8.1 Update'i ile beraber artik Windows Store uygulamalarini da taskbar'a pinliyebiliyoruz. Tipki eski tip desktop uygulamalarinda oldugu gibi.

Windows 8.1 Update ile artik start screen biraz daha keyboard ve mouse kullanicilarini sevebilecegi hale geliyor :) Artik herhangi bir tile'a sag tikladigimizda aliskin oldugumuz bir context menü görecegiz. Ayrica Ctrl'ye basili tutup birden fazla tile'i ayni anda seçebilmemizde mümkün.

Windows 8.1 Update su an MSDN üzerinden indirilebiliyor. 8 Nisan itibariyle tüm Windows 8 kullanicilari update'i Windows Update üzerinden ücretsiz olarak alabilecekler.

Windows 8.1 Update Sonrasi...

Build konferansinda konusulmasi beklenen konulardan biri de açikcasi Windows 9'du. En azindan Windows 9 ile ilgili olarak ufak tefek detaylar paylasilir diyorduk ancak bunun yerine Windows 8.1 Update'den sonra yeni bir update'in daha gelecegi duyuruldu. Bu update ile beraber eskiden alistigimiz start menü geri dönüyor.  Oturumda gösterilen tasarimin ise final sürümde degismesini umuyorum. Çünkü start menü içerisine tile koymak hiç olmamis :) Ayrica yine gelecegi bahsedilen update ile artik windows store uygulamalari desktop üzerinde bir pencere içerisinde çalisabilecek.

9 Inch Altindaki Cihazlara Windows Artik Ücretsiz

Ilk günün en çok dikkat çeken duyurularindan biri de Microsoft'un Windows'u ve Windows Phone 8.1'i 9 inch ve altindaki cihazlar için ücretsiz yapmasiydi. Microsoft bu sekilde bir stratejiyle pazardan daha fazla pay almayi hedefliyor.

Nokia Lumia 930, Nokia 630 ve Nokia 635

Windows Phone 8.1'in duyurulmasindan sonra sira telefonlar tarafina dolayisiyla da Nokia'ya geldi. Nokia'nin Windows Phone 8.1'li ilk telefonlari Lumia 930, 630 ve 635 olacak. Amerika disinda satisa sunulacak olan Lumia 930'un tasarimi hosuma gitti açikcasi. Özellikleri de oldukça iyi.

Nokia Lumia 635 ise Nokia'nin ilk dual sim özelligini destekleyen telefonu olacak.

Diger Gelismeler

Build'in birinci gününde yukaridaki konulardan ayri olarak üzerinde durulan diger konular touch tabanli office uygulamalari ve Kinect For Windows V2'di.

Developer Dünyasindan Haberler

Son kullanici dünyasindan haberler bu kadar. Simdi gelelim esas biz developerlari ilgilendiren haberlere.

Visual Studio 2013 Update 2 RC

Visual Studio 2013 Update 2 bugün itibariyle RC (Release Candidate) oldu. Ancak Beta versiyonunda olmayip RC sürümünde update içerisine eklenen pek çok sey var. Yazinin ilerleyen kisimlarinda eklenen kisimlara deginecegiz. Visual Studio 2013 Update 2'yi buradan indirebilirsiniz.

Windows Phone 8.1 SDK

Windows Phone 8.1 duyurulmasiyla Windows Phone 8.1 SDK RC sürümü developerlara sunuldu. Eger Visual Studio 2013 Update 2 RC'yi bilgisayariniza kurarsaniz Windows Phone 8.1 SDK'in de bilgisayariniza yüklendigini göreceksiniz.

Universal Windows  Apps

Developerlar açisinda birinci gün keynote'un en ilgi çekici konusu bence kesinlikle Universal Windows Apps. Her developerin rüyasidir tek bir kod yazip, yazdigi kodu farkli platformlarda çalistirmak. Su ana kadar portable class libraries ile bir nebze Windows ve Windows Phone uygulamalari için belirli bir miktar kodu paylastirabiliyorduk. Ancak aradaki uçurum çok fazlaydi.

Windows Phone 8.1'de telefonun altindaki runtime artik Windows Runtime. Yani su an Windows Store app yazarken kullandigimiz runtime ile ayni. Verilen rakamlara göre % 90 oraninda API'lar birbirleri ile ayni.

Universal Windows Apps konseptinde ise yapilmak istenen proje içerisinde shared bir alan içerisinde kodunuzu ve viewlerinizi tutarak windows ve windows phone applerinizin bu ortak kodlari kullanmasini saglamak. Viewlarda bulunan kontroller ise bulunduklari platforma uygun bir sekilde render ediliyor. Eger paylasilan alanda bulunan viewlari platform spesifik olarak degistirmek isterseniz de ilgili view'i platforma ait olan projeye sürükleyip orada özellestirmeniz mümkün.

Konunun bu sekilde çok havada kaldigini farkindayim :) Konferans dönüsü ne kisa zamanda bu konuyla ilgili detayli bir yazmayi düsünüyorum.

Typescript 1.0

Bugün itibariyle Typescript 1.0 versiyonu release oldu. Visual Studio Update 2 RC içerisinde Typescript'in 1.0 versiyonu bulunuyor. Detayli bilgiye buradan ulasabilirsiniz.

Cross Platform ve Open Source WinJS

Windows Store uygulama gelistirirken HTML & JS tarafindan ilerleyenlerin kullandigi javascript librarysi WinJS artik cross platform oldu ve webde çalisabilecek hale getirilerek open source olarak açildi. Detayli bilgiye buradan erisebilirsiniz.

.NET Native Preview

Build'in ilk günü keynote'da bahsedilmeden sessiz sedasiz duyurulan ve bana göre biraz da gölgede kalmis olan .NET Native,  C# ile yazilan Windows Store uygulamalarinin dogrudan makina dilinde derlenmesini sagliyor. Böylece kod yazarken ve debugging yaparken C#'in getirdigi kolayliklari kullanabilirken performans olarak da C++'in avantajlarina sahip olabiliyoruz. Bu konuyla ilgili de Build dönüsü bir yazi yazmayi düsünüyorum. Simdilik buradaki yazidan detaylari okuyabilirsiniz.

Satya Nadella Sahnede !

Ilk gün keynote'un sonunda ise sahnede Microsoft'un yeni CEO'su Satya Nadella vardi. Daha önceki konferanslardan farkli olarak bu sene keynote'un sonuna kadar hep developer kökenli ve esas ürünlerden sorumlu kisilerin sunumlarini izledik. Bunlarda developer kökenli Satya Nadella'nin katkisi oldugu yadsinamaz bir gerçek.

Yarin keynote'da Azure günü :) Bakalim ne gibi yenilikler gelecek.

Benden simdilik bu kadar. Artik dinlenme vakti :)



Windows Runtime Componentlerinde Asenkron İşlemler - C# 5.0

Bir önceki yazimizda Windows Runtime Componentlerini inceledikten sonra simdi sira geldi WinRT Component'leri gelistirme sirasinda karsimiza siklikla çikabilecek olan bir durumu incelemeye. :) Bildigimiz gibi Windows 8 ile beraber gelen WinRT altyapisi içerisinde bulunan pek çok yapi asenkron sekilde çalismak üzere tasarlandi. Hatta bu asenkron altyapiyi kullanmayi kolaylastirmak için de C# 5.0 ile beraber gelen asenkron programlama yeniliklerini kullanmaktayiz.

Hal böyle olunca Windows Runtime Componentleri içerisinde de asenkron olarak çalisacak yapilar gelistirmek artik neredeyse kaçinilmaz bir hal aldi. Bu yazimizin konusu da Windows Runtime Componentleri içerisinde asenkron sekilde çalisacak yapilari nasil gelistirecegimiz ile ilgili.

.NET Framework içerisinde asenkron islem diyince artik bir çirpida aklimiza gelen tip Task tipi olmakta. Önceki yazilarimizdan da hatirlayacagimiz üzere asenkron islemlerin yönetimini Task tipi üzerinden kolaylikla yapabiliyoruz. Peki Windows Runtime Component'i gelistirme tarafina geçtigimizde Task tipi hala daha orada mi yoksa karsimiza baska seyler mi çikiyor hemen durumu bir örnek yaparak inceleyelim.

Örnek olarak basit bir sekilde bir RSS adresinden ilgili contenti asenkron olarak download eden bir metot yazacagiz.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;

namespace AsyncWinRTComponent
{
    public sealed class AsyncHelper
    {
        public async static Task<string> DownloadRSSAsync()
        {
            HttpClient client = new HttpClient();

            var result = await client.GetAsync("http://www.ilkayilknur.com/feed");

            return await result.Content.ReadAsStringAsync();
        }
    }
}
Koda baktigimizda artik alistigimiz asenkron implementasyonlardan hiç bir farki yokmus gibi görünüyor :) Öyleyse kodu derleyelim bakalim herhangi bir sorunla karsilasacak miyiz :)

Error 1 Method 'AsyncWinRTComponent.AsyncHelper.DownloadRSSAsync()' has a parameter of type 'System.Threading.Tasks.Task<System.String>' in its signature. Although this generic type is not a valid Windows Runtime type, the type or its generic parameters implement interfaces that are valid Windows Runtime types. Consider changing the type 'Task' in the method signature to one of the following types instead: Windows.Foundation.IAsyncAction, Windows.Foundation.IAsyncOperation, or one of the other Windows Runtime async interfaces. The standard .NET awaiter pattern also applies when consuming Windows Runtime async interfaces. Please see System.Runtime.InteropServices.WindowsRuntime.AsyncInfo for more information about converting managed task objects to Windows Runtime async interfaces. C:\Users\ilkayilknur\AppData\Local\Temporary Projects\AsyncWinRTComponent\Class1.cs 39 42 AsyncWinRTComponent

Upps :) Bu hatanin artik ne demek oldugunu biliyoruz bir önceki yazimizdan. Bu demek oluyor ki Task tipi WinRT tarafinda bulunan bir tip degil. Sadece .NET Framework tarafinda bulunuyor ve asenkron olarak gelistirdigimiz  public metotlardan Task tipini dönemiyoruz. Peki ne yapacagiz ?

IAsyncAction ve IAsyncOperation<T> Interfaceleri

Windows Runtime tarafinda asenkron islemler dedigimizde de karsimiza Task tipi yerine IAsyncAction ve IAsyncOperation<T> interfaceleri çikiyor. IAsyncAction interface'i herhangi bir deger döndürmeyen asenkron islemlerin yönetiminde kullanilirken IAsyncOperation<T> interface'i de asenkron islem sonucu bir deger dönülen metotlarda kullanilmakta. Ayni zamanda IAsyncAction interface'i içerisinde yaptiginiz asenkron çagri ile ilgili olarak progress bilgisini de almamiz mümkün degil.

Simdi yapmis oldugumuz örnegimize dönersek asenkron metodumuz içerisinde islem sonlandiktan sonra bir deger döndürdügümüz için IAsyncOperation<T> interface'ini kullanmamiz gerekmekte. Peki kullanimi nasil gerçeklestirecegiz ? Burada en önemli konu bu. Çünkü metodumuzu async modifier'i ile tanimladik. Ancak metottan Task tipi dönemiyoruz ve Windows Runtime Component'i içerisinden de metodu disari açmamiz için de Task tipi yerine IAsyncOperation<T> dönmemiz gerekmekte. Yani isler oldukça karisik. :D

Simdi ilk olarak parça parça ilerleyelim ve yazmis oldugumuz metodu public yerine private olarak tanimlayalim ve metodu Windows Runtime Component'i içerisinde çalisacak olan bir iç metot olarak düsünelim.

private async static Task<string> DownloadRSSAsyncInternal()
{
    HttpClient client = new HttpClient();

    var result = await client.GetAsync("http://www.ilkayilknur.com/feed");

    return await result.Content.ReadAsStringAsync();
}

Evet simdi Windows Runtime Component'imiz basarili bir sekilde derlenebiliyor çünkü Task tipini döndügümüz metodumuzu private olarak tanimladik. (Metot isminin sonuna Internal kelimesini de yerlestirdik ki disari açtigimiz metotta yine DownloadRSSAsync ismini kullanabilelim ;) )

Simdi DownloadAsyncRSS isimli metodumuzu IAsyncOperation<T> dönecek sekilde tanimlayalim ve esas önemli kisma gelelim.

Bu yazdigimiz metot içerisinde de aslinda elimizdeki bulunan DownloadRSSAsyncInternal isimli metottan dönen Task tipini IAsyncOperation<T> interface'ine çevirebilirsek isimizi bitirebiliriz gibi görünüyor ne dersiniz ? Acaba elimizde bulunan bir Task tipini IAsyncOperation<T>'a çevirebilecek bir yapi var midir bakalim.

Iste aradigimiz tam da böyle birsey :) Windows Runtime içerisindeki yapilara baktigimizda içerisinde .NET Framework tipleri ve WinRT tipleri arasinda hizli geçisler yapabilecegimiz pek çok extension metot mevcut. Bu çerçevede elimizde bulunan Task tipinden de IAsyncOperation<T> üretmek için de AsAsyncOperation isimli bir metot WinRT içerisinde bulunmakta. Ayni sekilde elimizde bulunan Task tipinden IAsyncAction üretmemiz de mümkün. Öyleyse yazacagimiz Windows Runtime Component'in son hali su sekilde olacak.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;

namespace AsyncWinRTComponent
{
    public sealed class AsyncHelper
    {
        private async static Task<string> DownloadRSSAsyncInternal()
        {
            HttpClient client = new HttpClient();

            var result = await client.GetAsync("http://www.ilkayilknur.com/feed");

            return await result.Content.ReadAsStringAsync();
        }

        public static IAsyncOperation<string> DownloadRSSAsync()
        {
            return DownloadRSSAsyncInternal().AsAsyncOperation();
        }
    }
}

Gördügünüz gibi Windows Runtime Componentleri içerisinde asenkron metotlar yazip disari açmak da oldukça kolay. Özellikle .NET Framework ile WinRT tipleri arasindaki geçisleri yapmak gördügünüz gibi extension metotlarla oldukça kolaylasmis durumda. Bu extension metotlar sadece asenkron programlamada kullandigimiz tipler için degil ayni zamanda Streamler gibi yapilarda da islerimizi oldukça kolaylastirmakta. Tavsiyem eger WinRT tarafinda bir tipte sikisip kaldiysaniz ve bir islemi nasil yapacaginiza tam olarak emin degilseniz ve bu isi .NET Frameworkle hemen çözebileceginizi düsünüyorsaniz elinizdeki Windows Runtime tipini .NET Framework tipine çeviren bir extension metot olup olmadigini mutlaka arastirin ;)

Umarim faydali olmustur.

Hepinize kolay gelsin,

Not: Blogumu RSS veya sosyal sitelerden takip etmekte sikinti çekenler için blogumu mail ile de takip edebilirsiniz. Buradaki linke tiklayarak kaydinizi yapabilirsiniz. 



C# 5.0 Windows Runtime Desteği ve Windows Runtime Componentleri Geliştirme

Windows 8 ile beraber gelen WinRT altyapisi üzerinde bulunan en güzel özelliklerden biri de hiç süphesiz ki üzerinde pek çok programlama diliyle uygulama gelistirilebilmesi. Örnegin C, C++, C# veya VB bilen bir developer arayüz tarafinda da XAML kullanarak uygulamasini gelistirebilirken ayni zamanda Javascript ve HTML bilen bir front-end developer da artik Windows 8 üzerinde uygulama gelistirebilmekte. Peki ayni uygulama içerisinde bu dillerden ikisini birden kullanabiliyor muyuz ? sorusu eminim bir çogumuzun aklina geliyordur. :) Örnek olarak, bir Windows 8 uygulamasi gelistirirken data katmani bir C# developer tarafindan gerçeklestirilse ve arayüz kismi da javascript ve HTML ile yapilsa ortaya efsanevi senaryolar çikabilir :)  Peki bunu yapmak mümkün mü ? Evet mümkün :) Simdi gelin bunu nasil gerçeklestirebilecegimizi inceleyelim :)

WinRT (Windows Runtime) Components

Normalde uygulamalarimizi gelistirirken gerek baska uygulamalarin kullanmasi amaciyla gerekse kendi uygulamamiz içerisinde bir takim kavramlari dogrudan uygulama içerisine gömmek yerine yazdigimiz kodlari yeniden kullanabilmek amaciyla class libraryleri kullanmaktayiz. Windows Store uygulamalari tarafina baktigimizda ise bahsettigimiz senaryolarda kullanmak üzere adresimiz yine class library olmakta. Ancak Windows Store tarafinda yazmis oldugunuz class library'i hangi programlama dili ile yazdiysaniz bu class library'i kullanan Windows Store uygulamasi da class library'i yazdiginiz programlama dilinde olmali. Yani C# ile yazdigimiz bir class libraryi HTML & Javascript kullanarak yazilmis bir Windows Store uygulamasinda kullanamiyoruz.

Iste tam bu noktada karsimiza Windows Runtime Componentleri çikiyor. Windows Runtime Componentleri temelde class libraryler gibi yazmis oldugumuz kodun farkli uygulamalar tarafindan kullanilmasini saglarken bu gelistirmis oldugumuz komponentler ayni zamanda kendi yazildiklari programlama dili disinda yazilan uygulamalar tarafindan da kullanilabilmekte.

Windows Runtime Component ismi ilk olarak Visual Studio 2012 içerisinde uygulama yaratma penceresini açtigimizda Windows Store Apps bölümüne baktigimizda karsimiza çikmakta.

Projeyi seçip yarattigimizda karsimiza çikan sinif içerisinde dikkatimizi çeken ilk nokta yaratilan sinifin sealed olmasi !

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinRTComponent
{
    public sealed class Class1
    {
    }
}

Öncelikli olarak Windows Runtime Component'i gelistirme konusunda söylemem gereken ilk sey yazdigimiz komponentin pek çok farkli programlama dili ile yazilmis olan uygulamalarda kullanilmasi nedeniyle gelistirme kisminda ne yazik ki bir takim sinirlamalarla karsilasmaktayiz. Çünkü her programalama dilinin kendine has bazi özellikleri ve kullanim detaylari bulunmakta bu nedenle de ortak bir paydada bulusabilmek ve yazilan komponentin tüm dilleri tarafindan düzgün olarak kullanilabilmesi için bu konulan kurallara uymak zorundayiz :)

Evet sinirlamalarin nedenini de açikladiktan sonra gelelim Visual Studio 2012'nin yaratmis oldugu default sinifta karsimiza çikan sealed keywordüne :) WinRT Componeneti gelistirmesi sirasinda karsilasacagimiz ilk kural Windows Runtime Component'i içerisinden disari açacagimiz siniflarin mutlaka sealed olmasi kurali :)  Ancak burada dikkat etmemiz gereken nokta bu kuralin sadece Windows Runtime Component'i içerisinden disari açacagimiz siniflarda geçerli olmasi. Yani eger sinifinizi public olarak tanimlamazsaniz ve sadece komponent içerisindeki iç islemlerde kullanirsaniz bu noktada siniflarinizda istediginiz sekilde inheritance kullanabilirsiniz. ;)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinRTComponent
{
    //Windows Runtime bu duruma kizmaz :)
    class SealedOlmayanClass : List<string>
    {
    }
}

Simdi gelelim Windows Runtime Componenti içerisinde bulunan tiplerimizin içerisindeki metotlara. Çok basit olarak yazdigimiz Windows Runtime Component'in bir DataAccess componenti oldugunu düsünelim ve su sekilde bir metot yazalim.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinRTComponent
{
    public sealed class DataAccess
    {
        public static List<Speaker> GetSpeakerList()
        {
            return new List<Speaker>             {                 new Speaker{NameSurname="Daron Yöndem",Subject="Azure"},                 new Speaker{NameSurname="Umut Erkal",Subject="Kinect"},                 new Speaker{NameSurname="Yusuf Öztürk",Subject="Powershell"},             };
        }

        public sealed class Speaker
        {
            public string NameSurname { getset; }
            public string Subject { getset; }
        }
    }
}
Gördügünüz gibi oldukça basit bir sekilde DataAccess isimli bir tip içerisine GetSpeakers isminde bir static metot ekledik ve bu metot içerisinde de hizli bir sekilde bir List içerisine dummy olarak datalari doldurup bu listi metottan döndürdük. Simdi bu yazdigimiz kodu derleyelim ve ne ile karsilasacagiz bakalim  :)

"Error 1 Method 'WinRTComponent.DataAccess.GetSpeakerList()' has a parameter of type 'System.Collections.Generic.List<WinRTComponent.Speaker>' in its signature. Although this generic type is not a valid Windows Runtime type, the type or its generic parameters implement interfaces that are valid Windows Runtime types. Consider changing the type 'System.Collections.Generic.List<T>' in the method signature to one of the following types instead: 'System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.Generic.IEnumerable<T>'. C:\Users\ilkayilknur\AppData\Local\Temporary Projects\WinRTComponent\DataAccess.cs 11 37 WinRTComponent "

Yukarida yazanlar aslinda bize Windows Runtime Componenti içerisinde uygulamamiz gereken bir kurali basitçe hatirlatiyor. Nedir bu kural derseniz Windows Runtime Componenti içerisinde bulunan tipler içerisindeki public olarak tanimlanmis olan metotlarin imzalarinda mutlaka Windows Runtime tipi kullanilmalidir. Yani public olarak disari açtigimiz metotlarimizin parametrelerinin tipleri ile metodun dönecegi tip mutlaka Windows Runtime içerisinde bulunan bir tip olmalidir.

Bizim örnegimizde kullanmis oldugumuz tip aslinda baktigimizda bir .NET Framework tipidir. Ancak Windows Runtime interface tabanli bir altyapi oldugu için List tipinin Windows Runtime tarafindaki karsiligi IList interface'idir. Öyleyse yazdigimiz kodu su sekilde degistirirsek artik metodumuzu gelistirdigimiz komponent içerisinden disari açabiliriz.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WinRTComponent
{
    public sealed class DataAccess
    {
        public static IList<Speaker> GetSpeakerList()
        {
            return new List<Speaker>()
            {
                new Speaker{NameSurname="Daron Yöndem",Subject="Azure"},
                new Speaker{NameSurname="Umut Erkal",Subject="Kinect"},
                new Speaker{NameSurname="Yusuf Öztürk",Subject="Powershell"},
            };
        }
        //Windows Runtime buna da kizmaz :)
        private static List<Speaker> GetSpeakerListPrivate()
        {
            return new List<Speaker>()
            {
                new Speaker{NameSurname="Daron Yöndem",Subject="Azure"},
                new Speaker{NameSurname="Umut Erkal",Subject="Kinect"},
                new Speaker{NameSurname="Yusuf Öztürk",Subject="Powershell"},
            };
        }
    }
    public sealed class Speaker
    {
        public string NameSurname { getset; }
        public string Subject { getset; }
    }
}

Simdi kodumuz düzgün bir sekilde derlendi :) Simdi gelin yazmis oldugumuz komponenti HTML ve JS kullanarak yazacagimiz uygulamamiz da kullanalim.

Öncelikle projemizi yaratalim.

Projemizi yarattiktan sonra hizli bir sekilde ayni dll referansi eklyormusuz gibi Add Reference diyerek yazmis oldugumuz komponenti projemize referans olarak ekleyelim.

Ilk olarak default.html içerisine basit olarak bir table yerlestirelim ve bu tablo içerisinde Windows Runtime Component'i içerisinden gelecek datalari görüntüleyebilecek sekilde düzenlemeler yapalim.

<!DOCTYPE html>
<html>
<head>
    <meta charset=&quot;utf-8&quot; />
    <title>ComponentConsumer</title>

    <!-- WinJS references -->
    <link href=&quot;//Microsoft.WinJS.1.0/css/ui-dark.css&quot; rel=&quot;stylesheet&quot; />
    <script src=&quot;//Microsoft.WinJS.1.0/js/base.js&quot;></script>
    <script src=&quot;//Microsoft.WinJS.1.0/js/ui.js&quot;></script>

    <!-- ComponentConsumer references -->
    <link href=&quot;/css/default.css&quot; rel=&quot;stylesheet&quot; />
    <script src=&quot;/js/default.js&quot;></script>
</head>
<body>
    <table>
        <thead>
            <tr>
                <td>Isim</td>
                <td>Konu</td>
            </tr>
        </thead>
        <tbody id=&quot;table-body&quot;>
        </tbody>

    </table>
</body>
</html>

Simdi ise geldik Windows Runtime Componentimizi kullanacagimiz Javascript tarafina. Javascript tarafinda hemen default.js tarafina geçelim ve kodumuzu yazmaya baslayalim. Komponentin namespace'i olan WinRTComponent namespace'i  javascript tarafindan dogrudan erisilebilir durumda. Öyleyse hemen hizlica Windows Runtime Component'imizi kullanan ve ilgili tabloyu dolduran javascript kodumuzu yazalim.

(function () {
    "use strict";

    WinJS.Binding.optimizeBindingReferences = true;

    var app = WinJS.Application;
    var activation = Windows.ApplicationModel.Activation;

    app.onactivated = function (args) {
        if (args.detail.kind === activation.ActivationKind.launch) {
            if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
                var speakers = WinRTComponent.DataAccess.getSpeakerList();

                for (var i = 0; i < speakers.length; i++) {
                    var speaker = speakers[i];

                    var body = document.getElementById("table-body");

                    body.innerHTML += "<tr><td>"+ speaker.nameSurname + "</td><td>"+ speaker.subject + "</td></tr>";
                }
            } else {

            }
            args.setPromise(WinJS.UI.processAll());
        }
    };

    app.oncheckpoint = function (args) {
    };

    app.start();
})();

"Öncelikle yazmis oldugum javascript ve html'i okuyan front-end developerlara bu konuda oldukça tecrübesiz ve kötü oldugumu bildirmemde fayda var. :) (Sonra böyle kod mu olur seklinde serzenislerde bulunmayin :) )"

Neyse konumuza dönersek yukarida hizli bir sekilde kodumuzu yazdik ancak bu noktada sizlerin dikkatini çekmek istedigim önemli bir nokta var.

Farkettiyseniz yukarida yazmis oldugumuz C# kodlarinda metodumuzun adi GetSpeakerList'ti. Ayni sekilde propertylerimizin ismi de NameSurname ve Subject'ti. Ancak javascript tarafina geçtigimizde gördügünüz gibi metotlarimizin ve propertylerimizin ismi javascript tarafinda kullanilan casing'e göre yeniden düzenlendi ve böylece HTML ve JS tarafinda bulunan developerlarin bu isimlendirmelerde hiç bir sekilde sikinti çekmemesi saglandi. Microsoft'un development deneyimi konusunda yapmis oldugu en güzel hareketlerden biri olarak bu noktayi belirtmeden geçemedim ;)

Evet uygulamamizi gelistirdik simdi bir de uygulamamizi çalistiralim ve çalistigini görelim :)

Gördügünüz gibi HTML ve Javascript ile yazdigimiz uygulamamiz içerisinde C# ile yazmis oldugumuz Windows Runtime Componentini kullanabilmekteyiz. Windows Runtime Componentlerini aslinda pek çok farkli noktalarda devreye sokup uygulamalarimizi gelistirebilmekteyiz. Örnegin bu senaryomuzda oldugu gibi DataAccess tarafinda Windows Runtime Componentleri kullanabilecegimiz gibi hesaplama kisimlarinda, parse  vb..  gibi pek çok farkli noktada yine Windows Runtime Componentleri kullanabilmeteyiz. Hatta Windows Runtime Component'i kullanarak bir Windows Store projesini tüm yükü tek developera vermemek adina back-end kismini C# developera yaptirabilir arayüz tarafini da backend'den gelen metotlari çagirarak bir HTML & Javascript uygulamasi olarak gelistirebilirsiniz. Burada önemli olan Windows Runtime Componentlerini dogru zamanda devreye sokabilmek.

Bir kaç Windows Runtime Component Gelistirme Kurali Daha...

Yazimizin sonlarina gelirken yukarida bahsetmis oldugum Windows Runtime Component'i gelistirirken dikkat etmemiz gereken kurallara 2-3 ufak kurali daha ekleyerek yazimiza son verelim :)

  • Windows Runtime Component'i içerisinde disariya açilan structlarin sadece public alanlari olmalidir. Içerisinde private alanlar barindiramazlar. Ayrica disariya açilan structlar içerisinde propertyler de bulunamaz.
  • Windows Runtime Componentleri içerisinde sadece sistem içerisinde tanimli olan generic tipler kullanilabilir.
  • Windows Runtime Component'i içerisinde disariya sunulan tipler sealed olmalidir. Tek istisna XAML kontrolleridir. XAML kontrollerinde inheritance kullanilabilir.

Evet kurallarimiz bu kadar.

Umarim faydali bir yazi olmustur.

Hepinize kolay gelsin !