Aracılığıyla paylaş


Bağımlılık Ekleme

Not

Bu e-Kitap 2017 baharında yayımlanmıştır ve o zamandan beri güncelleştirilmemiştir. Kitapta değerli kalan çok şey var, ancak bazı malzemeler güncelliğini yitirmiş.

Genellikle, bir nesne örneği oluşturulurken bir sınıf oluşturucu çağrılır ve nesnenin ihtiyaç duyduğu tüm değerler oluşturucuya bağımsız değişken olarak geçirilir. Bu bir bağımlılık ekleme örneğidir ve özellikle oluşturucu ekleme olarak bilinir. Nesnenin ihtiyaç duyduğu bağımlılıklar oluşturucuya eklenir.

Bağımlılık ekleme, arabirim türleri olarak bağımlılıkları belirterek somut türlerin bu türlere bağlı koddan ayrıştırılması sağlar. Genellikle, arabirimler ve soyut türler ile bu türleri uygulayan veya genişleten somut türler arasındaki kayıtların ve eşlemelerin listesini tutan bir kapsayıcı kullanır.

Özellik ayarlayıcı ekleme ve yöntem çağrısı ekleme gibi başka bağımlılık ekleme türleri de vardır, ancak bunlar daha az görülür. Bu nedenle, bu bölüm yalnızca bağımlılık ekleme kapsayıcısı ile oluşturucu ekleme işlemi gerçekleştirmeye odaklanacaktır.

Bağımlılık Eklemeye Giriş

Bağımlılık ekleme, Denetimin Ters Çevrilmesi (IoC) deseninin özelleştirilmiş bir sürümüdür ve burada ters çevrilen sorun, gerekli bağımlılığı elde etme işlemidir. Bağımlılık ekleme ile başka bir sınıf çalışma zamanında bir nesneye bağımlılık eklemekle sorumludur. Aşağıdaki kod örneği bağımlılık ekleme kullanılırken sınıfın ProfileViewModel nasıl yapılandırıldığını gösterir:

public class ProfileViewModel : ViewModelBase  
{  
    private IOrderService _orderService;  

    public ProfileViewModel(IOrderService orderService)  
    {  
        _orderService = orderService;  
    }  
    ...  
}

Oluşturucu, ProfileViewModel başka bir IOrderService sınıf tarafından eklenen bir örneği bağımsız değişken olarak alır. sınıfındaki ProfileViewModel tek bağımlılık arabirim türündedir. Bu nedenle, ProfileViewModel sınıfın nesnenin örneğini oluşturmadan IOrderService sorumlu olan sınıfı hakkında herhangi bir bilgisi yoktur. Nesnesinin örneğini oluşturma IOrderService ve sınıfına ProfileViewModel eklemeden sorumlu sınıf, bağımlılık ekleme kapsayıcısı olarak bilinir.

Bağımlılık ekleme kapsayıcıları, sınıf örneklerinin örneğini oluşturacak ve kapsayıcının yapılandırmasına göre yaşam sürelerini yönetecek bir tesis sağlayarak nesneler arasındaki bağlantıyı azaltır. Nesneleri oluşturma sırasında kapsayıcı, nesnenin gerektirdiği tüm bağımlılıkları buna ekler. Bu bağımlılıklar henüz oluşturulmadıysa kapsayıcı önce bağımlılıklarını oluşturur ve çözer.

Not

Bağımlılık ekleme, fabrikalar kullanılarak el ile de uygulanabilir. Ancak kapsayıcı kullanmak, ömür yönetimi ve derleme taraması aracılığıyla kayıt gibi ek özellikler sağlar.

Bağımlılık ekleme kapsayıcısı kullanmanın çeşitli avantajları vardır:

  • Kapsayıcı, bir sınıfın bağımlılıklarını bulma ve yaşam sürelerini yönetme gereksinimini ortadan kaldırır.
  • Kapsayıcı, sınıfı etkilemeden uygulanan bağımlılıkların eşlenmesine olanak tanır.
  • Kapsayıcı, bağımlılıkların sahte olmasına izin vererek test edilebilirliği kolaylaştırır.
  • Kapsayıcı, uygulamaya yeni sınıfların kolayca eklenmesini sağlayarak sürdürülebilirliği artırır.

