
Asp.Net Core 2.0’a Giriş – Bölüm 1 (NewProject, Solution Structure, Solution File hakkında)
Selamlar. Bu yazı serimizde AspNet Core’a bir girizgah yapacağız. Basit bir örnekle biraz yüzeysel olarak AspNet Core‘a aşina olmuş, AspnetCore tarafında kod yazmaya başlayarak işin daha derinine inmeden önce biraz ellerimizi ısıtmış, AspnetCore tarafında biraz teorik bilgi sahibi olmuş olmak bu yazı serisinin temel amacı olacak. Sonraki yazılarda kısım kısım daha teknik detaylara girmeye çalışacağım.
Bu seri ve sonraki tüm yazılarda Visual Studio 2017 kullanacağım. Bu yüzden herhangi birşeye başlamadan önce, daha sağlık ilerlemek adına Visual Studio 2017 yi ve Asp.Net Core 2‘yi download edip pc nize yüklerseniz sorunsuz bir şekilde blogları takip edebilirsiniz.
- .NetCore un engüncel SDK sını şuradan indirebilirsiniz. Sadece SDK yı indirip kurmanız yeterli olucaktır, zaten Core Runtime, SDK içerisinde gelecek.
- Visual Studio 2017 yi download etmek ve kurulum ile ilgili detaylı bilgi almak için buradan faydalanabilirsiniz.
Asp.Net Core Microsoft tarafından en baştan geliştirildi. Bizde şimdi Visual Studio 2017 mizi açıp sıfırdan bir Asp.Net Core projesi oluşturalım ve her şeye sıfırdan bakıp anlamaya çalışalım.
Klasik olarak başlangıç noktamız File -> New Project seçtikten sonra, ister VisualC# altından, ister .NetCore altından isterseniz de Web sekmeleri altında Asp.Net Core Web Application proje tipini seçip, projemize bir isim verdikten sonra Template seçme adımına geliyoruz.
Yukarıdaki gibi projemizin tipini seçip, ismini verip, pc de saklayacağımızı yeri belirledikten sonra aşağıdaki Template seçme adımına geliyoruz. Herşeye sıfırdan bakmak istediğimiz için WebApplication veya WebApplication (Model-View-Controller) gibi birçok hazır dosya ve kodlar ile gelen template i değil de Empty template i seçerek yolumuza devam edelim.
Empty Template i seçip, herhangi bir authentication mekanizması seçmeden projemizi oluşturuyoruz. Şu ana kadar yaptımız tüm bu adımları Visual Studio yerine .NetCore CLI‘dan da yapmak mümkün biliyorsunuz. Ama CLI(Command Line Interface) detaylarına sonra gireceğiz. Yine de basitçe CLI dan nasıl proje oluşturulup, birbirine referans verilip, çalıştırılır abakmak isterseniz, önceki yazımda anlanttığım, .NetStandard 2.0 proje oluşturup bir Web app den kullanma örneği yaptığım yazıma bakabilirsiniz.
Peki, projemizi oluşturduk gelelim Solution Structer ın nasıl değiştiğine, düzenlendiğine. Yeni ve sıfırdan oluşturduğumuz projemizin structure ı aşağıdaki gibi görünüyor.
Eğer daha önceki .NetCore versiyonları ile çalıştıysanız, ilk fark edeceğiniz şey project.json doyasının artık olmadığı. Bunun sebebi bu dosyanın MSBuild ile uyumlu çalışmaması, ve MSBuild in birçok DevOps Environment‘ı tarafından kullanılıyor olması. Bunun yerine artık doğrudan, hiç projeyi unload etmeden, csproj (VB ile yazıyorsanız vbproj) dosyasını editleyebiliyor olmamız. proje dosyası (csproj-vbproj) herhangi bir folder veya file referansı içermiyor artık. Solution File Explorer da açıp içerisi boş bir txt dosyası ekleyelim ve bakalım ne olacak.
Gördüğünüz gibi proje klasörüne eklenen text dosyası doğrudan proje içerisine included edilmiş şekliyle geldi. Bunun sebebi Asp.Net Core, Solution Explorer ın pc deki Disk ile birebir map lenmiş olması. Yani bir dosyayı projeye eklemek istediğimizde doğrudan Solution klasörüne atmak artık yeterli, Folder veya File referansları ile alakamız yok. Bu da aslında bir Source Control mekinizması kullanırken ki sıkça karşımıza çıkan, projeye yeni bir şeyler eklendiğinde, ilgili klasörün folder-file referanslarının da projeye eklenmesi yüzünden yaşadığımız conflict lerden bizi kurtarıyor.
Birde proje dosyamızın içine bakalım.
görmüş olduğunuz gibi proje dosyası gayet net ve temiz. En üstte projeyi oluştururken seçmiş olduğumuz Asp.Net Core framework ünün takma ismi (tüm platformların kendi takma ismi var, ör: netstandard2.0, netcoreapp2.1, net461, net471 vb..)
Bir sonraki Item a bakalım. wwwroot klasörü. Classic AspNet projelerinde Root Folder daki tüm dosyalar sunulmaya hazır halde olurdu. Browserdan ilgili folder ve file a gittiğinizde eğer o dosyaı Blacklist e alıp blocklamadıysak, WebConfig, Global.asax gibi hassas dosyalarda browserdan ulaşılabilir oluyordu.
Asp.Net Core da ise bu Blacklisting bakış açısı değişti ve WhiteListing e döndü. Artık bu wwwroot klasörü altında olmayan hiçbir şey doğrudan ulaşılmaz halde. Css, Javascript dosyaları, resimler gibi, browser ın ulaşması gerken tüm dosyalarımı koyacağımız yeni yer artık bu wwwroot klasörü olacak. Proje klasörüne gidip wwwroot ltında img diye bir klasör oluşturup içine bir adet resim atalım.
Solution kalsöründe wwwroot altında img klasörümüz ve içerisindeki resim anında Solution Explorer da görünür oldu. Şimdi bunu browserdan test etmek için projeyi çalıştıralım. Ama şöyle ekstra bir adım atmamı lazım, Sıfırdan bir template dosyası oluşturduğumuz için, Startup.cs içerisinde nerdeyse hiçbir built-in gelen middleware eklenmemiş halde. Startup dosyasından, Middleware yapısından ilerde detaylıca bahsedeceğiz ama şuan bu projeye eklediğimiz resmi görmemiz için Startup.cs doyasına gidip, Configure metodunun içerisine şu satırı eklememiz gerekiyor.
app.UseStaticFiles();
Şimdi Browserdan ilgili klasöre gidelim ve resim karşımızda.
Peki proje dosyasındaki son item a bakalım.
<PackageReference Include=”Microsoft.AspNetCore.App” />
Normalde bir projeye nuget ten bir paket indirdiğinizde referansı buraya eklenirdi. Asp.Net Core 1.0 dan da hatırlarsanız, herbir paket ayrı ayrı projeye indiriliyordu, bu ilk başta güzel gibi gözüksede sonradan sorun çıkarmaya başladığı görüldü. Bu yüzden artık yeni bir proje oluşturduğunuzda içeriye versiyon numarası olmayan bu paket yükleniyor. Versiyon numarası yok çünkü siz .makinanızda NetCore her update ettiğinizde bu paket te güncelleniyor.
Microsoft.AspNetCore.App paketinde neler var?
- Asp.Net Core un kullandığı tüm paketler
- Entity Framework Core a ait paketler
- Asp.Net Core ve Entity Framework Core un kullandığı tüm 3rd party paketler
Dolasyısı ile projenize neredeyse başka paket eklemeden geliştirmeye başlamaya hazırsınız. Peki bu kadar paket deploy zamanı ne oluyor? 🙂 Tabii ki bunu da düşünmüşler, yeni .NetCore Runtime Store fetarure ile kullanılmayan paketler deploy edilmeden ayıklanıyor.
Bu yazıyı burada tamamlayalım ve bir sonraki yazımızda, Program.cs ve Startup.cs dosyalarından devam edelim. Yeni bir Asp.Net Core Web Application nasıl oluşur ve Solution structer ı nasıldır öğrenmiş olduk. Serinin diğer yazılarında biraz daha aktif kod yazmaya başlayıp, yine biraz teoriğe değineceğiz.
Bir sonraki yazımda görüşmek üzere.

