Arda Çetinkaya Yazılım ve arada kendim ile ilgili karaladıklarım…

.NET Core emekleme aşamasını geçtiğimiz aylarda 1.0 RTM versiyonu ile tamamladı. Yürüyor ama sağa sola çarpıyor, şu sıralar biraz daha düzgün yürümeyi öğreniyor diyebiliriz. Açık kaynak olması ve farklı platformlarda, aynı şekilde çalışan bir framework amaçlanması, mevcut .NET Framework kadar olgun bir hale gelmesi için biraz daha bekleyeceğiz demek. Bu gelişme ve olgunlaşma süresince de .NET Core ile ilgili bir çok yeni kavram da geliştirme kütüphanemize girdi, girmeye de devam ediyor.

Şu sıralar .NET Core ile ve ASP.NET Core ile sıkça uğraşmaktayım. Dolayısıyla bir çok yeni şeyi öğreniyor, sindiriyor ve fark ediyorum. Projelerinizi .NET Core alt yapısına çevirmeye başladıysanız büyük bir ihtimal benzer şeyleri yaşıyoruz. Yeni şeyleri fark ederken yaşadığım bir “publish” problemdeninden dolayı .NET Core ile ilgili bir şeylerden bahsetmek istiyorum. Bildiğiniz gibi .NET Core’un, platform bağımsız ve taşınabilir olması amaçlanıyor. Platform bağımsız derken, hem geliştirme hem çalışma ortamlarının Windows, OS X ya da Unix sistemlerde olması, taşınabilir derken de, Windows’da çalışan uygulamanın, aynı dosyalar ile Unix’e taşınıp, orada da sorunsuz çalışabilmesini kastediyorum.

Bu noktada .NET Core uygulamalarının “taşınabilirlik” özelliğinden biraz bahsetmeye çalışacağım. Geliştirdiğiniz uygulamaların bir çok farklı platformda çalışabilmesi için yapacağınız publish ayarlarını ve konfigürasyonları anlamak için, .NET Core da “taşınabilirlik” ne demek biliyor olmamız lazım.

.NET Core’da bu çerçevede iki farklı uygulama tipi var. “Portable”(Taşınabilir) ve “Self-Contained”(Bağımsız) uygulamalar…

“Portable” uygulamalar

“Portable” uygulamalar, çalışacağı makine de .NET Core’un yüklü olmasını gereksinimine sahip uygulamalardır. Geliştirdiğiniz uygulama eğer bu tip bir uygulama ise, .NET Core yüklü herhangi bir sistemde çalışacaktır. Uygulamanızın çalışması için oluşturulan “publish” paketi içerisinde sadece sizin yazdığınız bileşenler ve varsa kullandığınız diğer yardımcı bileşenler, uygulamanızın çalışması için yeterli olacaktır. Bu uygulama tipi, .NET Core uygulamalarının varsayılan tipi. Bu tip uygulamalar geliştirmek için projecj.json dosyanızın içeriği temel olarak aşağıdaki gibi ve dependencies‘deki .NET Core’un “type:platform” özelliğini yeterli olacaktır.

{
    "buildOptions": {
        "emitEntryPoint": true
    },
    "dependencies": {
        "Microsoft.NETCore.App": {
            "version": "1.0.0",
            "type": "platform"
        }
    },
    "frameworks": {
        "netcoreapp1.0": {}
    }
}

Eğer projenizde destekleyici farklı bir bileşen kullanıyorsanız bunlarıda “dependencies” altına eklemeniz gerekecektir tabi ki. Bu uygulamanızı “publish” ettiğinizde; dotnet publish, publish klasöründe sadece ilgili *.dll’leri görürsünüz. Bu *.dll’leri .NET Core yüklü herhangi bir sisteme taşıdığınız takdirde uygulamanız sorunsuz çalışacaktır.

Screen Shot 2016-08-21 at 7.30.23 PM