MVVM kullanan bir Xamarin.Forms uygulama bağlamında, bağımlılık ekleme kapsayıcısı genellikle görünüm modellerini kaydetmek ve çözümlemek, hizmetleri kaydetmek ve görünüm modellerine eklemek için kullanılır.

Uygulamada görünüm modeli ve hizmet sınıflarının örneğini yönetmek için TinyIoC kullanan eShopOnContainers mobil uygulamasıyla birçok bağımlılık ekleme kapsayıcısı mevcuttur. TinyIoC, bir dizi farklı kapsayıcı değerlendirildikten sonra seçildi ve iyi bilinen kapsayıcıların çoğuna kıyasla mobil platformlarda üstün performans sunuyor. Gevşek bağlantılı uygulamalar oluşturulmasını kolaylaştırır ve tür eşlemelerini kaydetme, nesneleri çözümleme, nesne yaşam sürelerini yönetme ve bağımlı nesneleri çözümlediğini nesnelerin oluşturucularına ekleme yöntemleri de dahil olmak üzere bağımlılık ekleme kapsayıcılarında yaygın olarak bulunan tüm özellikleri sağlar. TinyIoC hakkında daha fazla bilgi için bkz . TinyIoC on github.com.

TinyIoC'de TinyIoCContainer türü bağımlılık ekleme kapsayıcısını sağlar. Şekil 3-1'de bu kapsayıcı kullanılırken bir nesne örneği IOrderService oluşturan ve sınıfına ProfileViewModel eklenen bağımlılıklar gösterilmektedir.

Dependencies example when using dependency injection

Şekil 3-1: Bağımlılık ekleme kullanılırken bağımlılıklar

Çalışma zamanında kapsayıcı, bir ProfileViewModel nesnenin örneğini oluşturabilmesi için önce arabirimin IOrderService hangi uygulamasının örneklenmesi gerektiğini bilmelidir. Bunun için şunlar gereklidir:

  • Arabirimi uygulayan bir nesnenin örneğini oluşturma işlemine IOrderService karar veren kapsayıcı. Bu, kayıt olarak bilinir.
  • Arabirimini uygulayan nesnenin ve nesnesinin örneğini IOrderServiceProfileViewModel oluşturan kapsayıcı. Bu çözüm olarak bilinir.

Sonunda uygulama nesnesini kullanmayı ProfileViewModel tamamlar ve çöp toplama için kullanılabilir hale gelir. Bu noktada, diğer sınıflar aynı örneği paylaşmıyorsa çöp toplayıcı örneği atmalıdır IOrderService .

İpucu

Kapsayıcıdan bağımsız kod yazma. Uygulamayı her zaman kullanılan bağımlılık kapsayıcısından ayırmaya yönelik kapsayıcıdan bağımsız kod yazmaya çalışın.

Kayıt

Bağımlılıkların bir nesneye eklenebilmesi için önce bağımlılık türlerinin kapsayıcıya kaydedilmesi gerekir. Bir türün kaydedilmesi genellikle kapsayıcıya bir arabirim ve arabirimi uygulayan somut bir tür geçirmeyi içerir.

Kapsayıcıdaki türleri ve nesneleri kod aracılığıyla kaydetmenin iki yolu vardır:

  • Kapsayıcıya bir tür veya eşleme kaydedin. Gerektiğinde kapsayıcı, belirtilen türün bir örneğini oluşturur.
  • Kapsayıcıdaki mevcut bir nesneyi tekil olarak kaydedin. Gerektiğinde, kapsayıcı var olan nesneye bir başvuru döndürür.

İpucu

Bağımlılık ekleme kapsayıcıları her zaman uygun değildir. Bağımlılık ekleme, küçük uygulamalar için uygun veya yararlı olmayan ek karmaşıklık ve gereksinimler sunar. Bir sınıfın herhangi bir bağımlılığı yoksa veya diğer türler için bir bağımlılık değilse, bunu kapsayıcıya koymak mantıklı olmayabilir. Ayrıca, bir sınıfın türüne tam sayı olan ve hiçbir zaman değişmeyecek tek bir bağımlılık kümesi varsa, bunu kapsayıcıya koymak mantıklı olmayabilir.