NetStandard nedir? .NetCore, .NetFramework ve diğer .Net Platformları ile ilişkisi nasıl? (Bölüm 3)
Selamlar, .NetStandard ile ilgili örnek yapıp bir de developer gözünden bir metafor ile netstandard a bakıp bu seriyi sonlandıracağım yazıma hoşgeldiniz. Önceki yazıları bundan önce okumanızda fayda var. Bölüm1 ve Bölüm2 den sonra buraya devam ederseniz daha tatmin edici olacaktır sizin için 🙂
Önce şu bahsettiğim ve aslında şurada yazılmış olan ve çok hoşuma giden matefordan bahsedelim 🙂 Bir developer için .NetStandard ın, tüm .NetPlatformlarının implemente etmesi gereken API lar bütünü olduğundan bahsetmiştik. Yan, bu durumda her bir .NetStandard versiyonunu bir interface, her bir .Net Platformunu da bir concerete class olarak düşünmek yanlış olmaz 🙂
Bu durumda da aslında şöyle bir .cs dosyası ile tüm NetStandard versiyonlarını ve onu implemente eden platformları yazabiliriz.
Önce .NetStandard ı görelim;
// .NET Standard interface INetStandard10 { void Primitives(); void Reflection(); void Tasks(); void Collections(); void Linq(); } interface INetStandard11 : INetStandard10 { void ConcurrentCollections(); void EventSource(); void InteropServices(); } interface INetStandard12 : INetStandard11 { void ThreadingTimer(); } interface INetStandard13 : INetStandard12 { void AppContext(); void Console(); void StringInterpolation(); void Calendars(); void FileSystem(); void Sockets(); void AsyncLocal(); } interface INetStandard14 : INetStandard13 { void CryptoECDsa(); } interface INetStandard15 : INetStandard14 { void EventCounter(); } interface INetStandard16 : INetStandard15 { void LinqInterpretation(); void CryptoECCurve(); void PrecompiledRegex(); } interface INetStandard20 : INetStandard16 { void EverythingThatIsInNetFrameworkAndXamarin(); }
yukarıda gördüğünüz ve daha önce söylediğimiz gibi, .NetStandard versiyonları PCL den farkli olarak lineer bir şekilde gidiyor. Her bir versiyonda da, platformların implemente etmesi gerektiğini düşündükleri (required olarak label ladıkları API ları görüyorsunuz)
Peki birde .NetFramework ve .NetCore implementasyonlarına bakalım;
// .NET Framework class NetFramework45 : INetStandard11 { // ... } class NetFramework451 : NetFramework45, INetStandard12 { // ... } class NetFramework452 : NetFramework451 { // ... } class NetFramework46 : NetFramework452, INetStandard13 { // ... } class NetFramework461 : NetFramework46, INetStandard20 { // ... } class NetFramework462 : NetFramework461 { // ... } class NetFramework47 : NetFramework462 { // ... } class NetFramework471 : NetFramework47 { // ... } // .NET Core class NetCore10 : INetStandard16 { // ... } class NetCore11 : NetCore10 { // ... } class NetCore20 : NetCore11, INetStandard20 { // ... }
Burada da, kolayca .NetStandard 2.0 ın Framework 4.6.1 tarafından tamamen implemente edildiğini, aynı şekilde .NetCore1.0 ın NetStandard 1.6 yı implemente ettiğini, .NetCore 2.0 ın da .NetStandard 2.0 ı tamamen implemente ettiğini görüyorsunuz:)
Bir yazılımcı için anlaşılması çok daha kolay oldu değil mi 🙂
Bir de .NetCore CLI kullanarak küçük bir örnek yapalım, Visual Studio 2017 den sonra zaten bunu IDE üzerinden yapmayı göstermenin bir lüzumu yok 🙂 . Hem Cross Platform Command Line Interface i biraz kullanmış tanımış oluruz, hemde hakkında bu kadar yazdığımız .NetStandard ı bir de kod tarafından görmüş oluruz.
Öncelikle Windows tarafında Command Prompt u, Mac tarafında da ise Terminal i açıyoruz. Windows tarafı ile Mac tarafında hiçbir kod farklı olmadığı, yazanları iki tarafta da rahatça deneyebilirsiniz.
İlk olarak aşağıdaki kodu çalıştırarak yeni bir class library projesi oluşturuyoruz. bu proje otomatik olarak .NetStandard olarak oluşacaktır.
$ dotnet new classlib -o mystandardlibrary
bu şekilde bir standard class library projesi oluşturmuş olduk. Şimdi Class1 in içeriğini değiştirip basit bir static metod koyalım.
using System; namespace mystandardlibrary { public class Class1 { public static string GetMessage() => "Hello from .NET Standard!"; } }
Şimdi aşağıdaki komut satırını çalıştırarak yeni bir aspnet core projesi oluşturalım. web keyword ü ile default bir aspnet core projesi oluşacak.
$ dotnet new web -o aspnetcoreclient
Oluşturmuş olduğumuz web projesine, class library projesini referans olarak verelim.
$ dotnet add reference ../mystandardlibrary/mystandardlibrary.csproj
Şimdi de son olarak, web projesindeki Startup.cs dosyasında bulunan inline yazılmış ve gelen request e direk cevap veren tek middleware kodunu edit leyip, aşağıdaki gibi, standard class librarydeki metodumuzu kullanacak şekilde düzenleyelim.
app.Run(async (context) => { var message = mystandardlibrary.Class1.GetMessage(); await context.Response.WriteAsync(message); });
Son olarak, web projesi içerisindeyken önce “dotnet build” projemizi derleyip, sonrada aşağıdaki komut satırını çalıştırarak web projesini ayağa kaldıralım.
$ dotnet run
resimde görmüş olduğunuz gibi http ve https portları üzerinde sitemiz 5000 ve 5001 portlarında ayağa kalktı. Browser ımızı açıp http://localhost:5000 adresine gidersek aşağıdaki gibi, web projemizin, NetStandard kütüphanemizdeki kodu çalıştırdığını göreceğiz.
Birkaç satır kod ile, tüm .Net Platformlarında kullanabileğimiz .NetStandard2.0 kütüphanemizi oluştumuş ve bir aspnet core projesinde kullanmış olduk. 🙂 Bu 3 yazılık seri de, Genel olarak kod paylaşımını, NetStandard ı ve onun diğer .Net platformlar ile olan ilişkisini anlatmaya çalıştım.Umarım keyif almışsınızdır.
.Net Core ile ilgili detaylı yazı serilerinde görüşmek üzere,

