Dependency Injection / Ioc
Inversion of Control Container
Ioc Container
Uygulamaların IoC Container yapısını kurmak için Ninject ve Autofac kütüphaneleri kullanılıyor.
Ninject
Ninject
paketi kullanılır.
Uygulamanın tipine göre Ninjectin ek paketleri kullanılıyor.ASP.NET MVC
Ninject.MVC5
Ninject.Web.Common
Ninject.Web.Common.WebHost
Ninject.Web.Common.OwinHost (OWIN kullanılıyorsa)
WCF
Ninject.Extensions.Wcf
Ninject.Web.Common
Ninject.Web.Common.WebHost
Autofac
Autofac
paketi kullanılır.
.NET Core projelerinde Dependency Injection yapısına Autofac'i entegre etmek için Autofac.Extensions.DependencyInjection
paketi kullanılır.
Ioc yapısının merkezileştirilmesi (Composition Root)
Ioc modülleri (NinjectModule
, Autofac.Module
) ve DependencyResolver
sınıfları için ProjeAdı.Ioc
projesi kullanılır ve uygulamaların Ioc tanımları bu projede yapılır. Uygulama projesinde ve diğer projelerde Ioc ile ilgili dizinler, dosyalar olmaz.
Sınıfların Bağımlılıkları
Sınıf bağımlılıkları Construction Injection kullanılarak yapılır. Yani bir sınıfın kullanacağı diğer bileşenlerin arayüzleri ilgili sınıfın yapıcı metoduna parametre olarak geçirilir ve bileşeni temsil eden member değişkene atama yapılır.
Setter (Property) Injection ve dolayısıyla [Inject]
(Ninject) etiketinin kullanılması önerilmez.Setter injection kullanımının dezavantajları:
Sınıfın bağımlılıklarının görünür olmasını engeller, sınıf bağımlılıklarının asgaride tutulması hedefini zedeleyecek bir ortam yaratır.
Sınıfları Ninject kütüphanesine bağımlı kılar. IoC Container yapısı değiştirilirse ve başka bir araç kullanılırsa bu sınıfların güncellenmesi gerekir.
InRequestScope
Ninject
Ninjectin sınıf oluşturma davranışı incelendiğinde bazı genel kullanılan Framework sınıflarının yüzlerce adette oluşturulduğu görüldü. Bu durumu engellemek için bu sınıflarda InRequestScope
ayarı kullanıldı ve her istekte sadece bir örneğin oluşturulması sağlandı.
Not: InRequestScope
ayarı Ninject.Web.Common.WebHost paketinde yer alır ve Ninject.Web.Common
isim uzayında bulunur.
ILogger
ILoggerWrapper
ISettingsService
IConfigurationManagerWrapper
ISecurityService
Autofac
Her HTTP isteğinde bir sınıfın bir örneğinin oluşturulup kullanılması için Autofac'ta InstancePerLifetimeScope
scope tanımı kullanılır.
Singleton
Uygulama çağında bir sınıfın örneğin bir kere oluşturulup her istekte bu örneğin kullanılması için Singleton scope tanımı kullanılır.
Ninject
Autofac
Sınıf bağımlılıklarında dikkat edilmesi gerekenler
Birden fazla sorumluluğu olan büyük sınıfların birbirlerine bağımlı olması, yapıcı metotlar ile başlayan nesne oluşturma işleminde performans kaybına neden oluyor. Bir web metodunun çalışabilmesi için 2-4 saniye geçebiliyor.
Web projelerinde Controller bağımlılıklarından başlayarak, oluşturulacak object graphın derinlik seviyesi az tutulmalı.
Single Responsibility Principle gözetilerek sınıflar sorumluluklarına göre parçalanmalı ve yeni sınıflar oluşturulmalı. Controllerlar da aynı şekilde parçalanmalı.
Bir sınıfın içerdiği member servislerin kullanımları kontrol edilerek, tespit edilen anlamlı gruplara göre yeni sınıflar oluşturulmalı. Daha önceden büyük olan ana sınıf da küçültülmeli.
Bir sınıfın sadece bir veya birkaç metodunu kullanan istemci servis için bu metotları içeren daha küçük sınıflar oluşturulmalı.
Sınıfların bağımlı olduğu sınıfların veritabanına veya veri kaynağına en kısa yoldan erişen sınıflar olması tercih edilmeli. Sınıfların object graphlarındaki derinlik seviyesi olabildiğince düşürülmeli.
ServiceFactory kullanımı (Ninject)
Bir sınıfta az kullanılan bir memberın bağımlılığını yapıcı metottan vermek yerine bir ServiceFactory
aracılığıyla, gerektiği anda oluşturulmasını sağlayacak bir yapı kullanılabilir.
Bunun nedeni bu az kullanılan memberı oluşturmanın getireceği object graph yükünü azaltmak.
Bu memberın oluşturulması maliyetli ise ve kullanıldığı yerdeki metot da bir şekilde başka bir sınıfa taşınamıyorsa bu yöntem kullanılabilir. Ama çok sık kullanılması önerilmez. (Aslında bu member'ın az kullanıması sınıfın low-cohesion'a sahip olduğunu gösterir ve bu konu ele alınmalı, refactoring düşünülmelidir.)
Bunun için Ninject.Extensions.Factory
kütüphanesi ve yeni bir Bind
ifadesi kullanılır.
Az kullanılan sınıf yerine bu sınıfın Factory’si yapıcı metotta bağımlılık olarak belirtilir.
Factory arayüzü:
Kullanımı:
Bu arayüzün implementasyonunu çalışma zamanında Ninject oluşturuyor ve bunu mevcut kernel üzerinden yapıyor.
https://github.com/ninject/ninject.extensions.factory/wiki
Convention tabanlı Ioc tanımları
Arayüzlerin hangi implementasyonları oluşturacağı tanımını tek tek yapmak yerine, belli isimlendirme ve isim uzayı kuralları ile toplu Bind işlemi yapılabilir.
Ninject
Bu işlem Ninject'te Ninject.Extensions.Conventions
paketi kullanılarak yapılır.
Örnek:
Aşağıdaki tanım MemberService
sınıfının isim uzayında bulunan ve isimleri Service
ifadesi ile biten sınıfların arayüzleri ile implementasyonlarını bağlar.
Autofac
Last updated
Was this helpful?