.NET 8 İLE GELEN YENİLİKLER

Selamlar,

Bugünkü makalede, .Net 8.0 ile daha çok güncel hayatta kullanacağınızı düşündüğüm başlıca özelliklerden bahsetmek istiyorum.

Öncelikle Kurulum:

Öncelikle buradaki link’den, an itibari ile “SDK 8.0.1-rc.2” dosyasını seçtiğiniz işletim sistemine göre indirebilirsiniz. Sadece “Visual Studio 2022 (v17.8 Preview)” versiyonunda çalışmaktadır. Örneğin ben Windows 64Bit için indirdim.

Benim Setup’im aşağıdaki gibidir.

1-) GetItems():

Bir dizi içinden, belirli sayıda elemanın rastgele seçilmesini sağlayan “Random.Shared.GetItems()” methodudur. Aşağıdaki örnekde, 5 kişilik bir dizide 3 kişi rastgele seçilmiştir. Benim bu kütüphanede gördüğüm eksiklik, ayni kayit 2 defa seçilebilmektedir. Bunun için, ayrıca önlemlerin alınması gerekmektedir.

Yukarıda dörüldüğü gibi, aynı kayıdın gelmemesi için Random zorlama çözüm aşağıdaki gibidir. Kesinlikle doğru bir çözüm değildir. Amaç, aynı olmayan yani belirtilen sayıda farklı Random eleman seçmektir. Bir de size feyz vermesidir. Yoksa bu işlemin maliyeti, astarı yüzünden pahalıya gelmektedir.”

  • Random.Shared.GetItems(persons.ToArray(), count).Distinct()” : Distinct() extension methodu ile Random farklı elemanlar ilgili dizi içinden alınır.
  • randomPersons.Count() < count” : İstenen sayıda Random eleman alınamamış ise, eksik eleman Random olarak tekrardan alınır.
    • ? Random.Shared.GetItems(persons.Except(randomPersons).ToArray(), count- randomPersons.Count()) : randomPersons“: Random seçilen elemenların haricinde kalan elemanlar içinden eksik sayıda Random eleman alınır. “”Burda da tekrardan ayni elemanlarin Random olarak gelme ihtimali bulunmaktadır. Burdaki kod da, bir sonraki adımda DEĞİŞECEKTİR :)
  • if(randomPersons.Count() < count) returnList.AddRange(personFinalList)“:  Eğer random olarak seçilen sayı, istenen sayıdan az ise sonradan Random seçilen(personFinalList), ilgili listeye eklenir.

Final Çözüm: Burada eğer yeterli sayıda eleman bulunmaz ise bulunan elmanların haricindeki listeden, eksik elemanlar, linq query sorgusu ile çekilmektedir. Ama eksik kalan elmanlar maalesef Random olarak alınmamış olunur.

var personFinalList2 = randomPersons.Count() < count ? persons.Except(randomPersons).Take(count – randomPersons.Count()) : randomPersons“:

program.cs:

İleride bunla ilgili mutlaka Ticket açılacak ve Unique Random seçimi yapılabilecektir. Benim burada alternatifleri göstermemdeki esas amaç, sizlere farklı bakış açıları katmaktır.

* 2-) Alias Tip:

Dikkat ederseniz yukarıda “using GoogleMapPoint = (string, double)” tanımlaması yapılmıştır. Bu C# 12 ile gelecek olan “Alias Tip” tanımlamasıdır. Person sınıfının Point propertysi, bizim custom GoogleMapPoint’dir. Daha detaylı makalesine buradan erişebilirsiniz.

*3-) Primary Constructors: 

Dikkat edilecek ikinci konu, “public class Person(string name, string surname, int age, GoogleMapPoint point)” Person sinifina constructor ve local degişken tanımlamadan, ilgili propertylerin set edilmesidir. Bu işlem için C# 12 ile gelecek olan “Primary Constructor” kullanılmıştır. Daha detyalı makalesine buradan erişebilirsiniz.