“Self-Contained” uygulamalar

Bu tip uygulamalar, adından da anlaşılabileceği gibi, bağımsız olup, çalışacağı sistemde .NET Core’un yüklü olmasını gerektirmez. Çünkü “publish” olduğunda tüm gerekli dosyaları içerisinde barındıracaktır. Bu “publish” içeriğinin daha büyük olmasına neden olacaktır tabi ki, ama Docker gibi container platformlarında uygulamanızı host etmek isterseniz tercih edilebilecek bir yaklaşım olabilir.

Bu tip uygulamaların project.json konfigürasyonu biraz daha farklı olacaktır. “Portable” tipdeki uygulamalardan farklı olarak “type:platform” özelliği dosyanın içerisinde olmamalı.

{
    "buildOptions": {
        "emitEntryPoint": true
    },
    "dependencies": {
        "Microsoft.NETCore.App": {
            "version": "1.0.0"
        }
    },
    "frameworks": {
        "netcoreapp1.0": {}
    },
    "runtimes": {
        "win10-x64": {},
        "osx.10.11-x64": {}
    }
}

publish self-containedEk olarak “runtimes” özelliğinde uygulamanın çalışacağın platformlar belirtilmelidir. Bu tanımlamaya göre projemizi publish ettiğimizde ilgili platform için uygulamamızın çalışması için gerekli tüm bileşenler publish klasöründe olacaktır. Böylece çalışacağı sistemde .NET Core yüklü olmak gerekliliği ortadan kalkmış oluyor.

Farklı amaçlar için tercih edebileceğimiz bu uygulama tipleri, .NET Core uygulamalarının çalışması için önemli bir konu. Şimdilik bu kadar, bir sonraki yazıda görüşürüz.

!!!Önemli!!! .NET Core’un ilerleyen versiyonlarında project.json değişeceği için bu yazıdaki örnekler ilerleyen versiyonlarda farklılaşabilir.

“Code Review” yani kod gözden geçirme bir çoğumuzun bildiği, çoğumuzun(?) da uyguladığı bir yazılım geliştirme adımı diye düşünüyorum. Yazdığımız kodun, başkası tarafından gözden geçirilmesi olarak basitçe tanımlayabileceğimiz bir adım. Araştırmalar, hata tespit etme ve kod kalitesini arttırmada birim test, fonksiyonel test gibi test adımlarından daha etkili olduğunu söylüyor. “Daha etkili” kısmını doğrulamak için, nasıl daha etkinli kod gözden geçirme yapılır bunun üstüne de biraz kafa yormak gerekiyor sanırım.

Gözden geçirilecek kod 400-500 satırı geçmesin.

code-reviewGözden geçirilecek küme, ne kadar az olursa “code review” o kadar etkili olur. Gözden geçirmeye başlamadan öncede, gözden geçirilecek kod kümesini belirlenmeli ve net olmalı. 400-500 satırdan fazla kodu gözden geçirme hem yorucu olacaktır, hem de hata ve iyileştirmelerin tespitini zorlaştıracaktır. Samanlıkta iğne aramak gibi aslında…Ne kadar az saman, o kadar kolay iğne bulmak.

 

Gözden geçirme 1 saati geçmemeli

Gözden geçirme oturumu maksimum 1 saatlik farklı bloklar şeklinde olmalı. Uzadığı takdirde gözden geçirilen kod üzerindeki konsantrasyon kaybolur dolayısıyla bulguları bulmak zorlaşır. Zaman sınırı olan senaryolarda birden fazla kişi farklı kod kümeleri üzerinde gözden geçirmeyi yapabilir.

Kodu yazan kişi değil, kod gözden geçirilmeli

