DotNet Core ile Windows Service

DotNet Core kullanarak arka plan servislerinizi hazırlayın

Adem Catamak
2 min readNov 27, 2019

Yeni versiyonlarının da çıkması ile giderek güçlenen DotNet Core üzerinde geliştirilebilecek uygulamalar hakkında çok fazla kaynak bulunabilmektedir. Örneklerin birçoğu ise Web tabanlı uygulama geliştirme yöntemleri hakkındadır. HostedService ve BackgroundService gibi yapılar ile arka plan uygulamalarının geliştirilmesi hakkındaki örnek ve yazılar web tabanlı uygulamalara nazaran biraz daha arka plan da kalmıştır.

Örnekleri kullanarak arka plan uygulaması geliştirdim ve geliştirme ortamımda kodları başarılı bir şekilde çalıştırdım. Ancak uygulamanın Windows işletim sistemine sahip bir sunucu üzerinde kurulması noktasında bazı sıkıntılar yaşadım. Bir süre araştırdıktan sonra çözümü System.ServiceProcess.ServiceController NuGet paketinde yer alan (.Net Framework’den de aşina olabileceğiniz) ServiceBase sınıfı üzerine bir extension metot ile servisi ayağa kaldırmakta buldum. Çözümün yer aldığı linkte yer alan kod parçası IWebHost üzerinde çalışırken, bizim aşağıda yapacağımız örnekte bu kısmı değiştirerek IHost üzerinde çalışmasını sağlayacağız.

Bu örnekte ConsoleApp uygulamamız NetCore 2.2 ile geliştirilmiştir fakat geliştirmesine odaklandığımız sınıflar, .Net Standard 2.0 üzerinde kodlanmıştır. Bu sayede aşağıdaki yöntemi .NetCore 3.0 için de kullanabilirsiniz.

Win Service on DotNet Core 3

Bu yöntemde bir ServiceBase sınıfı oluşturuyoruz ve Start, Stop gibi metotları içerisinde DotNet Core üzerinde var olan IHost objemizi çalıştırıyoruz. Örneklerden aşina olacağınız üzere, bizim yazdığımız HostedService veya BackgroundService sınıflarımız IHost tipindeki objeye bağlı olarak yaşamaktadır. IHost, uygulamalarımızın üzerinde çalıştığı ana yapı olarak düşünülebilir. Biz de bu ana yapının çalıştırılması işlemini aşağıdaki örnekte görebileceğiniz gibi ServiceBase tipindeki sınıfımıza bırakacağız. Böylece Windows sunucu üzerinde ServiceBase tipinden bir obje ile projemizi “Yerel Hizmetler” (Services) olarak sisteme kaydetmiş olacağız. Bu link üzerinden geliştirdiğimiz uygulama örneğine erişebilirsiniz.

GenericHostService adında ServiceBase sınıfını miras alan bir sınıf oluşturarak işe başlayalım. Bu sınıf OnStart, OnStop gibi içerisini doldurabileceğimiz metotlara sahiptir. OnStart metodu içerisinde, GenericHostService sınıfımıza parametre olarak geçtiğimiz IHost tipindeki objemizi çalıştıracağız. Böylece geliştirdiğimiz uygulama çalışmaya başlayabilecektir.

Burada çalıştırma aşamasında, IHost tipindeki objemizin ApplicationStopped durumuna geçmesi halinde tetiklenecek bir metot yerleştiriyoruz. Buradaki amacımız IHost objemizin üzerine durdurma isteği geldiği zaman (bu isteğin ServiceBase sınıfı üzerinden gelmediği durumda), GenericHostService sınıfımızın Stop metodunu çağırarak (Windows Service) Windows servisimizi durdurmaktır. Bunu yapmadığımız durumda, IHost objemiz yani uygulamamız durmuş olsa bile, Yerel Hizmetler sayfasına baktığımız zaman uygulamamızın çalıştığı şeklinde yanlış bir bilgi ile karşılaşırız.

Eğer ServiceBase tipindeki objemize ait OnStop metodu çalıştırılırsa yani Windows Service durdurulmak istenmişse, IHost tipinden oluşmuş host objemizin StopAsync metodunu çağırıyoruz. Tuttuğumuz _setupRequestedByWindows isimli bayrak sayesinde ise IHost objemiz tarafından tekrar ServiceBase sınıfına ait olan Stop metoduna çağrı yapmıyor olacağız.

Bir de kullanımını kolaylaştırmak için aşağıdaki gibi bir metot oluşturabiliriz. Bu şekilde IHost tipindeki objemizin çalıştırma adımını daha kolay bir hale getirmiş olacağız.

En nihayetinde ise appSettings.json üzerinde RunAsWinService adında, boolean veri tutan bir değer tanımlayarak, Windows Server üzerindeki kurulumlarda bu alanı aktif ederken, development ortamında bu değerin pasif olmasını sağlayarak Windows işletim sistemine sahip olmayan ortamlarda da uygulamanın çalışmasını sağlayabiliriz.

Şimdiye kadar tanımladığımız kısımların kullanımına ait örnek ise aşağıda yer almaktadır.

Main Metot

CreateHost Metot

BuildApplicationConfiguration and InjectDependencies Metot

--

--