2016-04-14 14 views
2

Tüm amacı iki veri kaynağını tüketmek ve benzerlikleri ve farklılıkları açığa çıkarmak olan bir uygulama yazıyorum (bir ASP.NET web API'sı aracılığıyla görünür).Aynı arabirimi uygulayan iki nesneye bağımlılığı olan Basit Enjektör

public class FooController : WebAPI 
{ 
    public FooController(IFooRepository repoFromSourceA, IFooRepository repoFromSourceB) 
    { 
     ... 
    } 
} 

bir (kaynağı A ve SourceB dönüşüm gerçekleştiremez) container.RegisterCollection(..) imkansız (veya çok tehlikeli) kullanmak için yapmak gibi görünüyor hangi kaynağın ait olduğu ayrım bakımı: Yani API aşağıdaki kurulum vardır. Ayrıca, bir sınıf her iki uygulamayı da tüketiyor olduğundan, dekoratör uyumsuz gibi görünüyor.

Bu bağımlılık enjeksiyonunu nasıl kurabilirim?

+0

Kimsenin bu soruyu cevaplayabilmesinden önce en önemli soru, iki argümanın (yanlışlıkla) değiştirilmesinin ardından FooController’a ne olacağıdır. Yani yeni FooController'ı (yeni RepoB(), yeni RepoA()) 'nı derlersek, FooController 'hala düzgün çalışır mı yoksa kırılır mı (örneğin bir istisna atar)? – Steven

+0

Kırılmaz (istisnalar atılmaz), ancak API arayan kişiye yalan söyler. Bazı aramalar, "A'da var olan ama bana B'de olmayan öğeler ver" biçimindedir. Takas edildiyse, arayanlar öğeleri (veya hiçbir eşyayı) geri alır, ancak sonuç hatalı olur. –

cevap

6

Sahip olduğunuz soru çok yaygın bir sorundur. Bağımlılık Enjeksiyonu ile başlarken birçok geliştirici bununla mücadele eder. Bunu yaparken, Liskov Substitution Principle'u (LSP) ihlal edip etmediğinizi öğrenmek her zaman önemlidir, çünkü bunu yaptığınızda, iki ayrı arabirim kullanmalısınız. Asla unutma: Bir arayüz sadece metot imzalarından daha fazlasıdır. Bu sözleşmenin uygulamalarının nasıl davrandığına ve geri döndüklerine dair bir sözleşmedir.

Yorumunuz, davranışları birbirinin aynısı olduğundan ve birbirleri için değiştirilebildiğinden (uygulamayı bozabilir, ancak tüketiciyi kırmayacak) LSP'yi ihlal etmediğinizi gösterir gibi görünüyor.

Basit Enjektörde işlenmenin yolu, yöntemlerini kullanarak context based injection kullanıyordur. Örneğin:

container.RegisterConditional<IFooRepository, FooRepoA>(
    c => c.Consumer.Target.Parameter.Name.Contains("SourceA")); 
container.RegisterConditional<IFooRepository, FooRepoB>(
    c => c.Consumer.Target.Parameter.Name.Contains("SourceB")); 

Burada RegisterConditional yöntem bağımlılık enjekte edilir tüketici, yapıcı parametresi "kaynağı A" ya da "SourceB" içeren bir ada sahip bir yüklemi ile birlikte verilir.

+0

Mükemmel; tam olarak istediğime benziyor. Ve evet, LSP'yi ihlal etmekten biraz korktum, bu yüzden yardım istemeden önce birden çok kez kontrol ettiğim bir şey. –