Kod gözden geçirecek kişi egosunu bir kenara bırakmalı. Ayrıca kodu yazanı değil, kodu gözden geçirmeli. Bu vesile ile tekrardan “Egosuz programlama için 10 emir…” yazısını hatırlamakta fayda var. Eğer kodu gözden geçiren kişi, kodu yazan kişiye göre çok daha tecrübeli bir kişiyse bunun farkında olup, “Bu kod bloğu saçma sapan olmuş”, “Bu ne biçim kod” yerine “Burada ne yapmak istedin”, “Bu kısım şöyle daha iyi olabilir” şeklinde yapıcı bir gözle kodu gözden geçirmeli.

code-review1

“Code Review” ve “Pair Programming” ayrımı yapılmalı

Kod gözden geçirme sırasında, kodu gözden geçiren kişi, tek başına bu görevi yapmalı. Kodu yazan kişinin o an müdahalesi olayı, “Pair Programming” etkinliğine dönüşecektir. Bulunan bulgular anında düzeltilmeye çalışılacak, hatta egosal durumlardan dolayı stresli bir olaya dönecektir. Kodu gözden geçirilecek kişiden öncesinde bir hazırlık yapması, gerektiğini düşündüğü yerlere açıklamalar yazabilmesinin sağlanması kodu gözden geçirecek kişiye yardımcı olacaktır.

Kontrol listesi olsun

Gözden geçirme sırasında takip edilebilecek bir liste olması, kod gözden geçirmenin etkisini arttıracaktır. Kod standartlarına uygunluk, null kontrolleri, güvenlik kontrolleri, varsa; kullanılan framework/API standartlarına uygunluk gibi bir kontrol listesinin olması işleri kolaylaştıracaktır. Bu kontrol listesine çeşitli puanlama sistemleri ile ölçülebilme özelliği eklemek, gelişimi gözlemlemek için faydalı olacaktır. Ayrıca bu kontrol listesine takılan bulguların düzeltilip düzeltilmediği de takip edilmeli.

Kod gözden geçirme düzenli olmalı

Kod gözden geçirme adımı düzenli olarak ve sürekli olarak yapılmalı. Aksi takdirde hiçbir önemi olmayacaktır. Biz de zaman zaman atlamak durumunda kalıyoruz, bu da bizim ayıbımız olsun. Ama atlandığı zaman, ortaya çıkan “bug”ların çözülmesi için harcanan efor, kod gözden geçirme için yapılacak efordan daha fazla olacaktır. Bu yüzden düzenli olarak yapmak şart.

Mümkünse bir uygulama kullanın

Kullandığınız IDE ya da SCM için mutlaka bir kod gözden geçirme eklentisi vardır, eklenti yoksa bile ayrı uygulamalar kullanabilirsiniz. Kod gözden geçirmenin sistematik hale gelmesini, hem de kolay yapılması için yardımcı olacaktır.

Kod gözden geçirme, hem kodu gözden geçiren, hem de kodu gözden geçirilen için oldukça öğretici bir adım; bunu da hiçbir zaman unutmamak lazım. Genel geliştirme sürecini iyileştirmek ve yazılımın kalitesini arttırmak için yapıldığını, kimseyi yargılamak için yapılmadığının da bilincinde olmak gerekli. Mutlu kodlamalar…

Bugün .NET Framework’ün kuzeni olarak nitelendirebileceğim, farklı platformlarda .NET uygulamaları çalıştırmamızı ve geliştirmemizi sağlayan .NET Core 1.0 versiyonu ile RTM oldu. 2 yılı aşkın süredir açık kaynak olarak geliştirilen .NET Core, farklı platformlarda da .NET uygulamaları geliştirmek isteyenler için Microsoft’un resmi olarak desteklediği bir alt yapı olarak önümüzdeki yıllarda daha da çok gündeme gelecek gibi.