Person sınıfı için yeni property tanımlama şekli aşağıdaki gibidir.

4-) Shuffle(): 

Bu ikinci örneğimizde, .Net 8.0 ile gelecek olan, bir dizinin sırasını rastgele hale getirme konusudur. Shuffle(), özellikle makina öğrenimi, şans oyunları ve sınav merkezleri gibi domainler için çok kullanışlı yapılardır. Aşağıdaki örnekde bir dizi eleman, öncelikle karıştırılıp yani rastgele hale getirilip sonra da listelenmiştir.

*5-) Keyed DI Service:

İşte geldik benim en sevdiğim .Net 8.0 yeniliğine. Bildiğiniz Dependency Injection artık değişiyor. Temel olarak, aynı servisleri farklı adlar altında birden çok kez kaydetme ve belirli bir tür/ad birleşimini enjekte etme olanağını bizlere sunuyor. Bunu mümkün kılmak için, eski dostumuz “IServiceProvider“‘ı iki yeni yöntemle genişleten yeni bir arayüz olan “IKeyedServiceProvider” hayatımıza giriyor.  GetKeyedService(serviceType yazın, nesne? serviceKey); nesne GetRequiredKeyedService(serviceType yazın, nesne? serviceKey). Aslında bunlar, işleri oldukça baside indirgeyen methodlar. Bu yapıları birazdan, basit bir örnek ile detaylıca inceleyeceğiz.

Ayrıca nesneleri kaydetmek için, örneğin singleton ömrü boyunca IServiceCollection’da anahtarları alan aşırı yüklenmiş methodlarımız var.

Şimdi yeni bir WebApi projesi yaratalim. Bir tane User servisi yazalım. Sonra da, ilgili servisi Keyed DI servisi kullanarak enjekte edelim.

Model/User:

Service/IUserService: UserService’de, kullanıcı listesi veya ID’ye göre tek bir User alınabilecek methodlarımızı tanımlayalım.

Service/UserService: İlgili UserService, aşağıdaki gibi yazılmıştır. Random yazılmış user listesi ve Id’ye göre spesifik dönülen user EndPointleri yazılmıştır.

program.cs: Bu kısım önemli. UserService, “AddKeyed” keyword’u ile yaşam döngüsü “Transient” olarak eklenmiştir. Ayrıca tanımlama amaçlı string keyword olarak, “user” kullanılmıştır. İlgili servis istendiğinde başka bir string keyword ile tekrardan eklenebilmektedir.

Controller/UserController: Aşağıdaki örnekde “FromKeyedServices” keyword’ü ile Userservice için atanan “user” string tanımlaması ile ilgili servis method içinde parametre olarak alınmaktadır. Klasik bir sınıfın Constructor’ında parametre olarak alıma işi, artık bitti :)

Önemli Not: “FromKeyedService”‘den string bir keyword ile çağrılan servis, bir config dosyasından okunarak çağrılabilir. Bu şu demektir, istendiğinde configden ilgili string değiştirilerek çağrılan servis Runtimeda kolaylıkla degiştirilebilir. Yani örneğin “rabbitMQ” keyword’ü ile çağrılan RabbitMQ Servisi, configden ilgili string keyword “kafka” olarak değiştirilerek runtime’da  Kafka servisi çağrılabilir. Böylece kuyruklama mekanizması, yeni FromKeyedServices ile basit bir string ifadenin güncellemesi ile değiştirilebilecektir.

6-) System.Text.Json’da Perfomans İyileştirmesi:

Artık System.Text.Json ile gelen Serialization methodlarının, Newtonsoft’a göre çok daha performanslı ve daha okunabilir olduğunu söylemek, artık hiç de yanlış olmaz :)

Aşağıdaki örnekde özellikle Interface hiyerarşisinde artık serileştirmenin yapılabildiği gösterilmek istenmiştir. IGeo => IBaseMath interface’inden, Squre ve Circile sınıfları da => IGeo interfaceinden türemiştir. Her iki geometri objesinin, Alanı ve Çevresi hesaplanmaktadır.