Bağımlılık ekleme gerektiren türlerin kaydı bir uygulamadaki tek bir yöntemde gerçekleştirilmelidir ve bu yöntem, uygulamanın sınıfları arasındaki bağımlılıkların farkında olduğundan emin olmak için uygulamanın yaşam döngüsünün başlarında çağrılmalıdır. eShopOnContainers mobil uygulamasında bu, nesnesini oluşturan TinyIoCContainer sınıfı tarafından ViewModelLocator gerçekleştirilir ve uygulamada bu nesneye başvuru tutan tek sınıftır. Aşağıdaki kod örneği, eShopOnContainers mobil uygulamasının sınıfındaki nesneyi nasıl bildirdığını TinyIoCContainerViewModelLocator gösterir:

private static TinyIoCContainer _container;

Türler oluşturucuya ViewModelLocator kaydedilir. Bu, önce aşağıdaki kod örneğinde gösterilen bir TinyIoCContainer örnek oluşturularak gerçekleştirilir:

_container = new TinyIoCContainer();

Türler daha sonra nesnesine TinyIoCContainer kaydedilir ve aşağıdaki kod örneği, tür kaydının en yaygın biçimini gösterir:

_container.Register<IRequestProvider, RequestProvider>();

Register Burada gösterilen yöntem bir arabirim türünü somut bir türle eşler. Varsayılan olarak, her arabirim kaydı tekil olarak yapılandırılır ve böylece her bağımlı nesne aynı paylaşılan örneği alır. Bu nedenle, kapsayıcıda yalnızca tek RequestProvider bir örnek bulunur ve bir oluşturucu aracılığıyla ekleme IRequestProvider gerektiren nesneler tarafından paylaşılır.

Somut türler, aşağıdaki kod örneğinde gösterildiği gibi doğrudan bir arabirim türünden eşleme olmadan da kaydedilebilir:

_container.Register<ProfileViewModel>();

Varsayılan olarak, her somut sınıf kaydı, her bağımlı nesnenin yeni bir örnek alması için çok örnekli olarak yapılandırılır. Bu nedenle, çözümlendiğinde ProfileViewModel yeni bir örnek oluşturulur ve kapsayıcı gerekli bağımlılıklarını ekler.

Çözüm

Bir tür kaydedildikten sonra çözümlenebilir veya bağımlılık olarak eklenebilir. Bir tür çözümlendiğinde ve kapsayıcının yeni bir örnek oluşturması gerektiğinde, tüm bağımlılıkları örneğe ekler.

Genellikle, bir tür çözümlendiğinde üç şeyden biri gerçekleşir:

  1. Tür kaydedilmemişse kapsayıcı bir özel durum oluşturur.
  2. Tür tekil olarak kaydedildiyse, kapsayıcı singleton örneğini döndürür. Tür ilk kez çağrılırsa, kapsayıcı gerekirse bunu oluşturur ve buna bir başvuru tutar.
  3. Tür tekil olarak kaydedilmemişse kapsayıcı yeni bir örnek döndürür ve buna başvuru sağlamaz.

Aşağıdaki kod örneği, daha önce TinyIoC'ye kaydedilmiş olan türün nasıl RequestProvider çözümlenebileceğini gösterir:

var requestProvider = _container.Resolve<IRequestProvider>();

Bu örnekte TinyIoC'den türün somut türünü IRequestProvider ve bağımlılıkları çözmesi istenir. Genellikle, Resolve belirli bir türün örneği gerektiğinde yöntemi çağrılır. Çözümlenen nesnelerin ömrünü denetleme hakkında bilgi için bkz . Çözümlenen Nesnelerin Yaşam Ömrünü Yönetme.

Aşağıdaki kod örneği, eShopOnContainers mobil uygulamasının model türlerini ve bağımlılıklarını nasıl görüntüleyişini gösterir:

