Bu yazıda Visual Studio 2015 ortamında oluşturacağımız ASP.NET Core projesini ve proje bileşenlerini inceleyeceğiz. Bu incelemeyi yaparken .NET Framework üzerinde geliştirdiğimiz ASP.NET uygulamalarına göre ne gibi farklılıklar olduğuna da yer vermeye çalışacağız.
Bu yazıdan önce ASP.NET Core ile ilgili bazı temel noktalara değindiğim aşağıdaki yazıyı da okumanızı öneririm:
Genel Yapı Hakkında Bazı Notlar (Application Pipeline, Middleware, Services, Host Yapısı)
ASP.NET Core projesi geliştirmek için bir kod editörü(Notepad++, Sublime, Atom vb.) kullanabilirsiniz. Ancak daha verimli çalışmak için öncelikli tercihiniz Visual Studio 2015 veya Visual Studio Code olmalı, bu araçlarda işinizi kolaylaştıran bir çok özellik mevcut. Visual Studio 2015’in Mac ve Linux platformlarda bulunmadığını hatırlatmakta fayda var.
ASP.NET Core projesi geliştirmek için kullandığınız işletim sistemi, IDE veya kod editörüne göre hangi bileşenleri bilgisayarınıza kurmanız gerektiği bu adreste detaylı şekilde açıklanmış. Ben örneklerimi Visual Studio 2015 üzerinde gerçekleştireceğim, bu nedenle Update 3 ve .NET Core eklentisini bilgisayarıma kurdum.
Başlayalım;
Visual Studio 2015’te File > New > Project menüsündeki Web şablonları altından ASP.NET Core Web Application(.NET Core) seçeneğini seçiyoruz ve diğer alanları doldurup OK butonuna basarak ilerliyoruz. Bir sonraki aşamada karşımıza üç farklı proje şablonu geliyor; Blank, Web API ve Web Application. Empty sadece temel dosyaların bulunduğu boş bir proje, Web API REST bazlı API servisleri yazmak için uygun altyapıya sahip bir proje, Web Application ise klasik bir web uygulaması(MVC) için gerekli altyapıya sahip bir proje oluşturmamızı sağlıyor.
* Web şablonları altındaki ASP.NET Core Web Application(.NET Framework) seçeneği geliştireceğiniz .NET Core projesinin .NET Framework sınıf kütüphaneleriyle çalışmasını sağlayan bir seçenektir ve sadece Windows platformlarında çalışacak uygulamalar için kullanılır. Cross-platform uygulama geliştirecekseniz bu seçenek uygun olmayacaktır.
Blank proje şablonu ile Web Application proje şablonu arasındaki farkı görmek adına aşağıdaki ekran görüntüsünü paylaşıyorum.
Varsayılan olarak açılan Blank ve Web Application proje dosyaları
Web Application şablonu Empty proje şablonundaki dosyaları da kapsadığı için bu şablondaki dosyaları anlatarak devam edeceğim. Yani üstteki resimin sağında yer alan proje dosyalarına göz atacağız şimdi;
JSON Tabanlı Konfigürasyon Dosyaları
Projede dikkat çeken ilk şeylerden biri sanırım JSON formatındaki dosyalardır. .NET Framework’ten aşina olduğumuz XML tabanlı web.config dosyası ve türevleri, Core projelerinde hem yapısal olarak, hem de içerik olarak değişiyor. Bu dosyalardan;
appsettings.json‘da eski web.config dosyasında sakladığımız başta connectionStrings, appSettings olmak üzere ayarlar,
bundleconfig.json‘da CSS ve JavaScript dosyalarını nasıl paketleyeceğimiz(minify ve bundling),
project.json dosyasında projenin kütüphane bağımlılıkları, build/publish seçenekleri, publish öncesi/sonrasında çalışacak komutlar… gibi bilgiler bulunmaktadır.
launchSettings.json dosyasında projenin çalıştırılacağı esnada ortam(test, production…) bilgisine göre kullanılacak ayarlar saklanmaktadır. Bu dosya yukarıdaki resimde görünmüyor, Properties’in klasörünün altında bulabilirsiniz kendisini.
global.json. Bu dosyada solution’da yer alan projelerin hangi .NET Core versiyonunda çalışacağı, web projesine ait kodların ve test projelerinin hangi dizinlerde yer alacağı, Nuget paketlerinin nerede tutulacağı gibi bilgiler saklanır.
* Not: Bu yazı .NET Core 1.0 sürümü yayındayken hazırlanmıştır ve yukarıdaki dosyalar bu sürümde yer almaktadır. İlerleyen .NET Core sürümlerinde bu dosyalarından bazıları tedavülden kalkabilir veya isim/içerik değişikliğine uğrayabilir.
appsettings.json dosyasıyla ilgili söylememiz gereken önemli bir nokta daha var. Bu dosya uygulamanın başlangıcında, yani Startup class’ının constructor’ında dinamik olarak yüklenmektedir. Eğer projede ortam(environment) için oluşturduğunuz farklı appsettings dosyalarınız varsa yine aynı constructor’da bu ayarları yüklemeniz mümkün. Aşağıdaki resimde mavi alan içerisinde appsettings.json dosyasının, bir alt satırında da environment’e göre yüklenen dosyanın tanımını görebilirsiniz.
Main Metodu, Startup Sınıfı, Configure ve ConfigureServices Metotları
ASP.NET Core uygulamalarının host yapısı ASP.NET’teki yapıya göre köklü değişikliklere uğradı. Core uygulamalarını Kestrel veya WebListener gibi light-weight web serverlarda host ediyoruz. Bir diğer önemli nokta da ASP.NET Core uygulamalarının aslında bir konsol uygulaması olması. Yani executable (çalıştırılabilir) bir uygulama olarak çalışan ASP.NET Core uygulamalarının bir başlangıç noktası (entry point) bulunuyor, bu da static Main metodu.
Projedeki Program.cs dosyasında yer alan Main metodu projenin başlangıç noktasıdır. Burada oluşturulan WebHostBuilder nesnesine uygulamanın ihtiyacı olan en temel bileşenler bağlanır ve uygulama bu nesne üzerinden çalıştırılır.
Program.cs
public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}
Burada üzerinde duracağımız iki önemli kısım var; biri Startup class’ı, diğeri de uygulamayı host edecek web server.
Startup class’ı, uygulama başlatıldığında Main metodundan sonra çalışan ikinci metottur, bir nevi başlangıç sınıfıdır diyebiliriz. Temel bileşenler Main metodunda belirlenirken bir sonraki aşamada ihtiyaç olan middleware ve service bileşenleri ise Startup isimli class’ta belirlenecektir. WebHostBuilder nesnesi bu class’ı UseStartup<T>() metodu ile belirlemektedir. Startup class’ını birkaç paragraf sonra tekrar değineceğiz.
Main metodunda belirlenen bir diğer önemli konu da uygulamanın hangi web server’da host edileceğidir. ASP.NET Core uygulamaları Kestel ve WebListener web server’larından biri üzerinde host edilebiliyor. İlk yazımda kısaca değinmiştim, bu iki server ancak IIS, Nginx veya Apache gibi web server’ların arkasında durarak uygulamamızı host edebiliyor, bu ana web server’lar ise reverse proxy olarak kullanılıyor. Main metodunda UseKestrel() metodu ile uygulamanın Kestrel’de host edileceği belirlenmiş.
UseIISIntegration() metodu ise IIS’e özel client certificate forwarding, sub application oluşturma gibi bazı reverse proxy özelliklerinin kullanılmasını sağlıyor. UseContentRoot() metodu da adından ve parametresinden anlaşılacağı üzere proje içeriklerinin ana dizininin neresi olduğunu belirliyor.
Main metodundan sonra bir de Startup.cs dosyasının içerisinde olup bitenlere bakalım. Bu class’da iki önemli metot bulunuyor; Configure ve ConfigureServices. Configure metodunda middleware bileşenleri belirlenir. Middleware bileşenleri ASP.NET’teki HttpModule’lere benzetebileceğimiz yapılar. Application pipeline’da yer alan ve her request-response’da çalıştırılan yapılardır. ConfigureServices metodunda ise service bileşenleri container objesine register edilerek uygulamanın farklı yerlerinde(örneğin Controller class’larında) kullanılması sağlanır.
MVC Bileşenleri: Model, View ve Controller
ASP.NET Core uygulamaları MVC(Model View Controller) tasarım kalıbına göre yapılandırılmakta ve çalışmaktadır. Core projesinde Model dosyaları için bir klasör gelmiyor, isterseniz siz açabilirsiniz veya Model nesnelerinizi ayrı bir class library projesinden yönetebilirsiniz. Burada standart proje şablonuyla Controller ve View yapısı hazır geliyor. Controllers klasörü altındaki HomeController ve Views klasörü altındaki view nesnelerini projede görebiliriz.
MVC ve MVC’nin ASP.NET ile ASP.NET Core’a nasıl uyarlandığı ayrıca incelenmesi gereken konular. Daha önceden bu tasarım kalıbıyla çalışma fırsatınız olmadıysa konuyu ayrıca incelemenizi tavsiye ederim. Ben en azından sistem Controller ve View dosyalarına nerede nasıl dokunuyor, bunu kısaca anlatayım;
Uygulamanın URL yapılandırması Startup class’ındaki Configure metodunda yapılır. UseMvc() metodu ile gerçekleştirilen URL ayarlarına göre uygulama, gelen bir URL’ye bakarak isteğin hangi Controller class’ına gideceğine karar verilir. Örneğin; varsayılan bir URL routing yapılandırmasına göre www.siteurl.com/Home/Index şeklinde yapılan bir request HomeController class’ı içerisindeki Index metoduna gider. Index metodu belirli işleri yapar(veritabanına bağlanır vb.) ve işlemin sonucunu Views/Home klasörü altındaki Index.cshtml dosyasına gönderir. Index.cshtml buradaki view nesnesidir ve kendisine gönderilen model içeriğini HTML kodları arasında uygun yerlere basar ve nihayetinde oluşan HTML istemciye gönderilir.
ASP.NET Core uygulamasında yapılan isteklerin(request) cevaba(response) dönüştürülmesi, genel hatlarıyla yukarıda bahsettiğim Controller sınıfı, Action metodu ve View dosyası arasında olmaktadır.
Ortama Göre Projenin Yapılandırılması
ASP.NET Core projesinin genel yapılandırmaları yukarıda bahsettiğimiz .json dosyalarında ve Startup.cs dosyasında yapılıyor. appsetting.json dosyasından bahsederken ortam bilgisine(environment variable) göre projedeki farklı bir appsetting.json dosyasının kullanılabileceğine değişmiştik.
Geliştirme yaparken development, test, pre-production, production gibi farklı ortamlarımız olabiliyor. Her ortamın kendine has ayarları olabileceği için, ayarları ortam değişikliklerine hazır halde tutmak bize ciddi kolaylık sağlayacaktır. ASP.NET 4.0 ve sonrasındaki sürümlerden bildiğimiz config transformation konusundan, yani Web.Debug.config gibi farklı Web.config dosyalarının yönetiminden bahsediyoruz aslında.
ASP.NET Core uygulamalarında appsetting.json dosyası dışında kullanılacak ortama bağlı json ayar dosyasını Startup class’ının contructor metodunda belirliyoruz. Aşağıdaki kod örneğinde bu tanımları görebiliriz.
 var builder = new ConfigurationBuilder()
    .SetBasePath(env.ContentRootPath)
    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
    .AddEnvironmentVariables();