program.cs: Aşağıda görüldüğü gibi oluşturulan Circile ve Square şekilleri, onca hiyerarşik kalıtıma rağmen doğru bir şekilde Serialize edilebilmişdir.

program.cs(2): JsonSerializeOptions ile isternir ise çıktısı alınacak JsonString, “Snake Case(altı çizgili)” ya da “kebab-case” ile tireli gibi farklı formatlarda yazılabilir. Ayrica The JsonSerializerOptions.MakeReadOnly()methodu ile, ilgili JsonOption’ın değiştirilemez readonly olması sağlanabilmektedir. Ayrıca “IsReadOnly” propertysi ile, ilgili JsonOption’ın read-only olup olmadığı kontrol edilebilir. Sonradan ilgili option değiştirlmeye çalışılır ise, hata alınacaktır.

7-) Default Lambda Expression:

Aşağıda görüldüğü gibi C# 12 ile lambda expression default değer atamaya izin vermektedir. Son tanımlamada da, geri dönülecek değer hesaplanmaktadır. İlgili Lambda Expression, bir methodun içinde child bir method gibi kullanılmaya imkan sunmaktadır.

8-) Breaking Change: C#12’de"ref" parametresi"in"parametresi yerine geçebilir.

Gelelim sosyal medyada tek bir tweet ile dikkat çekmeye çalıştığım ama yeterince anlatamadığım şu Breaking Change’e :)

  • Car sınıfının bir Name() methodu bulunmaktadır. Parametre olarak da (in int i) verilmiştir. Buradaki “in” keyword’ü, değişkenin immutable yani değiştirilemez olmasını sağlamakda ve değişkeni referans değeri ile read-only şekilde ilgili method içine taşımaktadır.
  • CarExtension olarak Car sınıfına Name() methodu, bu sefer (ref int i) parametresi ile tanımlanmıştır.

Şimdi biz bu Car sınıfının Name() methodunu çağırdığımızda, C#’ın versiyonlarına göre farklı Methodlar çağrılacaktır.

Nedeni C#11’de “ref” keyword’ü, “in” keyword’ü yerine kullanılamaz yani iki keyword tamamen birbirinden farklı algılanır ve yorumlanırlar. Bu nedenle C# 11’de “ref”, keywordü ile çağrılan “Name()” methodu “Name() Extension”‘ının çağırmakta ve console’a “Park” yazmaktadır. Ama C# 12’de “ref” keyword’ü, “in” keyword’ü yerine geçebilmektedir. Yani C# 12’de “ref”, keywordü ile çağrılan “Name()” methodu, Car sınıfına ait içinde “in” keywordü ile tanımlı parametreli Name() methodunu çağıra bilmekte, ve Console’a “Car” yazmaktadır.

program.cs: İşte tam olarak C# 12 ve sonrası versiyonlarının, “ref” keywordünün “in” keywordü yerine kullanılabilmesi, C#’ın önceki versiyonları için Breaking Changes oluşturacaktır.

C# 12 çıktısı:

C# 11 çıktısı:

Geldik bir makalenin daha sonuna. Bu makalede, 14 Kasımda çıkacak olan .Net 8.0 ile kodlarımızda canlı canlı kullanabileceğimiz olan ve beni en çok heycanlandıran yeni özelliklerden bahsetmek istedim. Bunların yanında birçok performans geliştirmesinin de geldiğini, belirtmeden geçmeyeyim. .Net Derleme süresi, Entity Frameworks sorgu çekme süreleri, kullanılan resourcelarda olan gözle görülür düşme ve daha birçoğu. En önemlisi de .Net 7.0’ın supportunun 6 ay sonra bitecek olması. .Net 6 Long Term Support olmasına rağmen .Net 7’nin Suppoprtunun bu kadar kısa olması, pek de alışıla gelmiş bir durum değil. Güzel haber ise, .Net 8 Long Term Support olacak ve 36 ay yani 2026’ya kadar Microsoft tarafında desteği verilecek.

