Aslında, “doğru” yol, kesinlikle başka bir seçenek olmadığı sürece (fabrika testlerinde ve bazı cihazlarda olduğu gibi - üretim kodu için bir fabrika kullanmazsınız) kesinlikle bir fabrika kullanmamaktır! Bunu yapmak aslında bir anti-kalıptır ve ne pahasına olursa olsun kaçınılmalıdır. Bir DI konteyner arkasında bütün mesele gadget işi yapmak için izin vermektir için size.
Önceki bir yayında yukarıda belirtildiği gibi, IoC gadget'ınızın uygulamanızda çeşitli bağımlı nesnelerin yaratılması sorumluluğunu üstlenmesini istiyorsunuz. Bu, DI gadget'ınızın çeşitli örnekleri kendisi oluşturmasına ve yönetmesine izin vermek anlamına gelir. Bu DI'nin arkasındaki asıl nokta - nesnelerinizin bağlı oldukları nesneleri nasıl yaratacağını ve / veya yöneteceğini ASLA bilmemesi gerekir. Aksi taktirde gevşek bağlantı kopar .
Mevcut bir uygulamayı tüm DI'ye dönüştürmek büyük bir adımdır, ancak bunu yaparken bariz zorlukları bir kenara koymak, aynı zamanda (sadece hayatınızı biraz kolaylaştırmak için) ciltleme işlemlerinizi otomatik olarak gerçekleştirecek bir DI aracını keşfetmek isteyecektir. (Ninject gibi bir şeyin özü "kernel.Bind<someInterface>().To<someConcreteClass>()"
, arayüz bildirimlerinizi bu arabirimleri uygulamak için kullanmak istediğiniz somut sınıflarla eşleştirmek için yaptığınız çağrılardır. DI gadget'ınızın yapıcı çağrılarınızı engellemesine ve sağlamasına olanak sağlayan "Bağlama" çağrılarıdır. gerekli bağımlı nesne örnekleri: Bazı sınıflar için tipik bir kurucu (burada gösterilen sözde kod):
public class SomeClass
{
private ISomeClassA _ClassA;
private ISomeOtherClassB _ClassB;
public SomeClass(ISomeClassA aInstanceOfA, ISomeOtherClassB aInstanceOfB)
{
if (aInstanceOfA == null)
throw new NullArgumentException();
if (aInstanceOfB == null)
throw new NullArgumentException();
_ClassA = aInstanceOfA;
_ClassB = aInstanceOfB;
}
public void DoSomething()
{
_ClassA.PerformSomeAction();
_ClassB.PerformSomeOtherActionUsingTheInstanceOfClassA(_ClassA);
}
}
Not hiçbir yerde bu kodda herhangi bir kod SomeConcreteClassA veya SomeOtherConcreteClassB oluşturulan bu / yönetilen / salınan örneği ya idi. Nitekim, somut sınıflara bile değinilmemiştir. Peki ... büyü nerede oldu?
Uygulamanızın başlangıç bölümünde, aşağıdakiler gerçekleşti (yine, bu sözde kod ama gerçek (Ninject) olayına oldukça yakın ...):
public void StartUp()
{
kernel.Bind<ISomeClassA>().To<SomeConcreteClassA>();
kernel.Bind<ISomeOtherClassB>().To<SomeOtherConcreteClassB>();
}
Bu küçük kod parçası, Ninject gadget'ına yapıcıları aramasını, onları taramasını, işlemek için yapılandırılmış olduğu arabirimlerin örneklerini aramasını söyler (bu "Bağlama" çağrılarıdır) ve sonra her yerde somut sınıfın bir örneğini yaratıp değiştirir örnek referanslıdır.
Ninject'i, Ninject.Extensions.Conventions (yine başka bir NuGet paketi) olarak adlandırılan ve bu çalışmanın büyük kısmını sizin için yapacak olan iyi bir araç var. Bunu kendiniz oluştururken yaşayacağınız mükemmel öğrenme deneyiminden uzaklaşmamak, ancak kendinizi başlatmak için bu araştırmanın bir aracı olabilir.
Bellek hizmet ederse, Unity (şu anda Microsoft'tan resmi bir Açık Kaynak projesidir) aynı şeyi yapan bir yöntem çağrısına veya ikisine birden sahipse, diğer araçların benzer yardımcıları vardır.
Hangi yolu seçerseniz seçin, DI eğitiminizin büyük bir kısmı için kesinlikle Mark Seemann'in kitabını okuyun, ancak, yazılım mühendisliği dünyasının (Mark gibi) "Büyük Olanlar" ın bile göz kamaştırıcı hatalar yapabileceğine dikkat edilmelidir - Mark her şeyi unuttu Kitabında Ninject yani sadece Ninject için yazılmış başka bir kaynaktır. Ben ve onun iyi bir okuma var: Bağımlılık Enjeksiyonu için Ninject Mastering