.NET Core ile berebar doğal olarak ASP.NET Core 1.0‘da RTM olmuş oldu. MVC 6, Web API gibi web uygulaması alt yapılarını tek bir çatı altında toplayan ASP.NET Core 1.0 yine platform bağımsız bir alt yapı. .NET Core ile beraber bugün Entity Framework Core 1.0’da yayınlandı. İlerleyen zamanlarda yeni Core ailesi ile ilgili bir çok gelişme daha hızlı bir şekilde gündemimize gelecek gibi. .NET Core alt yapısına port edilen bileşenler de daha hızlı bir şekilde hayatımıza girmeye başlayacak. Bütün bu gelişmeler ile ilgili güncel linkleri sizin için derlemeye çalıştım. Buyrun efenim…

ASP.NET tarafında uzun zamandır büyük bir değişiklik var, Web Forms’un yanına MVC kalıbının gelmesi, .NET Framework’ün yeni versiyonları çıktıkça MVC’nin daha popülerleşmesi, OWIN, WebAPI, SignalR falan derken, ASP.NET kavramı ilk çıktığı zamankinden çok farklı bir hal aldı. .NET Framework’ün açık kaynak olabilmesi için, ondan ortaya çıkan .NET Core ile ASP.NET 5 duyurulmuştu. Bulut için uygun, performans açısından daha gelişmiş ama aynı zamanda alt yapıdaki karmaşıklığın basitleştirildiği, WebAPI, MVC gibi kavramların tekilleştiği ve içerisinde daha bir çok geliştirmeyi barındıran bir alt yapı olarak kısa zamanda çok sık konuşulmaya başlandı. Bu arada .NET Core != .NET Framework yazımı hatırlatmak isterim. Yeni nesil .NET Core alt yapısının ne olduğu öğrenmek ya da hatırlamak isteyenler göz atabilir.

mass_confusionKısa zamanda, acaba geleneksel ASP.NET ölüyor mu, .NET Framework ne olacak gibi karmaşıklıklarda gündemde oldu. Komple yeni bir alt yapının, mevcut versiyon ağacından ASP.NET 5 diye ortaya çıkması bunun en büyük sebebi. Aynı şey Entity Framework 7 ile de olmuştu. EF 6’dan sonra, tüm alt yapıyı değiştirdik, *.edmx alt yapısını kaldırdık diye EF 7’yi duyurunca da kısa bir şaşkınlık olmuştu. Kısaca Microsoft bunu hep yapıyor… Ama hangimiz yapmıyor ki…

Hem bu kafa karmaşıklıklarını yok etmek, hem de gerçekten yeni bir alt yapı olduğu için Microsoft’daki meslektaşlarımız ASP.NET 5’in artık ASP.NET Core 1.0 olduğunu geçen ay duyurdu. Bununla ilgili Scott Hanselman‘nın duyurusundaki ilk giriş cümlesi de aslında olayı özetliyor. “Naming is hard”

Neyse…Bu isim değişikliğinden sonra yeni isimler aşağıdaki gibi oldu;

  • ASP.NET 5 –> ASP.NET Core 1.0.
  • .NET Core –> .NET Core 1.0.
  • Entity Framework 7 –> Entity Framework Core 1.0

Şu an mevcut Github içeriklerinde ya da tüm resmi sayfalarda da bu değişiklikler yayınlanmaya başladı. Bu isimlendirme değişikliğinden dolayı RTM tarihlerinde biraz değişiklik oldu dolayısıyla. Son tarihleri bilemiyoruz ama buradan roadmap’i takip edebilirsiniz.

aspnet-core