Kodlarınızda .Net versiyonunu ne kadar güncel tutarsanız, en son versiyona geçişiniz de o denli kolay olacaktır. Siz ne kadar eski .Net versiyonunda kalırsanız ve ne kadar 3th Party Tool kullanırsanız, karşılaşacağınız Breaking Changeler o denli olacaktır. Unutmayin, en güncel .Net versiyonunda kodlamanız demek, en performanslı, yeni özellikler sayesinde kolay ve okunabilir bir kod geliştirebildiğiniz ve son olarak support konusunda sorun yaşamıyacağınız bir versiyonda çalışmanız demektir. Yeni bir makalede görüşmek üzere hepinize hoşçakalın.

Github: borakasmer/Net8.0-Features (github.com)

Source:

 

 

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

15 Cevaplar

  1. Görkem Rıdvan dedi ki:

    Teşekkürler.

  2. Ahmet dedi ki:

    Merhaba Bora hocam,
    Yazı için teşekkürler. Daha iyi bir okuma için;
    Yazı fontunu ve boyutunu daha okunaklı yapsanız, göz yormadan okusak.
    * Opera kullanıyorum ve okuma modunda sıkıntı yok ama resimler ve renkli yazılar belli olmuyor maalesef =(
    İyi çalışmalar.

  3. Ömer dedi ki:

    Emeğine sağlık hocam. Birde şu mobil kısmıyla ilgili bizi bir aydınlatsan MAUI geleceği ne olur xamarin gibi atılır mı? gibi gibi

  4. Kingpin dedi ki:

    Selamlar Bora hocam;
    Öncelikle bizlerle paylaştığınız tüm bilgileriniz ve emekleriniz için sizlere sonsuuz teşekkür ederim. Lakin kendi adıma diyorum ki inşaAllah bi gün sizi anlayacağım. İki kere okuyorum üç kere okuyorum sonra bakıyorum ki 0 :D. Her şey için çoook teşekkürler hocam.
    Not: bu yazılım olaylarında 4. senem sadece kendimce bi yorum yapmak istedim.

    • borsoft dedi ki:

      Tesekkurler. Konuyu tam anlamiyorsan ama bir başkası anlıyor ise, belki bazı temel konuların uzerinden tekrar gecmende bir fayda olabilir.

  5. Emre Yılmaz dedi ki:

    Teşekkür ederiz emekleriniz için, yine çok faydalı içerik.

  6. Murat dedi ki:

    Bora hocam elinize sağlık. Şunu sormadan edemiyorum, bu yeni güncellemeler gerçekten ilerleme mi? Bir önceki sürümlerden desteği çekmek için bir bahane mi? Evet güzel gelişmeler var ancak insan sürümlerin hızına yetişemiyor.

  7. Yusuf Kaya dedi ki:

    Hocam iyi çalışmalar. Mauı için de bir içeriğiniz olacak mı malum piyasada pek yok

    • borsoft dedi ki:

      Selamlar Yusuf,
      Maui uzerine cok bir icerik üretmeyi planlamıyorum.Kendim de pek fazla kullanmıyorum.Ama guncel hayatimda kullanirsam, mutlaka makalesini yazarim..

      Iyi calışmalar.

  8. Bilal dedi ki:

    Selam Bora hocam,
    Yeni yılınızı kutlarım. İnşallah yeni yılda .net8 ile gelen daha detaylı yeniliklere değindiğiniz makaleleri okuyabiliriz. Özellikle microservis açısından :)

  9. Muhammet Bilgin dedi ki:

    Bora hocam KEYED DI da verdiginiz ornekte bir sey kafama takildi ama keyed la ilgisiz. GetByUserId methodunda once where ile sorgulayip sonra firstordefault yapmissiniz. Expression’i direkt olarak firstordefault a vermek verimsiz bir hareket mi oluyor. Yoksa bilmedigim bambaska bir soruna sebep oluyor mu?

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.