{"id":4213,"date":"2022-11-16T13:52:42","date_gmt":"2022-11-16T12:52:42","guid":{"rendered":"https:\/\/gokhan-gokalp.com\/?p=4213"},"modified":"2022-11-18T23:13:36","modified_gmt":"2022-11-18T22:13:36","slug":"some-awesome-news-of-net-7","status":"publish","type":"post","link":"https:\/\/gokhan-gokalp.com\/tr\/some-awesome-news-of-net-7\/","title":{"rendered":".NET 7 ile Gelen Baz\u0131 Harika Yenilikler"},"content":{"rendered":"<p>Bildi\u011fimiz gibi <em><strong>.NET Conf 2022<\/strong><\/em>, 8-10 kas\u0131m aras\u0131nda ger\u00e7ekle\u015fti. Konferans s\u0131ras\u0131nda ise <strong><em>.NET 7<\/em><\/strong> ve <em><strong>C# 11 <\/strong><\/em>\u00e7evresinde gelen heyecan verici yeniliklerden ve performans iyile\u015ftirmelerinden bahsedildi. Bu release de \u00f6zellikle biz developer&#8217;lar\u0131n daha &#8220;h\u0131zl\u0131&#8221;, &#8220;lightweight&#8221; ve daha kolay &#8220;cloud-native&#8221; application&#8217;lar geli\u015ftirebilmesi gibi harika konulara odaklan\u0131lm\u0131\u015f.<\/p>\n<p>Bu makale kapsam\u0131nda ise be\u011fendi\u011fim baz\u0131 yeniliklere de\u011finmeye \u00e7al\u0131\u015faca\u011f\u0131m.<\/p>\n<blockquote><p><em><strong>NOT<\/strong><\/em>: \u00d6ncelikle <em>.NET 7 <\/em>release&#8217;ine\u00a0hen\u00fcz sahip de\u011filseniz, <em><a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet\/7.0\" target=\"_blank\" rel=\"noopener\">buradan<\/a> <\/em>indirebilirsiniz.<\/p><\/blockquote>\n<p>Her <em>.NET<\/em> release&#8217;inde oldu\u011fu gibi bu release i\u00e7erisinde de <strong>major<\/strong> denilebilecek bir seviyede, hatta en iyi seviyede performance iyile\u015ftirmesi yap\u0131ld\u0131\u011f\u0131 s\u00f6ylendi. Ger\u00e7ekten de performans konusunda g\u00fczel bir i\u015f \u00e7\u0131kart\u0131lm\u0131\u015f. Bu iyile\u015ftirmelerin \u00f6nemli bir k\u0131sm\u0131 ise <strong><em>JIT<\/em><\/strong> taraf\u0131nda ger\u00e7ekle\u015ftirilmi\u015f ve bu konuya k\u0131saca de\u011finmek istiyorum.<\/p>\n<p>Bildi\u011fimiz gibi <em>JIT,<\/em> <em>MSIL<\/em> code&#8217;u runtime&#8217;da native code&#8217;a \u00e7evirmekten ve y\u00f6netmekten sorumludur. Application&#8217;lar\u0131m\u0131z\u0131n performansl\u0131 \u00e7al\u0131\u015fabilmesi i\u00e7in arka planda bulundu\u011fu environment&#8217;\u0131\/process&#8217;i de dikkate alarak, bir \u00e7ok farkl\u0131 optimizasyonlar ger\u00e7ekle\u015ftirmektedir. Tahmin edebilece\u011fimiz gibi bu tarz just-in-time performans optimizasyonlar\u0131 ise do\u011fas\u0131 ve baz\u0131 tradeoff&#8217;lar gere\u011fi biraz zaman alan i\u015flemlerdir. \u00d6rne\u011fin <em>JIT<\/em> taraf\u0131ndan optimizasyonlar yap\u0131lmad\u0131\u011f\u0131nda veya tam yap\u0131lmad\u0131\u011f\u0131nda application&#8217;\u0131n start-up time&#8217;\u0131 h\u0131zlanabilir fakat fonksiyonalitesi yani throughput&#8217;u d\u00fc\u015febilir. Bu tarz tradeoff&#8217;lar\u0131 azaltabilmek i\u00e7in <em>JIT<\/em>, bildi\u011fimiz gibi <em>.NET Core 3 <\/em>&#8216;den bu yana <strong>Tiered Compilation<\/strong> &#8216;\u0131 default olarak kullanmaya ba\u015flam\u0131\u015ft\u0131r. B\u00f6ylece <em>JIT<\/em> daha iyi bir performans optimizasyonu ger\u00e7ekle\u015ftirebilmek i\u00e7in ilgili method&#8217;lar\u0131 sadece bir kere compile etmek yerine, kullan\u0131m istatisti\u011fine g\u00f6re birden fazla recompile ederek runtime&#8217;da hot-swap i\u015flemini ger\u00e7ekle\u015ftirebilmektedir.<\/p>\n<p><em>.NET 7<\/em> ile birlikte <em>JIT<\/em> taraf\u0131nda yap\u0131lan performans iyile\u015ftirmelerinde <strong>On-stack replacement<\/strong> tekni\u011finden de yararlan\u0131larak, <em>JIT <\/em>&#8216;in azaltmaya \u00e7al\u0131\u015fm\u0131\u015f oldu\u011fu bu tradeoff&#8217;lar tamamen handle edilmeye \u00e7al\u0131\u015f\u0131lm\u0131\u015f. B\u00f6ylece <em>JIT <\/em>&#8216;in ger\u00e7ekle\u015ftirmi\u015f oldu\u011fu optimizasyonlar\u0131 sadece method invocation&#8217;lar\u0131 aras\u0131nda de\u011fil, ilgili method \u00e7al\u0131\u015f\u0131rken dahi ger\u00e7ekle\u015ftirebilmesi sa\u011flanm\u0131\u015f.<\/p>\n<p>Bunlar\u0131n d\u0131\u015f\u0131nda <em>Threading<\/em>, <em>Networking<\/em>, <em>Collections<\/em>, <em>LINQ<\/em> vb. gibi bir \u00e7ok \u00f6nemli noktada da harika performans \u00e7al\u0131\u015fmalar\u0131 yap\u0131lm\u0131\u015f. K\u0131sacas\u0131 <em>.NET 7<\/em> s\u00fcr\u00fcm\u00fcne ge\u00e7i\u015f ile, default olarak g\u00fczel bir performans kazan\u0131m\u0131 elde edebilece\u011fiz.<\/p>\n<h2>Console Application&#8217;lar i\u00e7in Native AOT<\/h2>\n<p>\u00d6ncelikle beni heyecanland\u0131ran <em>Native Ahead-of-time<\/em> (<em>AOT<\/em>) konusu ile ba\u015flamak istiyorum.\u00a0 Bildi\u011fimiz gibi <em>.NET<\/em> tak\u0131m\u0131 bir s\u00fcredir <em>Native AOT<\/em> ile ilgili baz\u0131 \u00e7al\u0131\u015fmalar yapmaktayd\u0131 ve <em>.NET 7<\/em> ile birlikte bu \u00e7al\u0131\u015fmalar\u0131 experimental stat\u00fcs&#8217;\u00fcnden \u00e7\u0131kartarak mainline development&#8217;a dahil edeceklerini duyurmu\u015flard\u0131. Bu release ile birlikte art\u0131k <strong>console application&#8217;lar\u0131<\/strong> ve <strong>class library&#8217;leri<\/strong> i\u00e7in <em>Native AOT<\/em> official olarak bizlerle.<\/p>\n<p><em>Native AOT<\/em> k\u0131saca ilgili code&#8217;u run-time yerine <strong>compile-time<\/strong>&#8216;da &#8220;native&#8221; olarak olu\u015fturmaktad\u0131r. K\u0131sacas\u0131 application&#8217;\u0131 publish ederken belirtilen runtime&#8217;a g\u00f6re ilgili <em>IL<\/em> code&#8217;unu native code&#8217;a compile etmektedir. B\u00f6ylece <em>Native AOT<\/em> application&#8217;lar\u0131 \u00e7al\u0131\u015f\u0131rken <em>JIT<\/em>&#8216;e ihtiya\u00e7 duymamaktad\u0131r. Bir ba\u015fka de\u011fi\u015fle, <em>.NET<\/em> runtime&#8217;\u0131 olmayan environment&#8217;larda da <em>Native AOT<\/em> application&#8217;lar\u0131m\u0131z\u0131 \u00e7al\u0131\u015ft\u0131rabilmekteyiz. Tabi her ne kadar bu durum daha \u00f6nce farkl\u0131 \u00f6zellikler alt\u0131nda da bizlere sunulsa da, \u00f6rne\u011fin &#8220;<em>Ready to Run<\/em>&#8221; gibi, <em>Native AOT<\/em> ile birlikte bu concept daha iyi bir noktaya getirilmi\u015f.<\/p>\n<p>Faydalar\u0131 ise k\u0131saca;<\/p>\n<ul>\n<li><em>JIT<\/em> gereksinimini kald\u0131rmakta diyebiliriz. (Tabi bu konu biraz tart\u0131\u015fmaya a\u00e7\u0131k s\u00f6z konusu start-up time&#8217;\u0131 yerine runtime performans\u0131 olunca. Bildi\u011fimiz gibi <em>JIT <\/em>compiler bulundu\u011fu ortam\u0131 analiz ederek, kodumuz i\u00e7in en iyi optimizasyon i\u015flemini de sa\u011fl\u0131yor.)<\/li>\n<li>Application <strong>start up<\/strong> time&#8217;\u0131n\u0131 olduk\u00e7a h\u0131zland\u0131rmakta.<\/li>\n<li>Daha az memory kullan\u0131m\u0131 sa\u011flamakta.<\/li>\n<li>Compile oldu\u011funda ise application&#8217;\u0131n disk size&#8217;\u0131n\u0131 &#8220;self-contained&#8221; publish&#8217;e k\u0131yasla olduk\u00e7a azaltmaktad\u0131r.<\/li>\n<li>Farkl\u0131 programlama dilleri taraf\u0131ndan kullan\u0131labilecek native library&#8217;ler geli\u015ftirilebilmesini de sa\u011flamaktad\u0131r.<\/li>\n<\/ul>\n<p><em>Native AOT<\/em> &#8216;nin heyecan verici olmas\u0131n\u0131n yan\u0131 s\u0131ra, maalesef baz\u0131 limitation&#8217;lar\u0131 da bulunmakta.<\/p>\n<ul>\n<li>E\u011fer runtime code generation&#8217;\u0131na ihtiyac\u0131n\u0131z varsa (System.Reflection.Emit), maalesef <em>Native AOT<\/em> ile kullan\u0131lamayacak.<\/li>\n<li>Dynamic olarak loading&#8217;de ger\u00e7ekle\u015ftirilememekte (Assembly.LoadFile).<\/li>\n<li>\u015euanl\u0131k console application&#8217;lar\u0131 ve class library&#8217;leri i\u00e7in kullanabilmekteyiz.<\/li>\n<li>\u015euanl\u0131k t\u00fcm runtime library&#8217;leri hen\u00fcz full olarak <em>Native AOT<\/em> i\u00e7in uygun de\u011fil.<\/li>\n<li>Trimming&#8217;e de ihtiya\u00e7 duymaktad\u0131r ve trimming&#8217;in de kendisine has limitation&#8217;lar\u0131 bulunmaktad\u0131r. \u00d6rne\u011fin yine dynamic assembly loading ve execution, reflection-based serializers vb. Bu limitation detaylar\u0131na ise, <em><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/core\/deploying\/trimming\/incompatibilities\" target=\"_blank\" rel=\"noopener\">buradan<\/a> <\/em>ula\u015fabilirsiniz.<\/li>\n<\/ul>\n<p>Her ne kadar \u015fimdilik limitation&#8217;lar\u0131 bulunsa da, ilerleyen d\u00f6nemlerde g\u00fczel bir noktaya gelece\u011finden eminim.<\/p>\n<p>H\u0131zl\u0131ca bir test ger\u00e7ekle\u015ftirebilmek i\u00e7in target framework&#8217;\u00fc <em>.NET 7<\/em> olan bir console application olu\u015ftural\u0131m. Ard\u0131ndan verilen input&#8217;un palindrome olup olmad\u0131\u011f\u0131n\u0131 kontrol eden basit kod par\u00e7as\u0131n\u0131 <em>Program.cs<\/em> dosyas\u0131 i\u00e7erisine alal\u0131m.<\/p>\n<pre>string? input = Console.ReadLine();\r\n\r\nbool result = IsPalindrome(input);\r\n\r\nConsole.WriteLine($\"The input '{input}' is a palindrome: {result}\");\r\nConsole.ReadLine();\r\n\r\nstatic bool IsPalindrome(string? input)\r\n{\r\n    if (string.IsNullOrEmpty(input))\r\n    {\r\n        return false;\r\n    }\r\n\r\n    bool result = true;\r\n\r\n    for (int i = 0; i &lt; input.Length; i++)\r\n    {\r\n        if (input[i] != input[(input.Length - 1) - i])\r\n        {\r\n            result = false;\r\n        }\r\n    }\r\n\r\n    return result;\r\n}<\/pre>\n<p>\u015eimdi bu application&#8217;\u0131 native olarak compile edebilmek i\u00e7in, application&#8217;\u0131n project file&#8217;\u0131na a\u015fa\u011f\u0131daki gibi bir property eklememiz gerekmektedir.<\/p>\n<pre class=\"wp-block-preformatted\">&lt;PublishAot&gt;true&lt;\/PublishAot&gt;<\/pre>\n<p>E\u011fer property eklemek istemiyorsak da, publish command&#8217;\u0131 i\u00e7erisinde de parametre olarak ge\u00e7ebiliriz.<\/p>\n<pre>-p:PublishAot=true<\/pre>\n<p>Ard\u0131ndan application&#8217;\u0131 istedi\u011fimiz bir runtime identifier&#8217;\u0131 belirterek, native bir \u015fekilde compile edebilece\u011fiz. \u00d6rne\u011fin <em>Windows<\/em> environment&#8217;\u0131 i\u00e7in &#8220;win-x64&#8221;, <em>Linux<\/em> i\u00e7in ise &#8220;linux-arm64&#8221; identifier&#8217;lar\u0131n\u0131 kullanabiliriz.<\/p>\n<blockquote><p><em><strong>NOT<\/strong><\/em>: E\u011fer application&#8217;\u0131 <em>Ubuntu 20.04<\/em> \u00fczerinde compile edersek, sadece bu versiyonda veya \u00fcst versiyonlar\u0131nda \u00e7al\u0131\u015fmaktad\u0131r. K\u0131sacas\u0131 compile etmek i\u00e7in kullanm\u0131\u015f oldu\u011fumuz <em>Linux<\/em> versiyonuna da dikkat etmemiz gerekmektedir.<\/p><\/blockquote>\n<p>\u015eimdi test edebilmek i\u00e7in a\u015fa\u011f\u0131daki gibi bir <em>Dockerfile<\/em> kullanal\u0131m.<\/p>\n<pre>FROM mcr.microsoft.com\/dotnet\/sdk:7.0 AS build\r\n\r\n# Install NativeAOT build prerequisites\r\nRUN apt-get update \\\r\n    &amp;&amp; apt-get install -y --no-install-recommends \\\r\n       clang zlib1g-dev\r\n\r\nWORKDIR \/source\r\n\r\nCOPY . .\r\nRUN dotnet publish -c release -r linux-x64 -o \/app\r\n\r\nFROM debian:bullseye-slim\r\nWORKDIR \/app\r\nCOPY --from=build \/app .\r\nENTRYPOINT [\"\/app\/NativeAOTTest\"]<\/pre>\n<p>Bu noktada dikkat edersek compile edebilmek i\u00e7in <em>Debian-based<\/em> &#8220;dotnet\/sdk:7.0&#8221;<em>\u00a0<\/em>image&#8217;ini kullan\u0131rken, runtime olarak ise i\u00e7erisinde <em>.NET<\/em> runtime bar\u0131nd\u0131rmayan &#8220;debian:bullseye-slim&#8221; image&#8217;ini kullanaca\u011f\u0131z.<\/p>\n<p>Ayr\u0131ca application&#8217;\u0131 <em>Linux<\/em> machine \u00fczerinden publish etmeden \u00f6nce, a\u015fa\u011f\u0131daki ilgili paket&#8217;e de sahip olmam\u0131z gerekmektedir.<\/p>\n<ul>\n<li>Ubuntu (18.04+): &#8220;sudo apt-get install clang zlib1g-dev&#8221;<\/li>\n<li>Alpine (3.15+): &#8220;sudo apk add clang build-base zlib-dev&#8221;<\/li>\n<\/ul>\n<p><a href=\"\/wp-content\/uploads\/2022\/11\/native-test.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4217 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/11\/native-test.jpg\" alt=\"\" width=\"2080\" height=\"932\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/native-test.jpg 2080w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/native-test-300x134.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/native-test-1024x459.jpg 1024w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/native-test-768x344.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/native-test-1536x688.jpg 1536w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/native-test-2048x918.jpg 2048w\" data-sizes=\"(max-width: 2080px) 100vw, 2080px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2080px; --smush-placeholder-aspect-ratio: 2080\/932;\" \/><\/a><\/p>\n<p>Container&#8217;\u0131 yukar\u0131da g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi build edip \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131m\u0131z da, application&#8217;\u0131n sorunsuz bir \u015fekilde \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 g\u00f6rebiliriz.<\/p>\n<p><em>Native AOT<\/em>&#8216;nin \u00f6zellikle serverless solution&#8217;lar i\u00e7in olduk\u00e7a kullan\u0131\u015fl\u0131 olabilece\u011fini d\u00fc\u015f\u00fcnmekteyim. \u00d6zellikle execution duration&#8217;lar\u0131n\u0131n ve start-up (cold-start) zamanlar\u0131n\u0131n \u00f6nemli oldu\u011funu g\u00f6z \u00f6n\u00fcne al\u0131rsak, bu noktada g\u00fczel bir kazan\u00e7 sa\u011flayabiliriz.<\/p>\n<h2>Built-in Container Support<\/h2>\n<p><a href=\"\/wp-content\/uploads\/2022\/11\/docker-logo.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4230 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/11\/docker-logo.png\" alt=\"\" width=\"960\" height=\"546\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/docker-logo.png 960w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/docker-logo-300x171.png 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/docker-logo-768x437.png 768w\" data-sizes=\"(max-width: 960px) 100vw, 960px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 960px; --smush-placeholder-aspect-ratio: 960\/546;\" \/><\/a><\/p>\n<p>Bu release kapsam\u0131nda bizlerin daha efektif ve h\u0131zl\u0131 cloud-native application&#8217;lar geli\u015ftirebilmemiz \u00fczerine odaklan\u0131ld\u0131\u011f\u0131n\u0131 s\u00f6ylemi\u015ftim. \u0130\u015fte tam da bu kapsamda &#8220;Built-in Container Support&#8221; deste\u011fi de bunlardan birisi.<\/p>\n<p>\u00c7ok k\u00fc\u00e7\u00fck bir \u00f6zellik gibi g\u00f6r\u00fcnse de, h\u0131zl\u0131 bir \u015feyler yapabilmek i\u00e7in ben olduk\u00e7a kullan\u0131\u015fl\u0131 buldum. \u00d6zellikle custome-made bir <em>Dockerfile<\/em> &#8216;a ihtiyac\u0131n\u0131z yoksa, application&#8217;\u0131m\u0131z\u0131 publish ederken belirtece\u011fimiz bir parametre ile containerization i\u015flemini ger\u00e7ekle\u015ftirebilece\u011fiz.<\/p>\n<p>Bu i\u015flem i\u00e7in sadece a\u015fa\u011f\u0131daki package&#8217;\u0131 <em>NuGet<\/em> \u00fczerinden eklememiz gerekmektedir.<\/p>\n<pre class=\" prettyprinted\" tabindex=\"0\"><code class=\"language-shell prettyprinted\"><span class=\"pln\">dotnet <\/span><span class=\"kwd\">add<\/span> <span class=\"kwd\">package<\/span> <span class=\"typ\">Microsoft<\/span><span class=\"pun\">.<\/span><span class=\"pln\">NET<\/span><span class=\"pun\">.<\/span><span class=\"typ\">Build<\/span><span class=\"pun\">.<\/span><span class=\"typ\">Containers<\/span><\/code><\/pre>\n<p>Ard\u0131ndan publish i\u015flemini a\u015fa\u011f\u0131daki gibi ger\u00e7ekle\u015ftirdi\u011fimizde, container image&#8217;i de otomatik olarak olu\u015fturulmu\u015f olacak.<\/p>\n<pre class=\" prettyprinted\" tabindex=\"0\"><code class=\"language-bash prettyprinted\"><span class=\"typ\">dotnet publish --os linux --arch x64 -c Release -p:PublishProfile=DefaultContainer<\/span><\/code><\/pre>\n<p>Ben a\u015fa\u011f\u0131daki gibi bir <em>.NET 7 Web API<\/em> projesi i\u00e7in bir deneme ger\u00e7ekle\u015ftirdim.<\/p>\n<pre>dotnet new webapi -n my-test-api<\/pre>\n<p><a href=\"\/wp-content\/uploads\/2022\/11\/dotnet-container-support.jpg\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4219 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/11\/dotnet-container-support.jpg\" alt=\"\" width=\"2164\" height=\"336\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/dotnet-container-support.jpg 2164w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/dotnet-container-support-300x47.jpg 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/dotnet-container-support-1024x159.jpg 1024w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/dotnet-container-support-768x119.jpg 768w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/dotnet-container-support-1536x238.jpg 1536w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/dotnet-container-support-2048x318.jpg 2048w\" data-sizes=\"(max-width: 2164px) 100vw, 2164px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 2164px; --smush-placeholder-aspect-ratio: 2164\/336;\" \/><\/a><\/p>\n<p>G\u00f6rebilece\u011fimiz \u00fczere container ba\u015far\u0131yla olu\u015fturuldu.<\/p>\n<p>Base image olarak ise <em>Debian-based Linux<\/em> image&#8217;leri default olarak kullan\u0131lmaktad\u0131r. E\u011fer farkl\u0131 bir distribution kullanmak istiyorsak da, bu i\u015flemi a\u015fa\u011f\u0131daki gibi &#8220;ContainerBaseImage&#8221; property&#8217;si ile ger\u00e7ekle\u015ftirebiliriz.<\/p>\n<pre class=\"wp-block-preformatted\">&lt;ContainerBaseImage&gt;mcr.microsoft.com\/dotnet\/aspnet:7.0-alpine&lt;\/ContainerBaseImage&gt;<\/pre>\n<p>Container ismi olarak ise default &#8220;AssemblyName&#8221;, tag olarak ise &#8220;Version&#8221; property&#8217;si kullan\u0131lmaktad\u0131r.<\/p>\n<p>Dilersek bunlar\u0131 da a\u015fa\u011f\u0131daki gibi ilgili property&#8217;ler ile de\u011fi\u015ftirebilmekteyiz.<\/p>\n<pre class=\"wp-block-preformatted\">&lt;ContainerImageName&gt;my-app&lt;\/ContainerImageName&gt;\r\n&lt;Version&gt;1.2.3-alpha2&lt;\/Version&gt;<\/pre>\n<p>Limitation olarak ise \u015fimdilik sadece <em>Linux-based<\/em> container&#8217;lar\u0131 desteklemektedir.<\/p>\n<h2>MemoryCacheStatistics<\/h2>\n<p>Bildi\u011fimiz gibi <em>ASP.NET Core<\/em> i\u00e7erisinde in-memory caching i\u00e7in kullanabilece\u011fimiz en kolay y\u00f6ntem, <em>IMemoryCache<\/em> &#8216;i kullanmak.<\/p>\n<p>Uzun bir zamand\u0131r bizlerle olan <em>IMemoryCache<\/em> &#8216;e, .<em>NET 7<\/em> ile birlikte metric deste\u011fi i\u00e7in yeni bir <em>API<\/em> eklendi. Art\u0131k <em>MemoryCacheStatistics<\/em> ile birlikte cache&#8217;in nas\u0131l kullan\u0131ld\u0131\u011f\u0131 bilgisinin yan\u0131 s\u0131ra, cache&#8217;in tahmini boyut bilgisine de eri\u015febilece\u011fiz.<\/p>\n<p>Application&#8217;\u0131n in-memory cache ile ilgili metric bilgilerine ula\u015fabilmek ve ona g\u00f6re aksiyonlar alabilmek, application&#8217;\u0131n sa\u011fl\u0131\u011f\u0131 a\u00e7\u0131s\u0131ndan faydam\u0131za olacakt\u0131r.<\/p>\n<p>Bu metric bilgilerine eri\u015febilmek i\u00e7in ise <em>IMemoryCache<\/em> \u00fczerinden &#8220;GetCurrentStatistics()&#8221; method&#8217;unu \u00e7a\u011f\u0131rmam\u0131z gerekmektedir. Ayr\u0131ca bu metric&#8217;leri takip edebilmek i\u00e7in ise ister\u00a0<em>EventCounters API<\/em>&#8216;\u0131ndan yararlanarak <em>dotnet-counters <\/em>tool&#8217;u arac\u0131l\u0131\u011f\u0131 ile bu bilgilere eri\u015febiliriz veya <em>.NET metrics API<\/em>&#8216;\u0131 ve <em>OpenTelemetry<\/em> &#8216;den yararlanabiliriz.<\/p>\n<pre>[ApiController]\r\n[Route(\"[controller]\")]\r\npublic class WeatherForecastController : ControllerBase\r\n{\r\n    private readonly IMemoryCache _memoryCache;\r\n\r\n    public WeatherForecastController(IMemoryCache memoryCache)\r\n    {\r\n        _memoryCache = memoryCache;\r\n    }\r\n\r\n    [HttpGet(\"stats\")]\r\n    public ActionResult&lt;MemoryCacheStatistics&gt; GetStats()\r\n    {\r\n        return Ok(_memoryCache.GetCurrentStatistics());\r\n    }\r\n}<\/pre>\n<p>Bu i\u015flemin \u00f6ncesinde ise <em>IMemoryCache<\/em>&#8216;i service collection&#8217;a eklerken, &#8220;TrackStatistics&#8221; parametresini &#8220;true&#8221; olarak set etmemiz gerekmektedir.<\/p>\n<pre>builder.Services.AddMemoryCache(c =&gt; c.TrackStatistics = true);<\/pre>\n<h2>Central NuGet Package Management<\/h2>\n<p>\u00c7ok b\u00fcy\u00fck bir feature olmasa da birden \u00e7ok proje taraf\u0131ndan kullan\u0131lan ortak <em>NuGet<\/em> package&#8217;lar\u0131n\u0131n versiyonlar\u0131n\u0131, merkezi bir lokasyondan y\u00f6netebilmek ho\u015fuma gitti.<\/p>\n<p>Bunun i\u00e7in ilgili solution&#8217;\u0131n root klas\u00f6r\u00fcnde <strong>Directory.Packages.props<\/strong> ad\u0131nda bir dosya olu\u015fturmam\u0131z ve i\u00e7erisinde istedi\u011fimiz package&#8217;lar\u0131 a\u015fa\u011f\u0131daki gibi tan\u0131mlamam\u0131z gerekmektedir.<\/p>\n<pre class=\" prettyprinted\" tabindex=\"0\"><code class=\"language-xml prettyprinted\">&lt;Project&gt; \r\n  &lt;PropertyGroup&gt;     &lt;ManagePackageVersionsCentrally&gt;true&lt;\/ManagePackageVersionsCentrally&gt; \r\n  &lt;\/PropertyGroup&gt; \r\n      &lt;ItemGroup&gt; &lt;PackageVersion Include=\"Newtonsoft.Json\" Version=\"13.0.1\" \/&gt; \r\n  &lt;\/ItemGroup&gt; \r\n&lt;\/Project&gt;\r\n<\/code><\/pre>\n<p>Ard\u0131ndan istedi\u011fimiz proje i\u00e7erisinde sadece ilgili package&#8217;\u0131n ismini reference olarak eklememiz yeterli olacakt\u0131r.<\/p>\n<pre class=\" prettyprinted\" tabindex=\"0\"><code class=\"language-xml prettyprinted\">&lt;Project Sdk=\"Microsoft.NET.Sdk\"&gt; \r\n  &lt;PropertyGroup&gt; \r\n    &lt;TargetFramework&gt;net7.0&lt;\/TargetFramework&gt; \r\n  &lt;\/PropertyGroup&gt; \r\n  &lt;ItemGroup&gt; \r\n    &lt;PackageReference Include=\"Newtonsoft.Json\" \/&gt; \r\n  &lt;\/ItemGroup&gt; \r\n&lt;\/Project&gt;\r\n<\/code><\/pre>\n<h2>Required Members<\/h2>\n<p><em>C# 11<\/em> taraf\u0131nda ise gelen &#8220;required&#8221; keyword&#8217;\u00fc ile, parameter null checking \u00f6zelli\u011fi olduk\u00e7a kullan\u0131\u015fl\u0131 bir hale gelmi\u015f.<\/p>\n<pre>public class MyClass\r\n{\r\n    public required string MyRequiredParam { get; init; }\r\n    public string? MyOptionalParam { get; init; }\r\n}<\/pre>\n<p>Yukar\u0131da g\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi &#8220;required&#8221; keyword&#8217;\u00fcn\u00fc kulland\u0131\u011f\u0131m\u0131zda, ilgili class&#8217;\u0131 initialize ederken &#8220;MyRequiredParam&#8221; parametresini set etmemiz zorunlu bir hale gelecektir.<\/p>\n<h2>Microsoft Orleans 7.0<\/h2>\n<p><a href=\"\/wp-content\/uploads\/2022\/11\/logo_full-orleans.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-4239 lazyload\" data-src=\"\/wp-content\/uploads\/2022\/11\/logo_full-orleans.png\" alt=\"\" width=\"1339\" height=\"512\" data-srcset=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/logo_full-orleans.png 1339w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/logo_full-orleans-300x115.png 300w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/logo_full-orleans-1024x392.png 1024w, https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/logo_full-orleans-768x294.png 768w\" data-sizes=\"(max-width: 1339px) 100vw, 1339px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1339px; --smush-placeholder-aspect-ratio: 1339\/512;\" \/><\/a><\/p>\n<p>Actor-model&#8217;e her zaman ayr\u0131 bir ilgi duymu\u015fumdur ve bu konuda <em>Orleans Project<\/em>&#8216;i de yak\u0131ndan takip etmekteyim. Daha \u00f6nce <em>Orleans<\/em> ile ilgili bir ka\u00e7 farkl\u0131 makale ve bir adet sunum ger\u00e7ekle\u015ftirmi\u015ftim.<\/p>\n<p>\u0130lgili i\u00e7eri\u011fe <em><a href=\"https:\/\/gokhan-gokalp.com\/en\/meetup-building-highly-scalable-distributed-applications-with-actor-model\/\" target=\"_blank\" rel=\"noopener\">buradan<\/a><\/em> eri\u015febilirsiniz.<\/p>\n<p><em>.NET 7<\/em> kapsam\u0131nda <em>Orleans<\/em> taraf\u0131nda da harika performans iyile\u015ftirmeleri ger\u00e7ekle\u015ftirilmi\u015f. Immutability taraf\u0131nda iyile\u015ftirmeler ve yeni bir serialization getirilmi\u015f. Ben bir ka\u00e7 y\u0131l \u00f6nce <em>Orleans<\/em> \u00fczerinde \u00e7al\u0131\u015f\u0131rken ozamanlar zaten harika ve performansl\u0131 bir tool idi. \u00dczerinde bir ka\u00e7 farkl\u0131 application geli\u015ftirmi\u015ftim. \u015eimdiki halini ve performans\u0131n\u0131 a\u00e7\u0131k\u00e7as\u0131 merak ediyorum.<\/p>\n<h2>EF7 JSON Columns &amp; Bulk Operations<\/h2>\n<p>Bildi\u011fimiz gibi <em>SQL Server<\/em> &#8216;\u0131n <em>JSON<\/em> columns deste\u011fi uzun bir s\u00fcredir bizlerle. <em>EF<\/em> taraf\u0131nda da <em>JSON<\/em> columns deste\u011fi art\u0131k bu release ile getirildi. Art\u0131k <em>LINQ<\/em> ile birlikte <em>SQL Server<\/em> taraf\u0131nda <em>JSON<\/em> aggregate&#8217;lerine y\u00f6nelik query&#8217;ler ve farkl\u0131 operation&#8217;lar ger\u00e7ekle\u015ftirebilece\u011fiz.<\/p>\n<p>\u00d6rne\u011fin a\u015fa\u011f\u0131daki gibi bir schema&#8217;ya sahip oldu\u011fumuzu d\u00fc\u015f\u00fcnelim.<\/p>\n<pre>public class Product\r\n{\r\n    public string Name { get; set; }\r\n    public string Description { get; set; }\r\n    public Price PriceDetails { get; set; }\r\n}\r\n\r\npublic class Price\r\n{\r\n    public decimal List { get; set; }\r\n    public decimal Retail { get; set; }\r\n}<\/pre>\n<p>Bu noktada <strong>PriceDetails<\/strong> bilgisini <em>JSON<\/em> column olarak tutmak istiyoruz. Bunun i\u00e7in yapmam\u0131z gereken tek \u015fey, a\u015fa\u011f\u0131daki gibi model configuration&#8217;\u0131 s\u0131ras\u0131nda &#8220;ToJson()&#8221; method&#8217;unu call etmek.<\/p>\n<pre>protected override void OnModelCreating(ModelBuilder modelBuilder)\r\n{\r\n    modelBuilder.Entity&lt;Product&gt;().OwnsOne(\r\n        product =&gt; product.Price, navigation =&gt;\r\n        {\r\n            navigation.ToJson();\r\n        });\r\n}<\/pre>\n<p>Gerisi ise <em>LINQ<\/em> g\u00fcc\u00fcm\u00fcze kalm\u0131\u015f.<\/p>\n<p>Bulk operation&#8217;lar taraf\u0131nda ise &#8220;ExecuteUpdateAsync&#8221; ve &#8220;ExecuteDeleteAsync&#8221; olmak \u00fczere iki yeni method getirilmi\u015f. Bu method&#8217;lar\u0131 kullanarak istedi\u011fimiz <em>LINQ<\/em> ile bulk i\u015flemler ger\u00e7ekle\u015ftirebilece\u011fiz.<\/p>\n<pre>await context.Tags.Where(t =&gt; t.Posts.All(e =&gt; e.PublishedOn &lt; priorToDateTime)).ExecuteDeleteAsync(); await context.Tags .Where(t =&gt; t.Posts.All(e =&gt; e.PublishedOn &lt; priorToDateTime)) .ExecuteUpdateAsync(s =&gt; s.SetProperty(t =&gt; t.Text, t =&gt; t.Text + \" (old)\"));\r\n<\/pre>\n<p>Bu tarz bulk i\u015flemleri ger\u00e7ekle\u015ftirebilmek i\u00e7in farkl\u0131 <em>EF<\/em> extension&#8217;lar\u0131 kullanmak yerine, <em>EF<\/em> i\u00e7erisine getirilmi\u015f olmalar\u0131 gayet tatl\u0131 olmu\u015f.<\/p>\n<h2>Rate-Limiting Middleware<\/h2>\n<p>Son olarak da <em>ASP.NET Core<\/em> taraf\u0131nda getirilen &#8220;Rate-Limiting&#8221; middleware&#8217;inden bahsetmek istiyorum.<\/p>\n<p>Bildi\u011fimiz gibi geli\u015ftirmi\u015f oldu\u011fumuz <em>API<\/em> &#8216;lar\u0131n rate-limiting&#8217;e sahip olmas\u0131 asl\u0131nda \u00f6nemli bir konu. \u00c7\u00fcnk\u00fc hem geli\u015ftirmi\u015f oldu\u011fumuz <em>API<\/em> &#8216;\u0131n <strong>overwhelm<\/strong> olup performans\u0131n\u0131n azalmamas\u0131n\u0131 hem de <strong>DoS<\/strong> gibi sald\u0131r\u0131lara kar\u015f\u0131 bir \u00e7e\u015fit g\u00fcvenlik mekanizmas\u0131na sahip olabilmemizi sa\u011flamaktad\u0131r. Elbette \u00f6zellikle public <em>API<\/em> &#8216;lar geli\u015ftiriyorsak.<\/p>\n<p>Kullan\u0131m\u0131 olduk\u00e7a basit bir middleware ve &#8220;Fixed window&#8221;, &#8220;Sliding window&#8221;, &#8220;Token bucket&#8221; ve &#8220;Concurrency&#8221; olmak \u00fczere 4 farkl\u0131 rate-limiting policy&#8217;si ile gelmektedir. \u0130stedi\u011fimiz endpoint seviyesinde de attach edebiliyoruz.<\/p>\n<pre>var builder = WebApplication.CreateBuilder(args);\r\n\r\nbuilder.Services.AddRateLimiter(rateLimitingoptions =&gt;\r\n    rateLimitingoptions.AddFixedWindowLimiter(policyName: \"fixed\", options =&gt;\r\n    {\r\n        options.PermitLimit = 100;\r\n        options.Window = TimeSpan.FromSeconds(10);\r\n        options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;\r\n        options.QueueLimit = 2;\r\n    }));<\/pre>\n<p>\u00d6rne\u011fin yukar\u0131daki gibi bir &#8220;Fixed window&#8221; policy, &#8220;10&#8221; saniyelik window&#8217;lar i\u00e7erisinde maksimum &#8220;100&#8221; request&#8217;e izin vermektedir.<\/p>\n<p>Daha sonra ise istedi\u011fimiz seviyede aktif veya pasif bir hale getirebilmekteyiz.<\/p>\n<pre>app.MapControllers().RequireRateLimiting(\"fixed\");<\/pre>\n<pre>[ApiController]\r\n[Route(\"[controller]\")]\r\n[EnableRateLimiting(\"fixed\")]\r\npublic class WeatherForecastController : ControllerBase\r\n{\r\n    private readonly IMemoryCache _memoryCache;\r\n\r\n    public WeatherForecastController(IMemoryCache memoryCache)\r\n    {\r\n        _memoryCache = memoryCache;\r\n    }\r\n\r\n    [HttpGet(\"stats\")]\r\n    [DisableRateLimiting]\r\n    public ActionResult&lt;MemoryCacheStatistics&gt; GetStats()\r\n    {\r\n        return Ok(_memoryCache.GetCurrentStatistics());\r\n    }\r\n}\r\n<\/pre>\n<h2>Toparlayal\u0131m<\/h2>\n<p>Bu makale kapsam\u0131nda ilk bak\u0131\u015fta ho\u015fuma giden baz\u0131 yeniliklerden bahsetmeye \u00e7al\u0131\u015ft\u0131m. Bu release de beni \u015fa\u015f\u0131rtmad\u0131 \u00e7\u00fcnk\u00fc her bir release i\u00e7erisinde ger\u00e7ekten harika yenilikler ve performans iyile\u015ftirmeleri ger\u00e7ekle\u015ftiriliyor. Harika bir i\u015f k\u0131sacas\u0131!<\/p>\n<p>\u00d6zellikle <em>CLR<\/em> taraf\u0131nda yap\u0131lan iyile\u015ftirmeler, ger\u00e7ekten harika bir i\u015f. Ayr\u0131ca <em>Native AOT<\/em> konusunun da nerelere gidece\u011fini olduk\u00e7a merak etmekteyim. Tabi bunlar\u0131n yan\u0131nda burada de\u011finmedi\u011fim bir \u00e7ok farkl\u0131 yeni \u00f6zellikler eklendi ve iyile\u015ftirmeler de ger\u00e7ekle\u015ftirildi. \u00d6rne\u011fin <strong>loop<\/strong> ve <strong>reflection<\/strong> performans optimizasyonlar\u0131, yeni eklenen <strong>Archive Tar API<\/strong>&#8216;\u0131 gibi bir \u00e7ok farkl\u0131 yenilikler ve iyile\u015ftirmeler de mevcut.<\/p>\n<p>E\u011fer sizlerinde be\u011fendi\u011fi farkl\u0131 noktalar varsa, yorumlar\u0131n\u0131z\u0131 bekliyorum.<\/p>\n<h2>Referanslar<\/h2>\n<blockquote><p><a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-dotnet-7?WT.mc_id=DT-MVP-5003382\">https:\/\/devblogs.microsoft.com\/dotnet\/announcing-dotnet-7<\/a><br \/>\n<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/performance_improvements_in_net_7?WT.mc_id=DT-MVP-5003382\">https:\/\/devblogs.microsoft.com\/dotnet\/performance_improvements_in_net_7<\/a><br \/>\n<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/announcing-builtin-container-support-for-the-dotnet-sdk?WT.mc_id=DT-MVP-5003382\">https:\/\/devblogs.microsoft.com\/dotnet\/announcing-builtin-container-support-for-the-dotnet-sdk<\/a><br \/>\n<a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/whats-new-in-orleans-7?WT.mc_id=DT-MVP-5003382\">https:\/\/devblogs.microsoft.com\/dotnet\/whats-new-in-orleans-7<\/a><br \/>\n<a href=\"https:\/\/learn.microsoft.com\/en-gb\/aspnet\/core\/performance\/rate-limit?view=aspnetcore-7.0&amp;WT.mc_id=DT-MVP-5003382\">https:\/\/learn.microsoft.com\/en-gb\/aspnet\/core\/performance\/rate-limit?view=aspnetcore-7.0<\/a><\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Bildi\u011fimiz gibi .NET Conf 2022, 8-10 kas\u0131m aras\u0131nda ger\u00e7ekle\u015fti. Konferans s\u0131ras\u0131nda ise .NET 7 ve C# 11 \u00e7evresinde gelen heyecan verici yeniliklerden ve performans iyile\u015ftirmelerinden bahsedildi. Bu release de \u00f6zellikle biz developer&#8217;lar\u0131n daha &#8220;h\u0131zl\u0131&#8221;, &#8220;lightweight&#8221; ve daha kolay &#8220;cloud-native&#8221; application&#8217;lar geli\u015ftirebilmesi gibi harika konulara odaklan\u0131lm\u0131\u015f.&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/gokhan-gokalp.com\/tr\/some-awesome-news-of-net-7\/\">Devam\u0131n\u0131 okuyun<span class=\"screen-reader-text\">.NET 7 ile Gelen Baz\u0131 Harika Yenilikler<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":4238,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,505,417,434,457],"tags":[652,655,656,657,653,322,658,654],"class_list":["post-4213","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net","category-net-core","category-asp-net-core","category-containerizing","category-dotnet","tag-net-7","tag-net-conf","tag-net-conf-2022","tag-c-11","tag-clr","tag-docker","tag-native-aot","tag-runtime","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"tr","enabled_languages":["en","tr"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"tr":{"title":true,"content":true,"excerpt":false}}},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>.NET 7 ile Gelen Baz\u0131 Harika Yenilikler - G\u00f6khan G\u00f6kalp<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\".NET 7 ile Gelen Baz\u0131 Harika Yenilikler - G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/\" \/>\n<meta property=\"og:site_name\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta property=\"article:published_time\" content=\"2022-11-16T12:52:42+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-11-18T22:13:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/gokhan-gokalp.com-dotnet-7-news.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"675\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"G\u00f6khan G\u00f6kalp\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"25 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/\"},\"author\":{\"name\":\"G\u00f6khan G\u00f6kalp\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"headline\":\".NET 7 ile Gelen Baz\u0131 Harika Yenilikler\",\"datePublished\":\"2022-11-16T12:52:42+00:00\",\"dateModified\":\"2022-11-18T22:13:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/\"},\"wordCount\":4308,\"commentCount\":5,\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/gokhan-gokalp.com-dotnet-7-news.jpg\",\"keywords\":[\".net 7\",\".net conf\",\".net conf 2022\",\"C# 11\",\"clr\",\"docker\",\"native aot\",\"runtime\"],\"articleSection\":[\".NET\",\".NET Core\",\"ASP.NET Core\",\"Containerizing\",\"dotnet\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/\",\"name\":\".NET 7 ile Gelen Baz\u0131 Harika Yenilikler - G\u00f6khan G\u00f6kalp\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/gokhan-gokalp.com-dotnet-7-news.jpg\",\"datePublished\":\"2022-11-16T12:52:42+00:00\",\"dateModified\":\"2022-11-18T22:13:36+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/#primaryimage\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/gokhan-gokalp.com-dotnet-7-news.jpg\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/gokhan-gokalp.com-dotnet-7-news.jpg\",\"width\":1200,\"height\":675},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/some-awesome-news-of-net-7\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Some Awesome News of .NET 7\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#website\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"description\":\"C# &amp; Python lover\",\"publisher\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/gokhan-gokalp.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/#\\\/schema\\\/person\\\/7e2a7fa98babd22a5fdae563c4b8cdbe\",\"name\":\"G\u00f6khan G\u00f6kalp\",\"pronouns\":\"he\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776775506\",\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776775506\",\"contentUrl\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776775506\",\"caption\":\"G\u00f6khan G\u00f6kalp\"},\"logo\":{\"@id\":\"https:\\\/\\\/gokhan-gokalp.com\\\/wp-content\\\/litespeed\\\/avatar\\\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776775506\"},\"sameAs\":[\"https:\\\/\\\/gokhan-gokalp.com\"],\"url\":\"https:\\\/\\\/gokhan-gokalp.com\\\/tr\\\/author\\\/gok-gokalp\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":".NET 7 ile Gelen Baz\u0131 Harika Yenilikler - G\u00f6khan G\u00f6kalp","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/","og_locale":"tr_TR","og_type":"article","og_title":".NET 7 ile Gelen Baz\u0131 Harika Yenilikler - G\u00f6khan G\u00f6kalp","og_url":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/","og_site_name":"G\u00f6khan G\u00f6kalp","article_published_time":"2022-11-16T12:52:42+00:00","article_modified_time":"2022-11-18T22:13:36+00:00","og_image":[{"width":1200,"height":675,"url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/gokhan-gokalp.com-dotnet-7-news.jpg","type":"image\/jpeg"}],"author":"G\u00f6khan G\u00f6kalp","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"G\u00f6khan G\u00f6kalp","Tahmini okuma s\u00fcresi":"25 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/#article","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/"},"author":{"name":"G\u00f6khan G\u00f6kalp","@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"headline":".NET 7 ile Gelen Baz\u0131 Harika Yenilikler","datePublished":"2022-11-16T12:52:42+00:00","dateModified":"2022-11-18T22:13:36+00:00","mainEntityOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/"},"wordCount":4308,"commentCount":5,"publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/gokhan-gokalp.com-dotnet-7-news.jpg","keywords":[".net 7",".net conf",".net conf 2022","C# 11","clr","docker","native aot","runtime"],"articleSection":[".NET",".NET Core","ASP.NET Core","Containerizing","dotnet"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/","url":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/","name":".NET 7 ile Gelen Baz\u0131 Harika Yenilikler - G\u00f6khan G\u00f6kalp","isPartOf":{"@id":"https:\/\/gokhan-gokalp.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/#primaryimage"},"image":{"@id":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/#primaryimage"},"thumbnailUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/gokhan-gokalp.com-dotnet-7-news.jpg","datePublished":"2022-11-16T12:52:42+00:00","dateModified":"2022-11-18T22:13:36+00:00","breadcrumb":{"@id":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/"]}]},{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/#primaryimage","url":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/gokhan-gokalp.com-dotnet-7-news.jpg","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/uploads\/2022\/11\/gokhan-gokalp.com-dotnet-7-news.jpg","width":1200,"height":675},{"@type":"BreadcrumbList","@id":"https:\/\/gokhan-gokalp.com\/some-awesome-news-of-net-7\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gokhan-gokalp.com\/"},{"@type":"ListItem","position":2,"name":"Some Awesome News of .NET 7"}]},{"@type":"WebSite","@id":"https:\/\/gokhan-gokalp.com\/#website","url":"https:\/\/gokhan-gokalp.com\/","name":"G\u00f6khan G\u00f6kalp","description":"C# &amp; Python lover","publisher":{"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gokhan-gokalp.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/gokhan-gokalp.com\/#\/schema\/person\/7e2a7fa98babd22a5fdae563c4b8cdbe","name":"G\u00f6khan G\u00f6kalp","pronouns":"he","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776775506","url":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776775506","contentUrl":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776775506","caption":"G\u00f6khan G\u00f6kalp"},"logo":{"@id":"https:\/\/gokhan-gokalp.com\/wp-content\/litespeed\/avatar\/e645f66b6264ced10d7b6d8b1f85509b.jpg?ver=1776775506"},"sameAs":["https:\/\/gokhan-gokalp.com"],"url":"https:\/\/gokhan-gokalp.com\/tr\/author\/gok-gokalp\/"}]}},"_links":{"self":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/4213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/comments?post=4213"}],"version-history":[{"count":29,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/4213\/revisions"}],"predecessor-version":[{"id":4249,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/posts\/4213\/revisions\/4249"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media\/4238"}],"wp:attachment":[{"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/media?parent=4213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/categories?post=4213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gokhan-gokalp.com\/tr\/wp-json\/wp\/v2\/tags?post=4213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}