NetStandard nedir? .NetCore, .NetFramework ve diğer .Net Platformları ile ilişkisi nasıl? (Bölüm 2)
Selamlar, bir önceki yazımda anlatmaya başladığım .NetStandard hakkında bilgiler vermeye devam edeceğim bu yazımdan önce, eğer okumadıysanız 1.Bölüm‘ü okumanızda fayda var.
Önceki yazıyı, buradaki kaynaktan aldığım resimle bir özetleyelim 🙂
Resimde de görüldüğü gibi .NetStandard, birbirinden farklı .Net platformlarında ortak kod paylaşımı yazmayı kolaylaştırmak için tüm platformların uyması gereken bir standard getirerek .Net Platformlarını birleştirmek ve ileride farklı platformların da doğmasıyla çıkabilecek başka sorunlara da çözüm olmak amacı ile ortaya çıktı.
Bu yazımıza biraz daha soru cevap şeklinde devam edeceğim. Farklı sorularınız olursa yorum yazmaktan çekinmeyiniz.
Kütüphane yazarken hangi .NetStandard versiyonunu seçmeliyim?
Aslında bu sorunun cevabı çok net. .NetStandard yerine geçtiği PCL aksine lineer olarak versiyonlanıyor. Yani daha yüksek versiyon demek daha fazla ortak API kullanımı, ve eski .NetStandard versiyonlarına destek demek. Bu yüzden yeni oluşturacağınız Class Library leriniz için bügünden itibaren .NetStandard 2.0 seçmeniz en mantıklısı olacaktır.
Bununla beraber şunu da söylemekte fayda var, .NetStandard versiyonları immutable olarak sunuluyor. Yani bir versiyon release olduğunda ona artık dokunulmuyor. Yeni bir versiyonda olması planlanan API lar önce platform spesifik ortamlarda implemente ediliyor (örneğin .NET Core). Eğer ekip bu API ın tüm platformarda olması gerektiğine karar verirse yeni .NetStandard versiyonuna bu API ekleniyor. Yani geçmişle uyumsuzluk yok, ve hangi API ların .NetStandard a ekleneceği çok dikkatlice seçiliyor.
Peki bu .NetStandard da neler olacağına kimler karar veriyor?
Hemen akla gelen ilk isim doğru tabii, Microsoft 🙂 Önemli .Net Plarformlarının(NET Framework, .NET Core, ve Mono) implemente eden firma olarak Microsoft başta olmak üzere, Unity asıl rol oynuyır diyebiliriz. Eğer isterseniz sizlerde buradan bu sürece katılabilir, fikirlerinizi söyleyebilirsiniz. Belki önereceğiniz bir API bir sonraki versiyonda hayatımıza girecektir =)
.NetStandard 2.0 ile gelen .NET Framework Uyumluluk modu nedir?
Bu uyumluluk modu sayesinde bir .NetStandard class library projenize, .NetFramework library sini, sanki .NetStandard 2.0 için derlenmiş gibi ekleyebilirsiniz. Fakat tahmin edeceğiniz üzere her API çalışmayacaktır. Örneğin, WPF için yazılmış bir API ı, .NetStandard projenize elediğinizde, onu Xamarin vs için kullanamayacaksınız. Peki bu şekilde çalışması kesin olmayan bir API eklediğinizi nasıl anlayacaksınız?
bu itici ünlem işareti ve uyarısı tanıdık geldi mi? 🙂 İşte bu uyarı Visual Studio size şunu söylüyor;
- Ben istediğin paketi, sanki NetStandard için derlenmiş gibi projeye eklemeye çalıştım fakat, bu pkaetteki her API buna uyumlu değil. Bu yüzden bunu en uyumlu kullanabileceğin versiyon ile restore ettim. Eğer sorun yaşamazsan ne ala, yaşarsan günah benden gitti 🙂
diyor. Eğer gerçekten sorun yaşamaz, eklediğiniz API ın düzgün çalıştığını görürseniz. bu mesajı her derlemede görmemek için şunu yapabilirsiniz. Proje dosyasını açarak aşağıdaki gibi ilgili paketin ve versiyonunun adını yazarak bu uyarıdan kurtulabilirsiniz.
<ItemGroup> <PackageReference Include="XXX" Version="XXX" NoWarn="NU1701" /> </ItemGroup>
Ben tam olarak neden PCL yerine .NetStandard kullanayım anlamadım
Diyecek olanınız var ise şöyle diyeyim;
Evet ikisininde nihai amacı aynı, ortak binary kod paylaşımı sağlamak. Ama arada ciddi farkları var.
- .NetStandard a eklenecek API lar özenle seçilip, önce platform spesifik taraflarda implemente edilip sonrada tüm platformlarda olup lmadığına karar veriliyor. PCL ise sadece farklı platformlar için kullanılan BCL lerdeki ortak API ları alıyor. Bir nevi sadece kesişim kümesini alıp çekiliyor aradan.
- .NetStandard da emin olabilirsiniz ki, yeni bir versiyon ile geride kalan tüm versiyonları desteklersiniz. Lineer bir versiyonlama vardır. Ama PCL bu şekilde çalışmıyor.
- Belkide en önemli fark şu ki; PCL Microsoft bağımlı iken, .NetStandard platform-agnostic. Hatta bir adım ötesi, Microsoft a özel olmamakla beraber .NetStandard aynı zamanda C# bağımsız. Herhangi bir language-spesific api bulunmuyor ve eklenmesi de düşünülmüyr henüz. Aslında zaten doğasında bu var, böyle olmak zorunda çünkü artık .Net platformları hemen hemen her yerde çalışıyor =)
.NetStandard ile destekleyebileceğim maksimum .Net Framework versiyonu nedir?
Şu an için 2.0 ile beraber Framework 4.6.1 i full kullanabiliyor olucaksınız.
.NetStandard a eklenecek API lara nasıl karar veriliyor?
Bunun için öncelikle Hem .NetFramework tarafında hem de Xamarin tarafında çalışan API lar göz önünde bulunduruluyor. Bu aşamadan sonra API ları required veya optional ikiye ayırıyorlar. Required olanlar tamamen implemente edilmeye çalışılırken optional olanlar ayrı nuget paketleri halinde .NetStandard için uyumlu olucak şekilde derlenmeye çalışılıyor. Fakat nuget paketi olarak gelen her API ın her fonksiyonunun çalışma garantisi yok daha önce belirttiğim gibi.
Peki Platform spesifik API ların ne olacağına nasıl karar veriyorlar?
Tüm platformlarda çalışacak API lar yazmaya çalışılırlen karşılaşılan en büyük sorunlardan biri de, Platform spesifik API lar ile ilgili nasıl ilerleneceği. Bu tür API lara örnek olarak;
- Runtime Spesific API lar
- Operating System Spesific API lar
Runtime spesifikler için reflection ile, runtime da kod oluşturup çalıştırmayı düşünebiliriz. Ama iOS buna izin vermiyor mesela, yada JIT compiler a sahip olmayan Windows platformları da bunu yapamayacak. Windows Registry de OS Spesifik olarak düşünebiliriz.
Peki siz olsanız bu durumda nasıl karar verirdiniz? Olasılıkları düşünelim
- İlgili API ı direk Unavailable yapmak
- .NetStandard a yine de eklemek ama desteklenmeyen platformlarda hata fırlatmak
- API simüle etmek 🙂
3. maddeye örnek olarak şunu söylebiliriz. Mono Registry API implementasyonu .ini dosyaları üzerinden yapıyor. Bu sayede uygulama kendi state i ile ilgili bilgileri registry de saklayabiliyor, fakat kendi dışında, mesela işletim sistemi ile ilgili bilgileri oradan okuyamıyor.
.NetStandard ekibi de sizin gibi düşünmüş olacak ki, hepsinin karışımı bir yol izlemek istiyorlar 🙂 Öncelikle .NetStandard’a sadece her platformda çalışacak API ları ekliyorlar, sonrasında popüler olanları ayrı nuget paketleri halinde .NetStandard ın üzerinde oturacak şekilde nuget e koyuyorlar(Tekrar belirtelim her fonksiyon çalışmayabilir). Bu kendi halinde ayrıştırılabilen ve kendi kendine yeten paketler için güzel çalışan bir yöntem. Fakat API ın tamamı bu şekilde değilse, 2. yada 3. yolu izliyorlar.
Peki gelelim esas sorulardan birine 🙂
.NetCore ile .NetStandard arasındaki bağ nedir?
.NetCore diğer .Net Platformlarına kıyasla en az API sayısına sahip ve en yavaş, dikkatli geliştirilmesi gereken bir framework. Sebebi belli, NetStandard ın tüm .Net Platformalarında çalışması istendiği gibi, .Net Core un da, neredeyse tüm OS, ve mimari seviyelerde çalışabilmesi isteniyor. Ortaya çıkış amacı bu zaten. Windows/IIS vs. bağımlılığın ortadan kalktığı her ortamda çalışabilen bir ürün olması. Ama runtime, OS level vb farklılıklar için ortak kod yazmak .NetStandard ın geliştirilmesi gibi hızlı gitmiyor. .NetStandard ın her bir versiyonunun immutable olduğundan söz etmiştik. Ve nasıl API ların seçildiği. Her bir platform kendine özgü API ları eklerken bir yandan da hangilerinin universal olabileceklerine karar veriyorlardı.
En nihayetinde durum .NetCore ve .NetStandard ı ayırmakla son buldu, çünkü tüm .net Platformlarında çalışacak olan API ları .NetCore tarafına ekleyip tüm işletim sistemi ve mimarilerde çalıştırmak mümkün olmuyordu.
Bu yüzden de .NetCore tarafından diğer platformlarda bulunan uyumluluk modunu kaldırdılar.
Artık NetCore bağımsız bir şekilde daha hızlı ilerliyor, ve yine gün sonunda core dahil olmak üzere ortak olması gerektiğini düşündükleri API ları, yeni .NetStandard versiyonlarına ekliyorlar.
.NetCore 2.0 tümüyle .NetStandard 2.0 uyumlu olduğundan, korkacak birşey aslında yok 🙂 Ama bu noktaya gelene kadar ki sürece bilmek te fayda olduğunuz düşünüyorum
Bir sonraki yazımda görüşmek üzere..

