Kasımda .NET Başkadır: .NET Konferansı’24 Notlarım 👩💻💜🍁

Herkese merhaba! Yine bir kasım ayı ve yine bir Dotnet Konferansı! 😊 “Kasımda Dotnet Konferansı bir başkadır” desek yanlış olmaz, değil mi? Bu hafta benim için tam anlamıyla Dotnet Konferansı haftası oldu. Her konferansta olduğu gibi birbirinden değerli konuşmacılar harika içerikler paylaştılar. Geride bıraktığımız hafta boyunca tam 92 oturum gerçekleşti, elimden geldiğince takip etmeye çalıştım ama tabii ki hepsini izlemek mümkün olmadı ancak bazı oturumları izleyip notlar alma fırsatı buldum. Bu yazı kapsamında da bu notları sizlerle paylaşmaya karar verdim. Umarım faydalı olur.
Tüm konferans ajandasına buradan ulaşabilirsiniz. Ayrıca tüm oturumlar Dotnet’in YouTube kanalı üzerinden kayıt alındı, kaçırdıysanız bu link üzerinden izleyebilirsiniz.
Keyifli okumalar ve iyi seyirler! 😊
Hazırsanız, başlayalım 🙂
Nelerden bahsedeceğiz?
params
Parametresiyle Koleksiyon Oluşturma- Geliştirilmiş
partial
Özelliği ile Kısmi Özellikler (Partial Properties) - Yeni Lock Nesnesi
- Metot Grubu Doğal Türü
- İçsel İndeks Erişimi
BinaryFormatter
’ın Kaldırılması- LINQ İçin Yeni
CountBy
,AggregateBy
veIndex
Metotları - .NET MAUI Yenilikleri
- Blazor’da Yeni API ve Hybrid Uygulamalar
- OpenAPI İyileştirmeleri
- HybridCache Yenilikleri
- Dotnet ve AI Temelleri
- Azure Fonksiyonları ile Aspire Entegrasyonu
- Dotnet Konferansı: AI Servisleri ile .NET Entegrasyonu
- .NET 9.0 Performans İyileştirmeleri
params
Parametresiyle Koleksiyon Oluşturma [1],[2]
C# 13 ile gelen params
desteği bir sınıfın constructor’ını daha pratik ve esnek hale getiriyor. Artık koleksiyonları başlatmak için ekstra bir liste oluşturmak yerine doğrudan elemanları constructor’a aktararak işlemi çok daha kolay yapabiliyoruz. Mesela, bir alışveriş sepeti (ShoppingCart) sınıfında ürünleri tek tek yazıp, bu ürünleri doğrudan constructor’a geçirebiliyoruz.
Önceki Versiyondaki Kullanım (C# 12 ve Öncesi)
Aşağıdaki kodda ShoppingCart
adlı bir sınıf alışveriş sepetindeki ürünleri temsil etmek için tanımlanmıştır. Sınıfın Items
adlı bir listesi vardır ve bu liste, sepet içindeki ürünleri (string
olarak) saklar. Sınıfın constructor’ı, başlangıçta bir ürün listesi alarak Items
özelliğine atar. Ana programda ise bir ShoppingCart
nesnesi “Laptop” “Mouse” ve “Keyboard” içeren bir listeyle oluşturulmuştur. Ardından foreach
döngüsüyle, sepetteki her bir ürün ekrana yazdırılır. Bu kodun çıktısı her satırda bir ürün adı olacak şekilde sırasıyla “Laptop” “Mouse” ve “Keyboard” olacaktır.
public class ShoppingCart
{
public List<string> Items { get; set; }
public ShoppingCart(List<string> items)
{
Items = items;
}
}
var cart = new ShoppingCart(new List<string> { "Laptop", "Mouse", "Keyboard" });
foreach (var item in cart.Items)
{
Console.WriteLine(item);
}
Laptop
Mouse
Keyboard
C# 13 ile Kullanım
C# 13 ile params
kullanarak alışveriş sepeti sınıfını daha kolay başlatabiliriz. Sınıfın yapıcı metodu (constructor
) params
anahtar kelimesi sayesinde ürünleri ayrı ayrı girmemize olanak tanıyor. Yani liste oluşturmakla uğraşmadan, new ShoppingCart("Laptop", "Mouse", "Keyboard")
şeklinde bir sepet oluşturabiliyoruz. Sonrasında foreach
döngüsüyle sepetteki her ürünü ekrana yazdırıyoruz. Çıktı olarak da yine sırasıyla “Laptop”, “Mouse” ve “Keyboard” kelimelerini görüyoruz.
public class ShoppingCart
{
public List<string> Items { get; set; }
public ShoppingCart(params string[] items)
{
Items = new List<string>(items);
}
}
var cart = new ShoppingCart("Laptop", "Mouse", "Keyboard");
foreach (var item in cart.Items)
{
Console.WriteLine(item);
}
C# 13 ile gelen özellikle params
anahtar kelimesi kullanılarak ürünler doğrudan constructor’a tek tek parametre olarak aktarılabiliyor, bu da kodun daha kısa ve anlaşılır olmasını sağlıyor. İlk kodda ise bir liste oluşturup sonra bu listeyi constructor’a göndermek gerekiyor, bu da daha fazla adım ve dolayısıyla daha fazla kod yazılmasını gerektiriyor. Yani, params
kullanmanın avantajı, kodun daha sadeleşmesi ve ürünleri kolayca ekleyebilmek için ekstra liste oluşturma ihtiyacını ortadan kaldırması diyebiliriz. 🙂
Geliştirilmiş partial
Özelliği ile Kısmi Özellikler (Partial Properties) [2][3]
C# 12 ve Öncesi ile Kullanım
Aşağıdaki kodda, User
sınıfı iki partiala ayrılmıştır. İlk partialda, SetFirstName
ve GetFirstName
adlı kısmi metotlar tanımlanır, ancak bu metotların işlevselliği belirtilmemiştir. İkinci partialda ise, bu kısmi metotların ne şekilde çalışacağı tanımlanır. SetFirstName
metodu, _firstName
adlı özel alanı güncellerken, GetFirstName
metodu bu değeri döndürür. Kullanıcı, SetFirstName("Ali")
ile ismini belirledikten sonra, GetFirstName()
ile ismi alıp konsola yazdırır. Bu kodun çıktısı “Ali” olacaktır.
- C# 12 ve öncesinde,
partial
anahtar kelimesi, sınıfları veya metodları birden fazla dosyaya bölmek için kullanılıyordu. Bu işlem büyük projelerde sınıfları düzenlemek ve yönetmek için faydalı bir işlem diyebiliriz. - Kodda
SetFirstName
veGetFirstName
gibi metodların imzaları (yani metodların adı, aldığı parametreler) birinci partialda tanımlanmış. Bu metodların ne iş yaptığı veya nasıl çalıştığı tanımlanmamış, sadece metodun ne yapacağına dair bir “şablon” verilmiş. - İkinci parçada ise bu metodların içeriği yani ne yaptıkları tanımlanmış.
SetFirstName
metodunda,_firstName
adlı değişkene yeni bir değer atıyoruz.GetFirstName
metodunda ise bu değeri geri döndürüyoruz. - Kodun kullanım kısmında,
user.SetFirstName("Ali");
ile,SetFirstName
metodunu çağırıp, “Ali” değerini_firstName
değişkenine atıyoruz. - Sonrasında
Console.WriteLine(user.GetFirstName());
ile,GetFirstName
metodunu çağırıp,_firstName
değerini ekrana yazdırıyoruz, yani ekrana “Ali” yazdırılacak.
public partial class User
{
private string _firstName;
public partial void SetFirstName(string name);
public partial string GetFirstName();
}
public partial class User
{
public partial void SetFirstName(string name) => _firstName = name;
public partial string GetFirstName() => _firstName;
}
var user = new User();
user.SetFirstName("Ali");
Console.WriteLine(user.GetFirstName());
Ali
C# 13 ile gelen özellik sayesinde, aslında çok kullanışlı bir değişiklik sağlamış. Daha önce, bir sınıfta özellikleri tanımlarken genellikle bir alan (field) ile birlikte, bu alana erişmek için getter ve setter metodlarını yazmamız gerekiyordu. Mesela, eski kodda SetFirstName
ve GetFirstName
metodlarıyla, _firstName
değerine erişiyorduk. Bu biraz daha fazla yazım gerektiriyordu. C# 13 ile artık bu kadar karmaşık olmasına gerek yok. Yani, bir sınıfın içinde bir özelliği iki ayrı parçada tanımlayıp bu parçaları birleşerek tam bir özellik haline getirebiliyoruz. Doğrudan FirstName
gibi bir özelliği tanımlayıp kullanabiliyoruz.
public partial string FirstName { get; set; }
şeklinde,FirstName
isminde bir özellik tanımlanmış. Bu özellik, hem getter (değer alıcı) hem de setter (değer atayıcı) metotlarına sahip. Fakat burada önemli bir şey var:partial
anahtar kelimesi, bu özelliğin yalnızca bir yerde tanımlanıp diğer yerde kullanılacağını gösteriyor. Yani, bu özellik iki parçadan birleştirilerek tek bir özellik haline geliyor.- Örneğin, bu sınıfın ilk kısmında (ilk
partial class User
),FirstName
özelliğinin tanımını yazıyorsunuz, ve ikinci kısmında (ikincipartial class User
), aynı özelliği tekrardan tanımlıyorsunuz. Sonuçta, her iki tanım birleşiyor ve sınıfın bir parçası haline geliyor.
public partial class User
{
public partial string FirstName { get; set; }
}
public partial class User
{
public partial string FirstName { get; set; }
}
// Kullanımı
var user = new User { FirstName = "Ali" };
Console.WriteLine(user.FirstName); // Çıktı: Ali
Ali
Yeni Lock Nesnesi [4]
Programlarda, birden fazla iş parçacığının (thread) aynı anda aynı veriye erişmesi bazen sorun yaratabilir. Bu durumda, bir iş parçacığı veriyi değiştirmeye başladığında diğerlerinin o veriye erişmesini engellemek gerekebilir. Bunu sağlamak için lock (kilitleme) kullanılır.
NET 9′da System.Threading.Lock adında yeni bir tür, yani yeni bir nesne tipi tanıtıldı. Bu yeni tür ile birlikte kilitleme işlemleri daha güvenli ve verimli hale gelmiş gözüküyor. Yeni özellikle birlikte Lock.EnterScope() adında bir yöntem eklenmiş. Bu yöntem, kodun kilitli olduğu bir “özel alan” (exclusive scope) başlatıyor. Yani, bir iş parçacığı o alana girdiğinde, başka iş parçacıkları bu alana giremiyor. Bu alanın dışına çıkıldığında ise Dispose() yöntemiyle bu kilit sonlanıyor, yani diğer iş parçacıkları tekrar o veriye erişebiliyor.
C#’ta lock ifadesi (yani kilitleme komutu) artık Lock nesnesini gördüğünde eski kilitleme yöntemini değil de, bu yeni ve güncellenmiş API’yi kullanacak. Eski yöntem System.Threading.Monitor kullanıyordu, yeni yöntem ise daha verimli görünüyor. Yani, eski kodu değiştirmeden sadece kilitlediğiniz nesnenin tipini değiştirmeniz yeterli olacak. 🙂
Metot Grubu Doğal Türü [5]
- “Method Group Natural Type” (Yöntem Grubu Doğal Tipi) diye adlanıdrılan özellik temel olarak bir tür optimizasyon yani iyileştirme sağlamaktadır.
- Bu iyileştirme yöntem aşırı yüklemesi (method overloading) ile ilgili bir durumdur. Yöntem aşırı yüklemesi, aynı isimle birden fazla yöntemin (method) olmasıdır. Mesela bir
Add()
metodu, farklı parametre sayılarıyla ya da parametre tipleriyle birden fazla kez tanımlanabilir. - Eskiden derleyici (compiler) her bir yöntem için tüm olası varyasyonları (yani aşırı yüklenmiş metodları) gözden geçirirdi ve hepsini bir arada değerlendirirdi.
- Yeni davranışla birlikte derleyici her bir kapsamda (scope) uygun olmayan yöntemleri çıkarıyor. Genellikle çıkarılanlar yanlış parametre sayısına (arity) sahip ya da bazı kısıtlamaları (constraints) karşılamayan yöntemler olmaktadır.
- Bu yeni özellik derleyicinin hangi metodun kullanılacağına karar verirken gereksiz seçenekleri eleyerek daha hızlı ve doğru bir seçim yapmasını sağlamaktadır.
İçsel İndeks Erişimi [6]
Bir dizideki elemanlara genellikle sırasıyla, baştan (yani 0. indisten başlayarak) ulaşırız. Örneğin, ilk elemanı myArray[0]
ile alırız, ikinci elemanı myArray[1]
ile alırız ve böyle devam eder. Ama bu yeni özellikte, dizinin sonundan (en sonuncusundan) geriye doğru saymaya başlamak için yeni bir yöntem getirildi.
^
işareti, dizinin sonundaki elemanlara erişmek için kullanılıyor. Yani^1
, dizinin sonundaki (sonuncu) elemanı,^2
dizinin sondan bir önceki elemanını ifade ediyor. Önceden, bir dizi baştan sona doğru indekslenmek zorundaydı ama şimdi C# 13 ile birlikte bu^
işareti sayesinde dizinin sonundan başlamayı kolayca yapabiliyoruz.
var countdown = new TimerRemaining()
{
buffer =
{
[^1] = 0, // Son eleman = 0
[^2] = 1, // Sondan bir önceki eleman = 1
[^3] = 2, // ... vb.
[^4] = 3,
[^5] = 4,
[^6] = 5,
[^7] = 6,
[^8] = 7,
[^9] = 8,
[^10] = 9
}
};
Bu örnekte, dizinin son elemanına ^1
, sondan bir önceki elemanına ^2
şeklinde erişiyoruz. Bu sayede diziyi tersine doğru kolayca doldurmuş olduk.
BinaryFormatter
’ın Kaldırılması [3][7]
Güvenlik endişeleri nedeniyle Binary Formatter artık .NET 9’da varsayılan olarak desteklenmemektedir. Kodu derlemek mümkün ancak çalıştırırken PlatformNotSupportedException
hatası alabilirsiniz. Eğer kullanmaya devam etmek istiyorsanız, alternatif bir paket ekleyebilirsiniz.
Bu değişiklik, güvenliği artırmak amacıyla yapılmıştır ve mevcut kodların uyumluluğunu korumak isteyenler için bir NuGet paketi sunulmaktadır.
Eski Kullanım Örneği
using System.Runtime.Serialization.Formatters.Binary;
public class Example
{
public void SerializeObject(object obj, string fileName)
{
BinaryFormatter formatter = new BinaryFormatter();
using (FileStream stream = new FileStream(fileName, FileMode.Create))
{
formatter.Serialize(stream, obj);
}
}
}
.NET 9’da bu kullanım artık desteklenmiyor. Alternatif olarak JSON veya XML serializer kullanabilirsiniz.Ancak, geliştiricilere Binary Formatter kullanımını bırakmaları tavsiye edilmektedir.
LINQ İçin Yeni CountBy
, AggregateBy
ve Index
Metotları[3][8]
Üç yeni LINQ metodu CountBy, AggregateBy ve Index ile daha fazla veri manipülasyon yeteneği sunulmaktadır. Özellikle Index metodu, veri dizilerinde elemanların indekslerine erişimi daha kolay hale getirmekte ve döngülerde kullanılan geleneksel yöntemlere olan bağımlılığı azaltmaktadır.
List<Person>
nesnesi üzerinde önce for
döngüsü kullanarak ardından da .NET 9 ile gelen Index
özelliğiyle nasıl işlem yapılacağını örneklerle açıklayayım. Öncelikle bir Person
sınıfı oluşturalım ve ardından her iki yöntemi de List<Person>
nesnesi üzerinde uygulayalım:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
Örnek bir List<Person> oluşturalım.
var people = new List<Person>
{
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Charlie", 35),
new Person("David", 28)
};
for
Döngüsü ile Index
ve Value
(Değer) Almayı deneyelim!
Bu for
döngüsü, people
listesi içindeki her bir öğeye sırasıyla erişerek dizin (index
) bilgisiyle birlikte öğenin özelliklerini (Name
ve Age
) ekrana yazdırır. Burada, i
değişkeniyle indeks bilgisi manuel olarak tutulur.
for (int i = 0; i < people.Count; i++)
{
Console.WriteLine($"Index: {i}, Name: {people[i].Name}, Age: {people[i].Age}");
}
Index: 0, Name: Alice, Age: 30
Index: 1, Name: Bob, Age: 25
Index: 2, Name: Charlie, Age: 35
Index: 3, Name: David, Age: 28
.NET 9 Index
Özelliği ile Select
Metodu Kullanarak Index
ve Value
Alma
.NET 9 ile gelen Select
metodu içindeki yeni Index
özelliğini kullanarak aynı işlemi daha kısa ve daha anlaşılır bir şekilde yapabiliriz. Bu özellik, her bir öğe ile birlikte dizin bilgisini otomatik olarak sağlar.
var indexedPeople = people.Select((person, index) => (Index: index, Person: person));
foreach (var item in indexedPeople)
{
Console.WriteLine($"Index: {item.Index}, Name: {item.Person.Name}, Age: {item.Person.Age}");
}
Index: 0, Name: Alice, Age: 30
Index: 1, Name: Bob, Age: 25
Index: 2, Name: Charlie, Age: 35
Index: 3, Name: David, Age: 28
for
döngüsü kullanıldığında, dizin (index
) değerini manuel olarak kontrol etmeniz gerekir. Bu, kodun daha uzun ve potansiyel olarak hata yapmaya açık olmasına neden olur, çünkü her for
döngüsünde i
gibi bir değişken kullanarak saymayı sizin yapmanız gereklidir. .NET 9 Index
özelliği ile Select
ile birlikte Index
özelliğini kullandığınızda, dizin değeri otomatik olarak sağlanır.
.NET MAUI Yenilikleri [9][10]
.NET MAUI’nin ana hedeflerinden biri, uygulamanın performansını ve kalitesini iyileştirmekteydi. Bu doğrultuda, end-to-end testlerin uygulamaya dahil edilmesi önemli bir adım oldu. Bu testler, uygulamanın başlangıcından sonuna kadar olan tüm süreçlerini kapsayarak olası hataları ve performans sorunlarını erkenden tespit edilmesine olanak tanıyor. Bu sayede geliştiriciler daha sağlam ve hatasız uygulamalar geliştirme imkanı buluyor.
- .NET 9 ile birlikte, iOS, Mac Catalyst, Android ve Windows gibi platformlar için minimum dağıtım hedefleri aynı kaldı. Bu da geliştiricilerin mevcut projelerinde herhangi bir büyük değişiklik yapmadan yeni özellikleri entegre edebilmelerini sağlıyor. Böylece geliştiricilerin zaman kaybı yaşamadan güncellenmiş özellikleri kullanmalarına olanak tanıyor ve mevcut uygulama geliştirme süreçlerine zarar vermiyor.
- .NET 9 ile .NET MAUI’ye iki yeni kontrol eklenmiş durumda. Bunlardan ilki, Hybrid WebView kontrolü. Bu kontrol uygulamalar içinde web içeriği barındırmak isteyen geliştiriciler için oldukça kullanışlı. WebView içinde HTML sayfaları göstermekle kalmıyor, aynı zamanda bu web içeriği ile uygulama arasındaki veri iletişimini de sağlıyor. Yani bir uygulama içinde dinamik web içerikleri gösterebilirken bu içeriklerle etkileşimde bulunmak da mümkün oluyor. Örneğin, bir e-ticaret uygulamasında dışa bağlı bir ödeme sayfası göstermek ve bu sayfada kullanıcı verilerini almak gibi işlemler rahatlıkla yapılabilir.
- Diğer bir yeni kontrol ise Title Bar Control. Bu kontrol, özellikle Windows platformu için tasarlanmış. Geliştiriciler, bu kontrolü kullanarak Microsoft Office ve diğer Microsoft uygulamalarında gördüğümüz başlık çubuğu benzeri bir yapıyı uygulamalarına entegre edebiliyor. Başlık çubuğunda; uygulamanın adı, menüler ve hızlı erişim araçları gibi öğeler yer alabiliyor, bu da uygulamanın görsel tasarımını daha profesyonel ve kullanıcı dostu hale getiriyor.
Blazor’da Yeni API ve Hybrid Uygulamalar [11][12]
- .NET 9’da Blazor için yeni bir API eklendi ve bu API, Blazor bileşenlerinin hangi ortamda çalıştığını ve etkileşim modunu (örneğin, WebAssembly mi yoksa Server mi?) belirlemeyi kolaylaştırıyor.
- Uygulamanızın çalıştığı ortama göre farklı işlemler yapabilirsiniz. Örneğin, Blazor bileşeni WebAssembly’de çalışıyorsa cihazda daha fazla işlemci gücü tüketirken, Server modunda çalışıyorsa sunucu üzerinde işlem yaparak daha hızlı veri transferi sağlayabilirsiniz.
- Bu geliştirmelerle Blazor bileşenleri artık .NET MAUI ile daha entegre hale gelmiş oldu. Bu mobil uygulamalarda Blazor bileşenlerini doğrudan kullanma imkânı veriyor ve .NET MAUI uygulamalarını hibrit hale getiriyor. Yani, mobil uygulamanızda web bileşenleri çalıştırarak web deneyimini mobile de taşıyabilirsiniz.
OpenAPI İyileştirmeleri [13][14]
OpenAPI entegrasyonunda yapılan son iyileştirmeler, API geliştirenler için daha kapsamlı ve uyumlu dokümantasyon oluşturmayı kolaylaştırıyor. Bu iyileştirmeler sayesinde, Swagger gibi araçlarla API testleri daha verimli yapılabilir ve hata ayıklama süreçleri hızlanır. Geliştirmelerde özellikle AddOpenApi ve MapOpenApi yöntemleri öne çıkıyor. Bu yeni yöntemler, .NET uygulamalarında OpenAPI dokümantasyonunu yapılandırmayı ve yönetmeyi daha kolay hale getiriyor.
- AddOpenApi yöntemi, OpenAPI dokümantasyonunun projelere hızlıca eklenmesini sağlıyor. Bu sayede geliştiriciler, OpenAPI desteğini daha kolay entegre edebiliyor ve servislerin yapısını ile parametrelerini daha düzenli bir şekilde dokümante edebiliyorlar. Böylece manuel yapılandırma gereksinimi azalıyor ve iş akışları daha verimli hale geliyor.
- MapOpenApi yöntemi ise API rotalarını otomatik olarak OpenAPI dokümantasyonuna dahil etmek için kullanılıyor. Bu özellik, uygulamanın tüm rotalarını ve uç noktalarını OpenAPI dokümantasyonuna dahil etmeyi çok daha pratik hale getiriyor. Geliştiriciler, her bir rota için manuel olarak dokümantasyon yazmak zorunda kalmıyor; bunun yerine, sistem tüm rotaları otomatik olarak dokümantasyona ekliyor. Bu sayede API geliştirme süreci daha hızlı ve hatasız ilerliyor.

HybridCache Yenilikleri [15][16]
Hybrid Cache API ve diğer yenilikler, .NET 9’un getirdiği önemli geliştirmeler arasında yer alıyor ve özellikle uygulama performansını artırmayı hedefliyor. Bu özelliklerin temel amacı, geliştiricilerin uygulamalarını daha verimli ve güvenli bir şekilde yönetmelerine yardımcı olmak.
Hybrid Cache API, bellek içi (in-memory) ve dağıtılmış (distributed) cache teknolojilerini bir araya getiren yeni bir çözüm. Daha önce bu iki tür cache ayrı ayrı kullanılıyordu; bellek içi cache verileri uygulamanın kendi belleğinde saklarken, dağıtılmış cache verileri birden fazla sunucuya yayarak daha büyük ölçekli uygulamalarda kullanılabiliyordu. Hybrid Cache, her iki çözümü birleştirerek bu tür sistemlerin avantajlarını bir arada sunuyor. Bu yenilikle birlikte, veriler hem hızlı erişim için bellek içinde saklanabiliyor, hem de farklı sunucular arasında güvenli bir şekilde dağıtılabiliyor. Örneğin, yüksek trafiğe sahip bir uygulama, verilerin kaybolmaması için dağıtılmış cache kullanırken, daha düşük trafikli durumlar için ise daha hızlı bellek içi cache kullanabiliyor. Bu da geliştiricilere esneklik ve ölçeklenebilirlik kazandırıyor. Ayrıca, her iki tür cache’i tek bir sistemde kullanmak, yönetim karmaşıklığını azaltarak işleri daha kolay hale getirebilir
- .NET 9 ile gelen bir diğer yenilik, test komutlarının farklı hedef platformlarda paralel olarak çalıştırılabilmesidir. Daha önce, aynı projedeki testler yalnızca bir hedef platformda çalıştırılabiliyordu, ancak bu yeni özellik sayesinde testler birden fazla platformda aynı anda çalıştırılabiliyor. Bu, testlerin daha hızlı ve verimli bir şekilde yapılmasını sağlıyor. Özellikle çapraz platform uyumluluğu test edilen projelerde bu özellik, önemli bir zaman tasarrufu sağlıyor.
- Bir diğer dikkat çeken yenilik, terminal logger özelliği. Bu özellik, proje derlenirken tüm önemli bilgilerin ve hataların terminal üzerinde anında görüntülenmesini sağlıyor. Bu, geliştiricilerin projelerini daha kolay bir şekilde izlemelerini ve sorunları hızla çözmelerini sağlıyor. Önceden bu özellik manuel olarak etkinleştirilmesi gerekiyordu, ancak artık varsayılan olarak aktif durumda ve isterse geliştirici bu özelliği kapatabiliyor.
- .NET 9‘un bir diğer önemli yeniliği, .NET restore komutunun artık yalnızca doğrudan paketleri değil, dolaylı bağımlılıkları da kontrol etmesidir. Bu, projelerde kullanılan bağımlılıkların daha güvenli hale getirilmesini sağlıyor. Daha önce yalnızca doğrudan kullanılan paketlerin güvenlik açıkları kontrol ediliyordu, ancak şimdi bu bağımlılıkların başka paketlerle olan ilişkileri de göz önünde bulunduruluyor. Böylece, projenin tüm bağımlılıkları daha kapsamlı bir şekilde güvenlik açısından taranabiliyor.
Dotnet ve AI Temelleri [17]
Dotnet Konferansı’nın AI Temelleri .NET oturumu, yapay zeka teknolojilerinin .NET platformuyla entegrasyonuna yönelik kapsamlı bilgiler dundu. Modern yapay zeka uygulamalarının .NET ekosistemine nasıl dahil edilebileceğini detaylı bir şekilde ele alındı diyebilirim.
ML.NET ve Semantic Kernel ile Yapay Zeka Entegrasyonu
Oturumda, .NET’in ML.NET ve Semantic Kernel gibi araçlarla yapay zeka uygulamalarına yönelik geniş imkanlar sunduğu vurgulandı. ML.NET, makine öğrenimi modellerinin kolayca geliştirilmesini ve kullanılmasını sağlarken, Semantic Kernel doğal dil işlemesi ve görev planlama gibi karmaşık işlevler için güçlü bir altyapı sunmaktadır. Bu iki araç, .NET ekosistemindeki yapay zeka projelerinde esneklik ve işlevsellik sağlamaktadır.
AI SDK ve Framework’leri
.NET, geniş bir yapay zeka araç seti ve çerçevesi ile dikkat çekmektedir. Bu çerçevede oturumda öne çıkan SDK ve framework’ler şunlar oldu:
- AI SDK’leri: Yapay zeka projelerinde temel işlevleri gerçekleştirmek için optimize edilmiş yazılım geliştirme kitleri.
- Vector Store SDK’leri: Vektör tabanlı verilerle çalışan projeler için etkin veri yönetimi sağlar.
- ONNX Runtime: Hızlı ve verimli model çalıştırma desteği.
- TorchSharp: PyTorch ile uyumlu bir araç olarak, derin öğrenme modellerini .NET ile entegre eder.
- LightGBM: Büyük veri setlerinde optimize edilmiş makine öğrenimi.
- DataFrame ve SciSharp: Veri analizi ve işleme için güçlü araçlar.
Veri İşleme ve Abstractionlar
Yapay zeka uygulamalarında veri işleme ve model entegrasyonunun önemi dikkate alınarak Tokenizers, Tensors ve AI/Vector Veri Abstractionları gibi konular ele alınmıştır. Bu yenilikler, geliştiricilere büyük boyutlu verilerle çalışırken performansı artıran çözümler sağlamaktadır.
Tokenizasyon Alanındaki İlerlemeler
.NET 9, farklı yapay zeka modelleriyle uyumlu çeşitli tokenizasyon algoritmalarını desteklemektedir:
- Tiktoken: GPT-3, GPT-3.5, GPT-4 ve Llama 3 gibi büyük dil modelleriyle tam uyumluluk.
- SentencePiece: LLama2 ve Mistral modelleri için optimize edilmiş yapılar.
- Codegen: Phi 2 ve Codegen tabanlı modellerin etkin çalışmasını sağlar.
- WordPiece: BERT tabanlı modeller için ideal tokenizasyon algoritması.
Bu çeşitlilik, farklı modellerle çalışırken geliştiricilere esneklik sunmakta ve projelerdeki entegrasyon zorluklarını en aza indirmektedir.
TensorPrimitives ve Tensor<T> Yenilikleri
.NET 9, tensör işlemlerini daha performanslı ve kullanıcı dostu hale getiren önemli güncellemeler içermektedir:
TensorPrimitives
- 200’ün üzerinde matematiksel işlem için genişletilmiş overload desteği.
- SIMD (Single Instruction Multiple Data) desteği ile yüksek performans.
- Generic overload’lar sayesinde daha geniş bir kullanım alanı.
Tensor<T> Önizlemesi
- TensorPrimitives temeli üzerine inşa edilmiştir.
- Çok boyutlu veri yapılarının kolayca manipüle edilmesine olanak tanır.
- AI kütüphaneleriyle sorunsuz entegrasyon sağlar ve performansı artırır.
.NET Aspire ile 25 dakikada bir Azure İşlevleri uygulaması oluşturma ve dağıtma [18][19]
Dotnet Konferansında Azure Fonksiyonları ile Aspire Entegrasyonu başlıkları ele alınarak .NET ekosistemindeki bulut tabanlı uygulama geliştirme süreçleri detaylı bir şekilde incelenmiştir. Oturumda, Azure ve Aspire’ın birlikte kullanımına yönelik pratik bilgiler ve örnek projeler sunuldu.
Azure Fonksiyonları ile Aspire Entegrasyonu
Azure Function ve .NET Aspire
Oturumda, Azure Function kullanılarak .NET 9.0 destekli bir fonksiyonun nasıl oluşturulacağı ve bu süreçte Aspire ile entegrasyonun nasıl sağlanacağı ele alınmıştır. Aspire, modern uygulama geliştirme için kullanılan güçlü bir çerçeve olarak öne çıkmaktadır ve Azure ortamında sorunsuz bir şekilde çalışabilmektedir.
Entegrasyon Süreci
Azure Fonksiyonları, .NET Aspire projeleri ile entegre edilebilir bir altyapı sunmaktadır. Oturumda, bu entegrasyonun adım adım nasıl gerçekleştirileceği detaylandırılmıştır. Geliştiricilere, Aspire projelerinin Azure platformunda nasıl verimli bir şekilde çalıştırılabileceği açıklanmıştır.
Örnek Projede Kullanılan Bileşenler
Gösterim yapılan örnek projede aşağıdaki bileşenler üzerinden entegrasyon süreci anlatılmıştır.
- AspNetFunction
- AspNetAspireFunction.AppHost
- AspNetAspireFunction.ServiceDefaults
- BlazorFrontend
Bu bileşenler, Aspire ve diğer projelerin (örneğin, Frontend gibi) birbiriyle uyum içinde çalıştığını göstermek için kullanılmıştır. Örnek proje, başarılı bir şekilde derlenerek Aspire Dashboard üzerinde görselleştirilmiştir.
Aspire Dashboard ve Log Yönetimi
Oturumda, Aspire Dashboard’ın sunduğu görsel yetenekler tanıtılmıştır. Dashboard üzerinden aşağıdaki bileşenlerin durumu ve log bilgileri görsel olarak sunulmuştur:
- Azure-Storage Container
- Blazor Frontend Projesi
- Azure Aspire Function
Aspire Dashboard, tüm projelerin log bilgilerinin merkezi bir yerden kontrol edilmesine olanak tanımaktadır. Azure ortamındaki loglara erişim sağlanabildiği gibi, Aspire Dashboard üzerinden de bu loglara kolaylıkla erişilebileceği gösterilmiştir.
Dotnet Konferansı: AI Servisleri ile .NET Entegrasyonu [20]
Dotnet Konferansı’ndaki son oturumda, AI servislerinin .NET platformunda nasıl entegre edilebileceği ve bu entegrasyonlarla geliştiricilere sağlanan fırsatlar detaylı bir şekilde ele alınmıştır. Aşağıda, oturumun ana başlıkları ve sunulan örneklerin özeti bulunmaktadır:
Entegrasyonlar ve Araçlar
Oturumda, .NET platformunda aşağıdaki AI servislerinin ve framework’lerin entegrasyonuna yer verilmiştir:
- OpenAI, Azure OpenAI, Azure AI Inference, ONNX Runtime GenAI, Ollama, Mistral, Anthropic
- Semantic Kernel: AWS Bedrock, Google Gemini, Mistral, Ollama, OpenAI ve Azure OpenAI gibi servislerle uyumlu çalışabilmektedir.
Tüm bu entegrasyonlar ayrıca Aspire altyapısıyla da entegre edilebilir hale getirilmektedir.
Ele Alınan Konular
Semantic Search ve Embedding İşlemleri
- Embedding İşlemleri: Metin verilerini sayısal verilere dönüştüren embedding süreçleri üzerinde durulmuştur.
Örnek Uygulama
- OllamaEmbeddingGenerator kullanılarak all-minilm modeli üzerinden embedding işlemi yapılmıştır.
- IEmbeddingGenerator arabirimi ile metinler bir diziye çevrilmiş ve embedding’lere dönüştürülmüştür.
- Cosine Similarity hesaplamaları ile metinler arasındaki benzerlik oranları tespit edilmiştir.
Chatbot Geliştirme ve Model Kullanımı
- OllamaChatClient ile llama3.1 modeli kullanılarak temel bir chatbot örneği oluşturulmuştur.
- Soru-Cevap Örneği: “What is AI?” gibi bir soru sorularak, “Max 10 kelime ile cevapla” şeklinde bir yanıt oluşturulmuştur. Alternatif olarak phi3 modeli ve AzureOpenAIClient ile gpt-4-o-mini üzerinde de denemeler gerçekleştirilmiştir.
Fonksiyon Bazlı Chatbot Geliştirme
- CompleteAsync metodu, parametre olarak verilen fonksiyon yapıları ile özelleştirilebilir yanıtlar sunma imkânı sağlamaktadır.
- Sistem, belirli araçlar (tools) ile farklı senaryolara uyum sağlama becerisini geliştirebilmektedir.
Middleware Kullanımı
Özelleştirilebilir Middleware Yapıları:
- UseLanguage Middleware: Örneğin, dil tercihini belirlemek için “Turkish” parametresi verilerek tanımlama yapılmıştır. Bu middleware sayesinde, kullanıcı İngilizce bir soru sorsa bile yanıt otomatik olarak Türkçe dönebilmiştir.
- Diğer Kullanım Alanları: Aynı yöntemle Rate Limiting gibi farklı işlevler de pipeline’a entegre edilebilmektedir.
Vektör Veri Saklama ve Sorgulama
- QdrantClient ile vektör tabanlı veri saklama ve sorgulama süreçleri ele alınmıştır.
- GenerateEmbeddingVectorAsync metodu ile embedding’ler oluşturularak vektör veritabanına kaydedilmiştir.
Görsel İçeriklerle Çalışma
- Oturumda yalnızca metin verileri değil, görsel içeriklerin analizi üzerine de çalışmalar gerçekleştirilmiştir.
- Örnek Çalışma:Bir fotoğrafın içeriği tanımlanmış, birden fazla fotoğraf i çin ise döngü kullanılarak analizler yapılmıştır.
.NET 9.0 Performans İyileştirmeleri [21][22]
.NET 9, tüm .NET uygulamaları için büyük performans iyileştirmeleri sunarak, şimdiye kadar yapılmış en hızlı .NET sürümü olduğu görülüyor. Bu sürümde 7.500’ün üzerinde pull request ile 350’den fazla performans odaklı iyileştirme yapılmış. Bu iyileştirmeler, .NET uygulamalarının genel çalışma hızını ve kaynak verimliliğini artırarak, daha hızlı ve verimli bir çalışma deneyimi sunuyor. Aşağıda, .NET 9 ile yapılan bazı önemli performans geliştirmelerini inceleyeceğiz.
JSON Parsing Performansı
- .NET 9’da yapılan iyileştirmelerden en dikkat çekeni JSON parsing (JSON ayrıştırma) performansıdır. JSON verisi işlemek özellikle web ve API uygulamalarında sık yapılan bir işlem olup, bu alandaki iyileştirmeler uygulama hızını doğrudan etkiler. .NET 9′da JSON ayrıştırma işlemleri daha hızlı hale getirilmiş, büyük veri setleriyle çalışırken daha az işlem gücü harcanması sağlanmıştır. Bu iyileştirmeler, özellikle web uygulamaları ve API’ler için önemli bir performans artışı sağlamaktadır.
Genel Uygulama Performansı
- .NET 9’da yapılan bir diğer büyük iyileştirme, genel bellek yönetimi, işlemci kullanımı ve async işlem optimizasyonları üzerinedir. Bu geliştirmeler sayesinde uygulamalar, daha az CPU ve bellek kullanarak daha fazla işlem gerçekleştirebilmektedir. Bu, özellikle büyük ölçekli uygulamaların daha verimli çalışmasını sağlar.
Çöp Toplama(garbage collection) ve Bellek Yönetimi
- .NET 9, çöp toplama (garbage collection, GC) sisteminde de önemli geliştirmeler sunuyor. Garbage Collection özetle kullanılmayan nesnelerin belleği temizlemek için yapılan bir işlemdir ve bu işlemin optimize edilmesi, uzun süre çalışan uygulamalar için büyük bir fark yaratır. .NET 9’da GC işlemleri daha verimli hale getirilmiş, uygulamaların performansının uzun vadede bozulması engellenmiştir.
Yaygın İşlemlerin Daha Hızlı Gerçekleştirilmesi
- .NET 9, string manipülasyonları, koleksiyon yönetimi ve LINQ sorguları gibi yaygın işlemler için hız iyileştirmeleri sunmaktadır. Bu geliştirmeler, verileri işleme ve analiz etme süreçlerini daha hızlı hale getirerek uygulamanın genel performansını artırır.
Eski Sürümlerle Uyumluluk
- .NET 9’daki performans iyileştirmeleri, daha eski sürümlere sahip olan uygulamalar için de geçerli. Yani eski .NET sürümlerinden .NET 9’a geçiş yapan uygulamalar da bu iyileştirmelerden faydalanabilir. Kod tabanında büyük değişiklikler yapmaya gerek kalmadan mevcut uygulamaların performansını artırmak için kolay ve maliyetsiz bir çözüm sunar.
Bu performans iyileştirmeleri, geliştiriciler için büyük avantajlar sunar, çünkü bu değişiklikler runtime (çalışma zamanı) üzerinde yapılmış olup, herhangi bir kod değişikliği gerektirmez. Bu sayede, uygulamalar .NET 9’a geçildiğinde otomatik olarak daha hızlı çalışır. Ayrıca, .NET 9 ile yapılan bu iyileştirmeler ücretsiz performans artışı sağlamakta, uygulama sahiplerinin daha iyi performans elde etmelerini sağlamaktadır.
Steven Toub, .NET 9‘daki bu performans iyileştirmelerinin detaylarını makale ile detaylı bir şekilde açıklamıştır. Makalesinde her bir iyileştirmenin nasıl çalıştığını ve hangi alanlarda fark yarattığını derinlemesine anlatmaktadır. Bu makale .NET 9‘a geçmeyi planlayan geliştiriciler için harika bir kaynak olup, detaylı açıklamalar ve örneklerle geliştiricilerin uygulamalarını daha verimli hale getirmelerine yardımcı olabilir.
Makalenin tamamına ve daha fazla detaya Steven Toub’un blog yazısından ulaşılabilir.
Kaynakça
- [1] https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#params-collections
- [2] https://youtu.be/japXYFS9YPQ?si=r1lN7gf7uVAhh9HB
- [3] https://youtu.be/u738cXLyvug?si=tz9btD6-3c9iDsX4
- [4] https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#new-lock-object
- [5] https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#method-group-natural-type
- [6] https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#implicit-index-access
- [7] https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-9/libraries
- [8] https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-9/libraries#linq
- [9] https://learn.microsoft.com/en-us/dotnet/maui/user-interface/controls/hybridwebview?view=net-maui-9.0
- [10] https://www.youtube.com/watch?v=4cosSX7ldPs&t=49s
- [11] https://learn.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-9.0?view=aspnetcore-9.0#blazor
- [12] https://www.youtube.com/watch?v=2xXc1hNwp0o&t=5s
- [13] https://learn.microsoft.com/en-us/aspnet/core/fundamentals/openapi/aspnetcore-openapi?view=aspnetcore-9.0&tabs=visual-studio
- [14] https://www.youtube.com/watch?v=pkQdwbYPRP4
- [15] https://learn.microsoft.com/en-us/aspnet/core/performance/caching/hybrid?view=aspnetcore-9.0
- [16] https://www.youtube.com/watch?v=rjMfDUP4-eQ
- [17] https://youtu.be/MdM8G2e7jOg?si=l04gnHhvxSNSQzFk
- [18] https://youtu.be/IQ3gtODpVYM?si=cKoWetv9rrI10LTd[19] https://learn.microsoft.com/en-us/dotnet/aspire/whats-new/dotnet-aspire-9?tabs=windows#support-for-azure-functions-preview…
- [20] https://youtu.be/qcp6ufe_XYo?si=tk_bQwhTl2z_HM0f
- [21] https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-9/
- [22] https://www.youtube.com/watch?v=aLQpnpSxosg&t=241s
- [23] Ve cümlelerimin toparlanmasında can yoldaşım ChatGPT kardeş, sana da teşekkürler 🙂
Her şeyin bir sonu olduğu gibi bir konferans daha sona erdi. Oysa daha dün Dotnet 23’ü konuşuyor, Dotnet 24’ü heyecanla bekliyorduk. Hayatımızın sürekli bir şeyleri beklemekle geçmesi ve zamanın bu kadar hızlı akması bazen düşündürücü, bazen de ürkütücü geliyor. Ancak insan zamanla bu duruma da alışıyor.
Sonuçta önemli olan ne beklediğimiz an ne de geçmişte kalan değil mi? Asıl değerli olan içinde bulunduğumuz “şu an.” Umarım bu makale de size tam şu anda faydalı oluyordur. 😊

Farklı yazılarda görüşmek dileğiyle ! 🙂
Sevgiler..
Kardel