Asp.Net Core 2.0’a Giriş – Bölüm 2 (Program.cs, WebHostBuilder, Kestrel hakkında)
Selamlar Arkadaşlar, bu yazımda geçen yazıda başladığımız AspNet Core Web Application oluşturma ve solution structer ına bir göz gezdirmeden sonra, Program.cs e ve içeriğindeki metodlara değineceğiz. Sonrasında sırası ile, Startup.cs dosyasına, bakıp AspNetCore Dependency Injection, Middleware yapısı vb konulara değinerek bu seriyi tamamlayacağız.
Öncelikle klasik AspNet ten hatırladığımız System.Web assembly sinden ve ne yaptığından bahsedip Core tarafına o şekilde geçelim.
Klasik Asp.Net projelerinde, bir web projesinin ayağa kalkma süreci System.Web assembly sindeki kodlar tarafından sağlanırdı ve sizin buna müdahele şansınız sadece size Global.asax dosyasında müdahele etmeniz, konfigürasyonlar yapmanız için verilen bazı metodları editlemekle kısıtlıydı. Artık yeni AspNet Core tarafında, application ın tümüyle başlatılma kısmı sizin elinizde. Nasıl olduğuna biraz daha derinlemesine değinelim.
Asp.Net Core projelerinde solution içerisinde bir adet Program.cs dosyası mevcut. Bu dosya içerisindeki Main() metodu artık sizin application nınızın entry point i. Uygulumanızı başlattığınızda, Runtime uygulama içerisinde ki bu metodu arar ve çalıştırır. Şu aşamada Asp.Net Core Web App projeniz aslında bir Command Line Application olarak yaşamına başlar.
public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup(); }
Uygulama çalıştığında Main() metodunuz, CreateWebHostBuilder Metodunu çağırır ve geri dönen IWebHostBuilder interface i üzerindeki Build() ve Run() metodlarını tetikler. Bu IWebHostBuilder metodu üzerindeki Run() metodu tetiklendiği andan itibaren artık uygulamanız gerçekten bir Asp.Net Core Web Application a dönüşür 🙂
Asp.Net Core un open source olmasından faydalanalım ve bu CreateDefaultBuilder(args) metodu arka planda ne yapıyor bir bakalım.
Buradan gördüğümüz gibi CreateDefaultBuilder(args) metodu aşağıdaki işleri yapıyor. Tek tek ne olduklarına değinmeye çalışalım.
public static IWebHostBuilder CreateDefaultBuilder(string[] args) { var builder = new WebHostBuilder(); if (string.IsNullOrEmpty(builder.GetSetting(WebHostDefaults.ContentRootKey))) { builder.UseContentRoot(Directory.GetCurrentDirectory()); } if (args != null) { builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build()); } builder.UseKestrel((builderContext, options) => { options.Configure(builderContext.Configuration.GetSection("Kestrel")); }) .ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment; config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); if (env.IsDevelopment()) { var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName)); if (appAssembly != null) { config.AddUserSecrets(appAssembly, optional: true); } } config.AddEnvironmentVariables(); if (args != null) { config.AddCommandLine(args); } }) .ConfigureLogging((hostingContext, logging) => { logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddConsole(); logging.AddDebug(); logging.AddEventSourceLogger(); }) .ConfigureServices((hostingContext, services) => { // Fallback services.PostConfigure(options => { if (options.AllowedHosts == null || options.AllowedHosts.Count == 0) { // "AllowedHosts": "localhost;127.0.0.1;[::1]" var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); // Fall back to "*" to disable. options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" }); } }); // Change notification services.AddSingleton( new ConfigurationChangeTokenSource(hostingContext.Configuration)); services.AddTransient<IStartupFilter, HostFilteringStartupFilter>(); }) .UseIIS() .UseIISIntegration() .UseDefaultServiceProvider((context, options) => { options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); }); return builder; }
Burada aslına bir takım kontroller ve konfigürasyonların dışında değinmek istediğim yerler şimdilik şunlar ;
- builder.UseContentRoot
- builder.UseConfiguration
- builder.UseKestrel
- .UseIIS()
- .UseIISIntegration()
- .ConfigureServices((hostingContext, services)
- .UseDefaultServiceProvider((context, options)
bu metodlar ile initialize edilen WebHostBuilder için aşağıdaki ayarlar default olarak yapılıyor.
- builder.UseContentRoot(Directory.GetCurrentDirectory());
- Burada projenin content root konfigürasyonu yapılıyor. Project Directory si Content Root olarak set ediliyor.
- builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build());
- Burada projenin settings konfigürasyonu yapılıyor. Default olarak appsettings.json dosyasında konfigürasyonlar okunup initiate ediliyor.
- builder.UseKestrel((builderContext, options) => { … }
- Kestrel AspNet Core için yazılmış olan internal bir Web Server. Tabii ki bir IIS, Nginx, Apache gibi donanımlı ve yetenekli değil, ama oldukça lightweight ve performanslı çalışan bir web server. Bunun detaylarına daha sonra gireceğiz ama özetle burada Asp.Net Core Web App projesinin internal olarak Kestrel i kullanması söyleniyor ve Kestrel in bazı konfigürasyonları yapılıyor.
- .UseDefaultServiceProvider((context, options)
- Burada WebHostBuilder a söylenen Asp.Net Core projesinin internal Dependency injection container ını kullanması. Dependency injection artık Core ile birlikte built-in gelen bir support. Object Creation lar, ve onların lifetime managementları için bunu doğrudan kullanabiliriz. Yada kendi istediğimiz IoC Containerları kullanmasını söyleyebiliriz. Burada Default olarak built-in gelen container ın kullanılması söyleniyor.
- .ConfigureServices((hostingContext, services)
- Burada, Builder a kullanması için verilen IoC Container a, Proje ile alakalı bazı type ların register edilmesi sağlanıyor.
- örneğin; services.AddTransient<IStartupFilter, HostFilteringStartupFilter>(); Transient (obje container dan her istendiğine yenisi oluşturulup veriliyor) olarak IStartupFilter istendiğinde, HostFilteringStartupFilter ın proje içerisinde kullanılması ayarları yapılıyor.
- .UseIIS()
- .UseIISIntegration()
- Burada, Web uygulamasının external web server olarak IIS kullanması söyleniyor. Gelen requestler önce IIS den geçip, internal olan Kestrel e ulaşacak, sonrasında da middleware lerin eklenme sırasına göre her bir middleware de ilgili process ler gerçekleşip, aynı şekilde önce Kestrel e sonra da IIS e response iletilecek, ve response client tarafına dönecek.
Bu yazımıza da burada son verelim. Bir uygulamanın hayatına bir command line application olarak başlayıp, nasıl bir Asp.Net Core Web App e dönüştüğünü yüzeysel olarak source kodları inceleyerek anlamaya çalıştık. Bir sonraki yazımızda da Startup.cs dosyasını inceleyip artık bir Asp.Net Core Web Application ın, nasıl oluştuğunu, solution un neler içerdiğini ve konfigürasyonlarının yapılıp hayatına nasıl başladığını tamamen anlamış olacağız.
Bir sonraki yazımda görüşmek üzere.