var viewModel = _container.Resolve(viewModelType);

Bu örnekte TinyIoC'den istenen görünüm modeli için görünüm modeli türünü çözümlemesi istenir ve kapsayıcı bağımlılıkları da çözer. Türü çözümlerken ProfileViewModel çözümlenmesi gereken bağımlılıklar bir ISettingsService nesne ve nesnedir IOrderService . ve OrderService sınıflarını kaydederken arabirim kayıtları kullanıldığından SettingsService TinyIoC, ve OrderService sınıfları için SettingsService tekil örnekler döndürür ve sonra bunları sınıfın ProfileViewModel oluşturucusna geçirir. eShopOnContainers mobil uygulamasının modelleri nasıl oluşturup görünümlerle ilişkilendirmesi hakkında daha fazla bilgi için bkz . Model Bulucuyu Görüntüle ile Modeli Otomatik Olarak Oluşturma.

Not

Kapsayıcıya türleri kaydetme ve çözmenin, özellikle uygulamadaki her sayfa gezintisi için bağımlılıkların yeniden oluşturulması durumunda kapsayıcının her türü oluşturmak için yansıma kullanması nedeniyle performans maliyeti vardır. Çok veya derin bağımlılıklar varsa oluşturma maliyeti önemli ölçüde artabilir.

Çözümlenen Nesnelerin Yaşam Ömrünü Yönetme

Somut bir sınıf kaydı kullanarak bir tür kaydettikten sonra TinyIoC için varsayılan davranış, tür her çözümlendiğinde veya bağımlılık mekanizması örnekleri diğer sınıflara eklediğinizde kayıtlı türün yeni bir örneğini oluşturmaktır. Bu senaryoda kapsayıcı, çözümlenen nesneye bir başvuru tutmaz. Ancak, arabirim kaydını kullanarak bir tür kaydederken TinyIoC için varsayılan davranış nesnenin ömrünü tekil olarak yönetmektir. Bu nedenle, kapsayıcı kapsam dahilindeyken örnek kapsam içinde kalır ve kapsayıcı kapsamın dışına çıktığında ve atık toplandığında veya kod kapsayıcıyı açıkça attığında atılır.

Varsayılan TinyIoC kayıt davranışı akıcı AsSingleton ve AsMultiInstance API yöntemleri kullanılarak geçersiz kılınabilir. Örneğin, AsSingleton yöntemi yöntemiyle Register kullanılabilir, böylece kapsayıcı yöntemi çağırırken Resolve türün tek bir örneğini oluşturur veya döndürür. Aşağıdaki kod örneği TinyIoC'ye sınıfının tek bir örneğini oluşturma talimatını LoginViewModel gösterir:

_container.Register<LoginViewModel>().AsSingleton();

Tür ilk kez LoginViewModel çözümlendiğinde kapsayıcı yeni LoginViewModel bir nesne oluşturur ve buna bir başvuru tutar. öğesinin LoginViewModelsonraki çözümlerinde kapsayıcı, daha önce oluşturulmuş olan nesneye LoginViewModel bir başvuru döndürür.

Not

Tekil olarak kaydedilen türler, kapsayıcı atıldığında atılır.

Özet

Bağımlılık ekleme, somut türlerin bu türlere bağlı koddan ayrıştırılmalarına olanak tanır. Genellikle, arabirimler ve soyut türler ile bu türleri uygulayan veya genişleten somut türler arasındaki kayıtların ve eşlemelerin listesini tutan bir kapsayıcı kullanır.

TinyIoC, iyi bilinen kapsayıcıların çoğuna kıyasla mobil platformlarda üstün performans sunan basit bir kapsayıcıdır. Gevşek bir şekilde bağlanmış uygulamalar oluşturulmasını kolaylaştırır ve tür eşlemelerini kaydetme, nesneleri çözümleme, nesne yaşam sürelerini yönetme ve bağımlı nesneleri çözümlediğinden nesne oluşturucularına ekleme yöntemleri de dahil olmak üzere bağımlılık ekleme kapsayıcılarında yaygın olarak bulunan tüm özellikleri sağlar.