Şu dönem .NET Core 2.2-Preview-1 ile gelişmeye devam eden ASP.NET Core, direkt framework içinde yerleşik olarak gelen “Dependency Injection(DI)” yaklaşımı bir çok açıdan kolaylıklar sağlıyor. Belli yapıları, geliştirilen uygulamalara enjekte etmek, uygulama fonksiyonlarının bağımlılıklarını sağlıklı yönetmek ve “seperation of concerns” prensibine sadık kalabilmek için DI oldukça gerekli. ASP.NET Core ile bunun yerleşik olarak sunulması, bağımlılıkların karmaşaya dönüşmesine uygun olan web uygulamaları için oldukça faydalı ve kolay bir özellik.

Bu kısa girişten sonra asıl konumuza gelelim; View ya da PageModel’larda(Razor Pages) bir bağlılığı nasıl kullanırız? Yani bir başka değişle *.cshtml’lerde bağımlılıkları nasıl kullanırız…

Enjekte ediyoruz…

ASP.NET Core’da Razor sayfalarda ya da View’larda @inject yöntemi ile bağımlılıkları sayfaların ön yüz tarafında kolay bir şekilde enjekte edebiliyoruz. Bu şekilde bir sayfada gösterilecek “data”’yı ASP.NET Core uygulamasına bağladğımız bir servis ile gösterebiliyoruz. Ne amaçla kullanabileceğimizden bahsetmek daha anlaşılır olmasını sağlayacak sanırım. Razor sayfası ya da View’de bir HTML “unordered list(<ul>)” elemanının içeriğini doldurma ihtiyacımız olsun ya da bir <select> elemanını… Bunun için View’e enjekte ettiğimiz bir servisi kullanarak kolaylıkla doldurabiliriz. Bunu tabi ki “Model” ya da “ViewData” ile yapmak da mümkün.Ama şöyle bir senaryonuz olduğunu düşünün; “multi-culture” bir uygulamanız var ve dil özelliklerine göre Model ya da ViewData’dan gelen veriler dil seçeneğine göre göstermeniz gerekiyor. 1 şeklinde gelen veriyi; “Yes, Ja, Si, Evet” şeklinde göstermek gibi. Bunun için dil değerlerini ViewData’ya gömmek yerine enjekte edilen farklı bir servis ile UI tarafında göstermek daha doğru olacaktır. Bu şekilde “seperation of concerns” prensibi de sağlanmış olur.

Peki bunu nasıl yapıyoruz…

Öncelikle bir servis oluşturmamız gerekiyor. Servisi burada, public olarak metotları olan bir sınıfı olarak düşünün. Public bir sınıfın, public metotları ile veri sağlayan bir yapı…

    public class VisitorService
    {
        private IServiceProvider _provider;
        private NotifyDbContext _db;
        public VisitorService(IServiceProvider provider, IConfiguration configuration)
        {
            _provider = provider;
            _db = (NotifyDbContext)_provider.GetService(typeof(NotifyDbContext));
        }
        public int GetActiveVisitorCount() => _db.Connections.Where(c => c.Connected).Count();
    }

Bu servisi, ASP.NET Core uygulamasının servislerini tanımladığımız yerde uygulamaya eklememiz gerekiyor.

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<VisitorService>();
            ....
            ..
            .
        }

ASP.NET Core’un içinde yerleşik olarak gelen DI yaklaşımının kilit noktası burası. Burada önemli olan 3 farklı ekleme yöntemi var.

  • .AddTransient<TService>(): Her request için yeni bir instance yaratırılır ve kullanılır.
  • .AddSingleton<TService>(): İlk request ile yaratılan, tek bir instance kullanılır.
  • .AddScoped<TService>(): Belli bir kapsam(web request) içinde her request de yaratılan instance kullanılır.

Servis tanımlarını bu şekilde yaparak, TService tipinde oluşturulan servis nesnesinin yaşam süresini belirtiyoruz. Bunların ayrıntılarına çok girmeyeceğim şimdi. Bu şekilde yaşam süresini belirttiğimiz servis nasıl View’larımızda kullanırız buna hızlıca bakalım.

*.cshtml sayfamızda @inject anahtarını kullanarak önce servisi sayfamız için tanımlıyoruz.

Burada @inject {Servisin sınıf adı} {Instance adı} şeklinde bir kalıp kullanmak gerekiyor.

Daha sonra *.cshtml sayfasının içinde istenilen yerde @{Instance adı}.ServisMetodu şeklinde ilgili servisin metoduna ulaşmak mümkün.

@using Microsoft.AspNetCore.Identity

@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
@inject NotifyMe.Services.VisitorService VisitorService
@if (SignInManager.IsSignedIn(User))
{
    <a title="Active users count" asp-page="/Users">@VisitorService.GetActiveVisitorCount()</a>
    .....
    ..
    .
}

Bu kısa yazı ile hızlıca ASP.NET Core’da @inject ile bağımlılıkların *.cshtml tarafında nasıl yapılabileceğini görmüş olduk. Oldukça kolay ve hızlı bir şekilde belli ihtiyaçları hızlıca karşılamak bu sayede mümkün. Bunun farkındalığında olmak ve gerektiği yerde, olması gerektiği gibi kullanmak uygulamanızın kalitesini arttıracaktır; kesin bilgi, yayalım… 🙂 🙂