appsettings.{env.EnvironmentName}.json ifadesindeki env.EnvironmentName değeri proje ayarlarındaki ASPNETCORE_ENVIRONMENT değişkeninden okunur. Solution Explorer’da projeye sağ tıklayıp Properties seçeneğinden gelen ekrandaki Debug sekmesinde bu ayarı görebiliriz. Resimdeki değer “Development”, yani proje çalıştığında eğer root dizinde appsettings.Development.json isimli dosya varsa, bu dosyadaki ayarlar da uygulama için kullanılacaktır.
Bu penceredeki Profile seçeneğinden birden fazla debug profili tanımlayabilir ve debug işlemi esnasından bu profillerden birinin kullanımlasını, dolayısıyla farklı ortamlara özel config dosyalarının kullanılmasını sağlayabiliriz.
Statik Dosyalar(JavaScript, CSS, Resim vb.)
Son olarak ASP.NET Core projesindeki statik dosyaların nerede saklandığından ve nasıl yönetildiğinden kısaca bahsedelim. Projede bulunan wwwroot dizininde .js, .css ve resim(.png, .jpg vb.) dosyaları bulunuyor. Bu dosyalar Bower paket yöneticisi tarafından yönetilmektedir. Bower projede kullanılan JavaScript ve CSS kütüphanelerinin bağımlılıklarını yönetmemizi sağlıyor. Aşağıdaki resimde hem wwwroot dizinini, hem de Bower altında yer alan kütüphane bağımlılıklarını görebilirsiniz.
Bu yazıda Visual Studio 2015’te oluşturduğumuz bir ASP.NET Core projesinin temel bileşenlerine ve yapılandırmasına göz attık. Buradaki bazı başlıklar daha detaylı şekilde ele alınması gereken konular. İleride fırsatını bulabilirsem(umarım bulurum) bu konularla ilgili de daha detaylı yazmaya çalışacağım.
ASP.NET Core MVC
“ASP.NET Core – Proje Yapısı, Dosyalar ve Yapılandırmalar” hakkında 9 yorum	
Mustafa dedi ki:	
2 Ağustos 2016, 08:17	
Güzel bir yazı olmuş, ellerinize sağlık, devamının gelmesi dileğiyle.
Cevapla
Nevzat Akkaya dedi ki:	
2 Ağustos 2016, 08:53	
elinize sağlık
Cevapla
Yunus dedi ki:	
2 Ağustos 2016, 09:53	
Hocam elinize emeğinize sağlık,
Gelişen teknolojiyi ve değişen proje yapılarını sizin gibi değerli yazılımcı büyüklerimizden öğrenmek bizler için daha aydınlatıcı oluyor. Serinin devamını heyecanla bekliyoruz
Cevapla
Sinan BOZKUŞ dedi ki:	
2 Ağustos 2016, 19:47	
Güzel makale olmuş hocam, emeğinize sağlık.
Cevapla
Bilal dedi ki:	
5 Ağustos 2016, 20:01	
Hocam, 3.paragrafta Visual Studio Code yerine Visual Studio Core olmuş. Emeğinize sağlık, teşekkürler.
Cevapla
ugur dedi ki:	
7 Ağustos 2016, 00:05	
Teşekkürler, düzelttim Aslında Visual Studio Core isimlendirmesi de fena değilmiş
Cevapla
Ekin dedi ki:	
17 Ağustos 2016, 16:32	
Güzel bir makale olmuş hocam teşekkürler.
Daha önce yazdığınız makale ile birlikte güzel bir başlangıç oldu.
Cevapla
ibrahim dedi ki:	
6 Ekim 2016, 14:05	
Güzel bir anlatım tşkler.
Cevapla
Emre dedi ki:	
16 Ekim 2016, 20:25	
Emeğinize sağlık.
Cevapla
Bir Cevap Yazın Cevabı iptal et
E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir
Yorum
İsim *
E-posta *
İnternet sitesi
Yazı dolaşımı
ASP.NET Core – Genel Yapı Hakkında Bazı Notlar: Application Pipeline, Middleware, Services, Host Yapısı