.NetStandard nedir? .NetCore, .NetFramework ve diğer .Net Platformları ile ilişkisi nasıl? (Bölüm 1)
Selamlar arkadaşlar. Bu yazımda .NetStandard ın ne olduğunu, çıkış amacını, .Net platformları arasında ne tür bir öneme sahip olduğunu anlatıp, birçok kişiden duyduğum “Ya şimdi bu .netcore çıktı, netstandard geldi, zaten netframework vardı, ne oluyor arkadaş, ben neyi nasıl kullanacağım?” şeklindeki kafa karışıklıklarını tamamen gidermeye çalışacağım. Ayrıca farklı .Net platformları arasındaki kod paylaşım tekniklerine değinip, .NetStandard’ın PCL(Portable Class Library)’den farkına da değineceğim.
Öncelikle şuradan başlayalım, farklı .NET platformları derken nelerden bahsediyoruz?
- .NET Core
- .NET Framework
- Mono
- Xamarin.iOS
- Xamarin.Android
- Xamarin.Mac
- Universal Windows Platform
- Windows
- Windows Phone
- Windows Phone Silverlight
- Unity
Evet aslında yukarıda ki listeye baktığımıza, artık bir kişinin “Ben .net developer’ım” demesiyle birlikte aslında ne kadar geniş çapta işler çıkartabileceğini görebiliriz 🙂 Birbirinden farklı ve güzel birçok platform mevcut. Oyun geliştirmek, iOS, Android ve WP ye native mobil uygulamalar yazmak, Web uygulamaları geliştirmek, Windows, Xbox, Console vs bir çok ihtiyaç için birçok uygulamayı .Net kullanarak geliştirebiliyoruz. Fakat bu yelpaze genişledikçe, Visual Studio daki Solution’lar büyüdükçe, Client’ların arayüz istekleri değiştikçe, ortaya çıkan en büyük soru şu oluyor
– Ben tüm projemde ortak olması gereken kodları nasıl paylaştıracağım?
Ortak olması gereken kodlar nelerdir biraz düşünelim;
- Application Services katmanı olabilir. Uygulamanın tüm business ihtiyacını yazacağımız katmanı ortak kullanılacak şekilde bir kere yazmak mantıklı olabilir.
- Ortak bir Data Acces Katmanı olabilir. Repository, UnitOfWork vs gibi pattern ler ile ihtiyacımıza göre düzenleyip yazdığımız, belki bir ORM (EntityFramework, NHibernate) veya mikro ORM (Dapper vs.) kullandığımız, ortak bir data access katmanı mantıklı olabilir.
- Ortak bir Networking Layer olabilir. Uygulamalarımız dış dünya ile haberleşirken, API’lar ile yapacakları haberleşmeleri ayrı ayrı yazmak istemeyiz. Tek bir yerde, kurallara uygun, düşünülmüş bir katman yazmak çok daha faydalı olacaktır.
- DTO (Data Transfer Object) – POCO (Plain Old CLR Objects) lar ortak bir yerde olabilir. Evet spesifik projeler içerisinde model şekilleri değişip, client’a özel modeller oluşturmak gerekebilir. Ama en nihayetinde DB’den çıkan entity leri Data Access den bir üst level a taşımamak mantıklı olucaktır. Bu yüzden ortak bir dto katmanı mantıklı olabilir.
- Bunların dışında Cross-Cutting-Concerns denilen, tüm uygulamalarda kullanılacak olan, Log, Security, Cache vb. gibi fonksiyonaliteleri bir abstraction olarak ortak bir yerde yazmak mantıklı olabilir.
Peki, evet bunları tek bir yerde yazalım ama, farklı .Net platformlarında bunları nasıl kullanacağım? Kullanabilir miyim?
Şüphesiz ki sorunun cevabı evet olmalı =) Bunu nasıl başaracağımıza bakalım. .NetStandard’tan önce bunu yapabilmek için 2 popüler yöntemimiz mevcut idi.
- Shared Asset Projects (SAP)
- Protable Class Library (PCL)
SAP: File linking gibi çalışan, Compiler Directive’ler kullanarak, platform spesifik kodlarınızı yazabileceğimiz bir teknikti. Örneğin
#if __IOS__ path = "iOS"; #else
şeklinde SAP projesi içerisindeki bir .cs dosyasında, sadece Xamarin.iOS için çalışmasını istediğimiz bir kod yazabilirdik. Projeler derlendiğinde, SAP ayrı bir dll olarak değil, her bir referans olduğu projenin içerisine gömülmüş olarak hayatını sürdürürdü. Fakat bu yöntem tahmin edersiniz ki ortaya çok yönetilebilir olmayan ve karmaşık kodlardan oluşan projeler çıkartırdı.
PCL: SAP projeleri ile ilerlemenin pek yönetilebilir olmaması ve kod karmaşıklığına sebep olması yüzünden PCL kullanmak daha da mantıklı oluyordu. Fakat bu durumda da karşımıza farklı sıkıntılar çıkıyordu.
Şöyle düşünelim, bir solution var. İçerisinde her katman ayrı ayrı yazılmış güzelce. Fakat önyüz olarak, Silverlight, Xamarin.iOS, Web ve Desktop olması gerekiyor. Tüm bu farklı .Net platformları kendine has, kendine özel sınıfları ve fonskiyonaliteleri barındıran farklı Base Class Library (BCL) ler kullanıyor. Peki bunların arasında ortak kümeyi nasıl bulacağız? Ya kulllandığımız özel bir sınıf, Web, Desktop ve Sliverlight ile uyumlu ama Xamarin.iOS ile uyumlu değilse ne olacak?
İşte bu problemlerle sonradan karşılaşıp kötü sürprizler yaşamamak için, .net ekibi şöyle bir çözüm getirdi.
- Farklı PCL Profiles
Ne kadar farklı .Net platformları arasında kod paylaşmak istiyorsanız, kullanabileceğiniz ortak API sayısı da ters orantılı olarak düşüyordu. Yani sadece Web ve Desktop önyüzü ile proje geliştirirken neredeyse tüm .Net Framework üne ait sınıfları kullanabilirken, işin içine Silvelight, Xamarin, WP vs girmeye başladığında birçok sınıfı kullanamaz hale geliyordunuz. Örnek bir listeye bakalım
PCL Profile | PCL Platforms |
---|---|
Profile7 | .NET Framework 4.5, Windows 8 |
Profile31 | Windows 8.1, Windows Phone Silverlight 8.1 |
Profile32 | Windows 8.1, Windows Phone 8.1 |
Profile44 | .NET Framework 4.5.1, Windows 8.1 |
Profile49 | .NET Framework 4.5, Windows Phone Silverlight 8 |
Profile78 | .NET Framework 4.5, Windows 8, Windows Phone Silverlight 8 |
Profile84 | Windows Phone 8.1, Windows Phone Silverlight 8.1 |
Profile111 | .NET Framework 4.5, Windows 8, Windows Phone 8.1 |
Profile151 | .NET Framework 4.5.1, Windows 8.1, Windows Phone 8.1 |
Profile157 | Windows 8.1, Windows Phone 8.1, Windows Phone Silverlight 8.1 |
Profile259 | .NET Framework 4.5, Windows 8, Windows Phone 8.1, Windows Phone Silverlight 8 |
İşin içine Xamarin, UWP vs girmeye başladıkça çarşı hepten karışmaya başlıyor, API sayısı iyice azalıyor, tüm projelerinizde kullandığınız popüler bir nuget paketini bile ortak projelerinize ekleyemez oluyordunuz, çünkü ilgili PCLProfile ında çalışmayabiliyordu.
Peki ne olacak? Belli ki bu kod paylaşım işine daha kalıcı bir çözüm lazım. Aslında gerekli olan, farklı .Net platformlarının uyması gereken bir standard olması lazım 🙂
Bunun da farkına varan Microsoft .NetStandard ı hayatımıza kattı.
Nedir Bu .NetStandard?
Aslında işin derinine inmeden, .NetStandard ı ve 2.0 ile ilgili bazı özellikleri özetleyerek bu bölümü sonlandıralım.
- .NetStandard’ı tüm .Net platformlarının bundan böyle implemente etmek zorunda olduğu bir Interface gibi düşünebiliriz.
- Birçok API ı içerisinde barındıran, tüm platformların da bunları implement etmek zorunluluğu sayesinde, farklı .Net platformlarını birleştiren ve gelecekteki ayrışmaları önleyecek bir Unified BCL olarak düşünebiliriz 🙂 2.0 ile beraber ortak API sayısı 32.000 i geçti ve bir önceki versiyona oranla(1.6) %142 büyüdü. Bu çok ciddi bir oran. Aşağıda bazı Temel API ları listeliyorum.
- Xml (Xlinq, XmlDocument, Xsd, Xsl, Xpath)
- Serialization (DataContract, Binary Formatter, XML)
- Networking (Http, Sockets, WebSockets, Mail)
- IO (Files, Compression, MMF)
- Threading (Thread, ThreadPool, Task)
- Core (Primitives, Collections, Linq, Interop, Reflection)
- .NetStandard 2.0 ile beraber gelen bir uyum sağlama katmanı sayesinde, netstandard kütüphanelerinizden sayısı her geçen gün artan .NET Framework binary leri referance alabileceksiniz, Ve Tabii ki, önceki tüm .NetStandard versiyonlarına ait API larıda kullanabileceksiniz.
- .NetStandard artık gelecekte PCL in yerini alacak, bu yüzden şuandan itibaren yeni projelerinizin tümünde kod paylaşımı olarak, .Netstandard ı tercih edebilirsiniz.
Hazır PCL projelerinden bahsetmişken ve .NetStandard ın gelecekte PCL in yerini alacağını söylemişken, yukarıdaki PCL Profile tablomuza birde Profile ların uyumlu olduğu .NetStandard versiyonlarını ekleyip gösterelim. Bu profile lar ile mevcut proje geliştirenler, PCL yerine ilgili .NetStandard kütüphanelerine geçekten çekinmesinler =)
PCL Profile | .NET Standard | PCL Platforms |
---|---|---|
Profile7 | 1.1 | .NET Framework 4.5, Windows 8 |
Profile31 | 1.0 | Windows 8.1, Windows Phone Silverlight 8.1 |
Profile32 | 1.2 | Windows 8.1, Windows Phone 8.1 |
Profile44 | 1.2 | .NET Framework 4.5.1, Windows 8.1 |
Profile49 | 1.0 | .NET Framework 4.5, Windows Phone Silverlight 8 |
Profile78 | 1.0 | .NET Framework 4.5, Windows 8, Windows Phone Silverlight 8 |
Profile84 | 1.0 | Windows Phone 8.1, Windows Phone Silverlight 8.1 |
Profile111 | 1.1 | .NET Framework 4.5, Windows 8, Windows Phone 8.1 |
Profile151 | 1.2 | .NET Framework 4.5.1, Windows 8.1, Windows Phone 8.1 |
Profile157 | 1.0 | Windows 8.1, Windows Phone 8.1, Windows Phone Silverlight 8.1 |
Profile259 | 1.0 | .NET Framework 4.5, Windows 8, Windows Phone 8.1, Windows Phone Silverlight 8 |
Bu bölümü burada sonlandıralım. Bir sonraki bölüm de .NetStandard da ile ilgili yazmaya devam edeceğim. İşin biraz daha otaya çıkışını, biraz daha derinini öğrenmek isterseniz, bir sonraki yazımda görüşek üzere 🙂
Yardımcı kaynaklar:
https://github.com/dotnet/standard/blob/master/docs/faq.md
https://docs.microsoft.com/en-us/dotnet/standard/net-standard
https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/
https://docs.microsoft.com/en-us/dotnet/api/?view=netstandard-2.0