4. Bağımlılık Enjeksiyonu
Bağımlılık enjeksiyonu, kontrol tersine çevirmenin bir sonucu olarak görülebilir. Bunu yeni bir örnekle açıklayalım. Aşağıdaki 3 katmanlı web uygulamasını ele alalım:
![]() |
DAO katmanına erişimin, daha önce incelediğimiz [IArticlesDao] arayüzü tarafından kontrol edildiğini ve uygulamanın tamamının web üzerinden ürün satın almaya yönelik bir web uygulaması olduğunu varsayalım. Ürünler, [Dao] katmanı tarafından yönetilen ürünlerdir. İş katmanına erişimin aşağıdaki arayüz tarafından kontrol edildiği varsayılmaktadır:
Public Interface IArticlesDomain
' bir ürün sepeti satın alınır
Sub acheter(ByVal panier As Panier)
' ürün listesini alıyoruz
Function getAllArticles() As IList
' belirli bir ürünü alır
Function getArticleById(ByVal idArticle As Integer) As Article
' hataları kaydetmek için
ReadOnly Property erreurs() As ArrayList
End Interface
Farklı yöntemlerin anlamları üzerinde fazla durmayacağız. Sadece, satıştaki tüm ürünlerin listesini alması gereken [getAllArticles] yönteminin verilere erişmesi gerektiği belirtilmelidir. Bu verileri elde etmek için, [IArticlesDao] arayüzüne başvurması gerekir. [IArticlesDomain] arayüzünü uygulayan bir sınıfın iskeleti şu şekilde olabilir:
Imports istia.st.articles.dao
...
Namespace istia.st.articles.domain
Public Class AchatsArticles
Implements IArticlesDomain
'özel alanlar
Private _articlesDao As IArticlesDao
Private _erreurs As ArrayList
' oluşturucu
Public Sub New(ByVal articlesDao As IArticlesDao)
_articlesDao = articlesDao
End Sub
...
End Class
End Namespace
Daha önce de belirttiğimiz gibi, iş katmanı arayüzünün bazı yöntemleri, [Dao] katmanından veri talep etmek zorundadır. Dolayısıyla, [IArticlesDomain] arayüzünün [AchatsArticles] uygulama sınıfımız, [IArticlesDao] arayüzünün bir uygulamasına bir referansa ihtiyaç duyar. Yukarıda, bu referans, [_articlesDao] adlı özel alandır. Bu referans, bir [AchatsArticles] nesnesinin oluşturulduğu sırada sağlanır.
[AchatsArticles] sınıfının yazıldığını ve bunu [Nunit] türünde bir testle test etmek istediğimizi varsayalım. Bu testi, bir Spring yapılandırma dosyası kullanacak şekilde oluşturalım:
...
Imports Spring.Objects.Factory.Xml
Imports System.IO
...
<TestFixture()> _
Public Class NunitSpringTestArticlesDomain
' test edilecek nesne
Private articlesDomain As IArticlesDomain
<SetUp()> _
Public Sub init()
' Spring nesne oluşturucusunun bir örneğini alıyoruz
Dim factory As XmlObjectFactory = New XmlObjectFactory(New FileStream("spring-config-domain.xml", FileMode.Open))
' articles dao nesnesinin oluşturulmasını talep ediyoruz
articlesDomain = CType(factory.GetObject("articlesdomain"), IArticlesDao)
End Sub
...
End Class
Spring'in [spring-config-domain.xml] yapılandırma dosyasının içeriği ne olabilir? Şu şekilde olabilir:
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE objects PUBLIC "-//SPRING//DTD OBJECT//EN"
"http://www.springframework.net/dtd/spring-objects.dtd">
<objects>
<description>Gestion d'une table d'articles</description>
<!-- IArticlesDao arayüzünün uygulama sınıfı -->
<object id="articlesdao" type="istia.st.articles.dao.ArticlesDaoPlainODBC, articlesdao">
<constructor-arg index="0">
<value>odbc-firebird-articles</value>
</constructor-arg>
<constructor-arg index="1">
<value>SYSDBA</value>
</constructor-arg>
<constructor-arg index="2">
<value>masterkey</value>
</constructor-arg>
</object>
<!-- IArticlesDomain arayüzünün uygulama sınıfı -->
<object id="articlesdomain" type="istia.st.articles.domain.AchatsArticles, articlesdomain">
<constructor-arg index="0">
<ref object="articlesdao" />
</constructor-arg>
</object>
</objects>
Bu dosya, [Dao] katmanındaki [IArticlesDao] türündeki singleton'ı oluşturmak için halihazırda kullanılan dosyadır; buna, iş katmanındaki [IArticlesDomain] türündeki singleton'ı oluşturmak için kod eklenmiştir. Bu dosya nasıl oluşturulacaktır?
- Harici bir kod, Spring’den yapılandırma dosyasında “articlesdomain” adlı singleton’a ilişkin bir referans ister. Test sınıfımızdaki [init] yöntemi de buna bir örnektir:
<SetUp()> _
Public Sub init()
' Spring nesne oluşturucusunun bir örneği alınır
Dim factory As XmlObjectFactory = New XmlObjectFactory(New FileStream("spring-config-domain.xml", FileMode.Open))
' articles DAO nesnesinin örneklenmesini talep ediyoruz
articlesDomain = CType(factory.GetObject("articlesdomain"), IArticlesDao)
End Sub
- Spring, yapılandırma dosyasında söz konusu singleton'ın tanımını bulur. Bu singleton'ı oluşturmak için "articlesdao" adlı başka bir singleton'a ihtiyaç duyduğunu fark eder:
<object name="articlesdomain" class="istia.st.articles.domain.AchatsArticles, articlesdomain">
<constructor-arg index="0">
<ref object="articlesdao" />
</constructor-arg>
</object>
- Spring daha sonra "articlesdao" singletonunu oluşturacaktır. Bunun nasıl yapıldığını daha önce açıklamıştık.
- Bu işlem tamamlandıktan sonra, "articlesdomain" singletonunu oluşturabilir ve bunu talep eden koda bir referans verebilir.
Bu mekanizma şu şekilde şematize edilebilir:
![]() |
Görüldüğü gibi Spring, "articlesdomain" singletonunun "articlesdao" singletonuna olan bağımlılığını yönetmiştir. Spring'i bu şekilde kullanabilmek için, bağımlı singleton'u argüman olarak kabul eden bir yapıcıya sahip bir sınıf oluşturmamız gerekti:
Imports istia.st.articles.dao
...
Namespace istia.st.articles.domain
Public Class AchatsArticles
Implements IArticlesDomain
'özel alanlar
Private _articlesDao As IArticlesDao
' yapıcı
Public Sub New(ByVal articlesDao As IArticlesDao)
_articlesDao = articlesDao
End Sub
...
End Class
End Namespace
"Bağımlılık enjeksiyonu" terimi, hem:
- bağımlılıklarına göre örneklenecek sınıfların oluşturulma şekli
- Spring'in bu sınıfların örneklendirilmesi sırasında bu bağımlılıkları yönetme biçimi

