Varlıklar / iş nesneleri için bağımlılıkları çözmek için neden bir IoC konteyneri kullanmıyorsunuz?


82

DI'nın arkasındaki konsepti anlıyorum, ancak sadece farklı IoC konteynerlerinin neler yapabileceğini öğreniyorum. Görünüşe göre çoğu insan, vatansız hizmetleri bağlamak için IoC konteynerlerini kullanmayı savunuyor, ancak bunları varlıklar gibi durum bilgisi olan nesneler için kullanmaya ne dersiniz?

Doğru ya da yanlış, bu davranış dışarıdan bir sınıf gerektirse bile, normalde varlıklarımı davranışla doldururum. Misal:

public class Order : IOrder
{

    private string _ShipAddress;
    private IShipQuoter _ShipQuoter;

    public Order(IOrderData OrderData, IShipQuoter ShipQuoter)
    {
        // OrderData comes from a repository and has the data needed 
        // to construct order
        _ShipAddress = OrderData.ShipAddress;  // etc.
        _ShipQuoter = ShipQuoter;

    }

    private decimal GetShippingRate()
    {
        return _ShipQuoter.GetRate(this);
    }
}

Gördüğünüz gibi, bağımlılıklar Oluşturucu Eklendi. Şimdi birkaç soru için.

  1. Varlıklarınızın ShipQuoter gibi dış sınıflara bağlı olması kötü bir uygulama olarak kabul edilir mi? Tanımı doğru anlarsam, bu bağımlılıkları ortadan kaldırmak beni anemik bir alana yönlendiriyor gibi görünüyor.

  2. Bu bağımlılıkları çözmek ve gerektiğinde bir varlık oluşturmak için bir IoC konteyneri kullanmak kötü bir uygulama mı? Bunu yapmak mümkün mü?

Herhangi bir fikir için teşekkürler.


3
Sadece işinizi kolaylaştırdığı için yapmanız gereken şeyleri yapın, muhtemelen bunu yapmanız gerektiği için değil
Omu

28
Kendi kendini yetiştiren bir programcı olarak, bu rotaya gittim ve şirketim tarafından şu anda kullanılan yazılıma yol açtı. Prosedür / işlem betiği tabanlı bir yazılım, kısmen en kolay ve daha iyi bilmediğim için parti olduğu için ortaya çıktı. Sürdürmek ve genişletmek kesinlikle acı verici, bu yüzden onu yeniden yazmak için zaman ayırıyorum ve bu sorunları zaten aşmış insanlardan aynı hataları nasıl yapmayacağına dair tavsiye alıyorum.
Casey Wilkins

Yanıtlar:


90

İlk soru cevaplaması en zor olanıdır. Varlıkların dış sınıflara bağlı olması kötü bir uygulama mı? Kesinlikle yapılacak en yaygın şey bu değil.

Örneğin, Varlıklarınıza bir Depo enjekte ederseniz, Etkin Kayıt modelinin bir uygulamasına sahip olursunuz . Bazı insanlar sağladığı kolaylık için bu kalıbı beğenirken, diğerleri (benim gibi) Tek Sorumluluk İlkesini (SRP) ihlal ettiği için onu bir kod kokusu veya anti-kalıp olarak değerlendiriyor .

Varlıklara diğer bağımlılıkları enjekte etmenin sizi aynı yöne (SRP'den uzağa) çekeceğini iddia edebilirsiniz. Öte yandan, bunu yapmazsanız, çekimin Anemik Alan Modeli'ne doğru olduğu konusunda kesinlikle haklısınız .

Greg Young'un (terk edilmiş) DDDD hakkındaki makalesine rastlayana kadar uzun bir süre tüm bunlarla mücadele ettim ve o basmakalıp n-katmanlı / n-katmanlı mimarinin neden her zaman CRUDy (ve dolayısıyla anemik) olacağını açıkladı .

Odağımızı İsimler yerine Komutlar ve Olaylar olarak Etki Alanı nesnelerini modellemeye kaydırmak, uygun bir nesne yönelimli etki alanı modeli oluşturmamızı sağlıyor gibi görünüyor.

İkinci soruyu cevaplamak daha kolaydır. Çalışma zamanında örnekler oluşturmak için her zaman bir Soyut Fabrika kullanabilirsiniz . Castle Windsor ile Tipik Fabrika Tesisi'ni bile kullanabilirsiniz, bu da sizi fabrikaları manuel olarak uygulama yükünden kurtarır.


Teşekkürler Mark. Typed Factory'yi gördüm ve Abstract Factory yöntemiyle ilgili diğer gönderilerinizi okudum, ancak varlıkları çözmek için kullanıldığına dair herhangi bir örnek görmedim. Bunun nedeni, çoğu insanın varlıklarını depo dışında herhangi bir bağımlılık olmadan tasarlaması mı? Dış bağımlılıkları olan varlıklarımı çözmek için Typed Factory gibi bir şeyi titizlikle kullanırsam yolun aşağısında başım belaya girer mi?
Casey Wilkins

Söylemeye çalıştığım şey, Varlıklarınız diğer Varlıklara vb. Erişebilecek başka ortak çalışanlar içeriyorsa, her türlü bakım sorunuyla karşılaşabilirsiniz - SRP ihlalleri ve N + 1 sorunlarından bahsetmeye bile gerek yok. Bu nedenle Evans, her Varlığa bir Toplu Kök olarak davranılmasını önerir.
Mark Seemann

Örneğimde ShipQuoter, bir web hizmetinden (ör. UPS) bir sipariş için kargo ücretlerini alıyor. Bunu IOrder'ı kabul eden bir Hizmet mi yaparsınız yoksa Order.GetRates gibi etki alanı nesnesinin bir parçası yapar mısınız?
Casey Wilkins

En başta senkronize bir çekişi nasıl önleyebileceğimi bulmak için çok zaman harcardım. Verileri ne kadar senkronize, engelleyici tarzda çekerseniz tasarımınız o kadar kırılgan hale gelir. Bu nedenle CQRS bu kadar çekici bir alternatiftir.
Mark Seemann

4
Greg'in gazetesiyle bağlantınız kesildi. Ama yine de burada mevcuttur . Ve bu daha yeni bir sürüm gibi görünüyor .
BornToCode

1

Bunun eski bir gönderi olduğunu biliyorum ama eklemek istedim. Ctor'da soyutlanmış bir depoya girseniz bile etki alanı varlığı kendini sürdürmemelidir. Bunu önermemin nedeni yalnızca SRP'yi ihlal etmesi değil, aynı zamanda DDD'nin toplamasına da aykırı. Açıklayayım, DDD, doğası gereği derin grafiklere sahip karmaşık uygulamalar için uygundur, bu nedenle, altta yatan "çocuklarda" değişiklikleri kalıcı kılmak için toplu veya bileşik kökler kullanırız, bu nedenle, tek tek çocuklara kalıcılık enjekte ettiğimizde, çocukların sahip olduğu ilişkiyi ihlal ederiz yaşam döngüsü veya toplamadan "sorumlu" olması gereken bileşik veya toplu kök. Elbette bileşik kök veya toplam da kendi grafiğinde kalmaz. Bir diğeri, DDD nesnelerinin enjekte edilmesi bağımlılıkları ile ilgili, enjekte edilen bir etki alanı nesnesinin, durumunu hidratlamak için başka bir olay gerçekleşene kadar etkin bir şekilde hiçbir duruma sahip olmamasıdır. Kodun herhangi bir tüketicisi, kapsüllemeyi ihlal eden iş davranışını başlatmadan önce etki alanı nesnesini başlatmaya veya kurmaya zorlanacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.