Bu isimlendirme değişikliklerinden önce, aslında paralel demek kafa karışıklığını biraz azaltır; dnx tarafında da bir değişiklik oldu. Yine DNX, DNVM,DNU neydi hatırlamak isteyenlere bu konuyla alakalı önceki yazımı tavsiye ederim. Yeni nesil .NET Core uygulamaları ve ASP.NET 5’i geliştirmek ve çalıştırmak için gerekli olan runtime ve bileşenleri(dnx,dnvm…) .NET Core Command-line şeklinde değişti ve tek dotnet komutu ile yeni nesil .NET Core uygulamaları çalıştırılabilir oldu. .NET Core Command-line(Core CLI) araçları olarak yeniden düzenlenen komutlar ASP.NET Core 1.0 RC2 ile dnx tarafının yerini alacak. Şimdilik öncesinde GitHub sitesinden de indirip kurabilirsiniz. Ya da http://dotnet.github.io/getting-started/ adresinden de ayrıntılı olarak başka bilgilere hatta docker imajına ulaşabilirsiniz.

Kısacası değişiklikler artarak devam ediyor. Bütün bu değişim içerisinde, bu yeni şeyleri kavramak, denemek oldukça zahmetli olabiliyor. Daha tam oturmamış olması, .NET Framework tarafında olup .NET Core tarafında desteklenmeyen namespace’ler olması biraz uğraştırıyor. Ama işin keyifli ve güzel yanlarından biri de bu değil mi? Son durumun özeti olması adına faydalı olduğunu düşünüyorum. Bir sonraki kafa karışıklığında görüşmek üzere 🙂

.NET Framework’de geliştirme yapanların, “memory” konusunda biraz daha rahat hissetmesini sağlayan ama sanıldığı kadar basit olmayan bir kavramdan bahsetmek istiyorum. .NET Framework ve “memory” diyince zaten hepimizin bildiği Garbage Collector(GC) direkt aklınızda canlanmıştır diye düşünüyorum.

Geçen hafta yaşadığım bir performans sorununu ve GC ile olan ilişkisinden dolayı bir şeyler yazmak istedim. Şimdi direkt problemden bahsetsem çok anlamlı olmayacak. Bu yüzden öncesinde GC nedir ve nasıl çalışıyor biraz bunlardan bahsetmek istiyorum.

Nedir?

Garbage CollectorManaged platformalarda(.NET, Java…) memory işlemleri bu platformların kendi içinde yönetilir. Biraz daha low-level dillerde ise memory yönetimi geliştirmecinin kontrolündedir. C/C++ ile geliştirme yapmış olanlar malloc() ve free() metodlarını hatırlar. Gerçi çok hatırlamak istemezler sanırım…Neyse…

Basitçe; yazdığımız kodlardaki sınıflar için çalışma zamanında; nesneler için memory’de belli bir alan ayırırız. Nesne ile ilgili işimizi bitirdiğimizde de bu ayrılan yeri tekrar sisteme geri bırakmalıyız ki, uygulamalarımız sorunsuz çalışsın. “Memory Leak” olmak üzere çeşitli memory problemleri oluşmasın. Neyse ki bu işi .NET tarafında GC bizim için hallediyor.

Peki nasıl hallediyor?

.NET’de CLR(Common Language Runtime) ayağa kalktığında, nesneler için, “managed heap” diye bir alan oluşturur. GC’da bu alan üzerindeki nesnelerin kullanımına göre onları yok eder ya da korur. Kullanımı derken, bu nesnelerin yaşamı olarak düşünebiliriz. Bir nesne için, managed heap üzerinden yaratılan alan, referans olarak kullanılıyorsa, o nesne yaşıyordur gibi düşünebiliriz. GC bu referans alanlarına bakarak(buna GC Roots denir) nesnenin yaşamadığı sonucuna varırsa, memory’deki o nesne için olan alanı boşaltır ve başka nesneler için yer açar.

“Managed Heap”, nesnelerin farklı jenerasyonunu tutacak şekilde tasarlanmıştır. Nesneler yaşam sürelerine göre GC tarafından bir jenerasyondan diğerine taşınır. Bu sayede “memory”de daha fazla yaşaması gereken nesneler yaşamlarına devam eder. Ki bütün olayda burada kopuyor aslında. Bu jenerasyonlar Gen0, Gen1 ve Gen2 olmak üzere 3 tanedir.

Devam…