2012-02-22 10 views
8

Nếu tôi có một lớp, có phụ thuộc kép trên cùng một loại (cần hai trường hợp khác nhau), nếu khác biệt duy nhất giữa các cá thể là phụ thuộc sâu hơn, cách tốt nhất để có Ninject thực hiện DI và giữ hai đồ thị riêng biệt?Ninject: Tiêm hai đối tượng khác nhau cùng loại

đồ thị đối tượng Ví dụ:

foo → ClassA → ClassB 
bar → ClassA → ClassB 

Lớp C 's constructor:

public class C 
{ 
    public C(ClassB foo, ClassB bar) { … } 
} 

Vì vậy, làm thế nào để chắc chắn rằng ClassB instantiated với foo được cung cấp như các ClassB dependancy foobar & hellip; bar?

Chỉ cần cho một số nền tảng, tôi đã có một số yêu cầu thay đổi, vì vậy tôi cần phải thay thế một kho lưu trữ chỉ ghi (IAdd) với một hỗn hợp chỉ ghi kho

public class CompositeWriteRepository<T> : IAdd<T> 
{ 
    public CompositeWriteRepository(IAdd<T> foo, IAdd<T> bar, Func<T, bool> descriminator) { ... } 
    public Add(T entity) 
    { 
     if (descriminator(entity)) { 
      foo.Add(entity); 
     } else { 
      bar.Add(entity); 
     } 
    }   
} 

Với chế giễu, đó là đủ dễ dàng, Tôi chỉ có thể tiêm tên bằng cách sử dụng:

kernel.Bind<IAdd<EntityType>>().To<fooRepository>().Named("foo"); 
kernel.Bind<IAdd<EntityType>>().To<barRepository>().Named("bar"); 

kernel.Bind<IAdd<EntityType>>().To<CompositeWriterRepository<EntityType>>() 
    .WithConstructorArgument("foo", x => x.Kernel.Get<IAdd<EntityType>>("foo") 
    .WithConstructorArgument("bar", x => x.Kernel.Get<IAdd<EntityType>>("bar"); 

Sự cố xảy ra khi tôi sử dụng kho lưu trữ thực; foobar cuối cùng ghi vào tệp để chúng cần các tên tệp khác nhau. Vì chúng là các kho lưu trữ StreamWriter, một trong các phụ thuộc của chúng thực sự có hai tên tệp khác nhau.

string FileName → FileStreamWriterFactory → StreamRepository → CompositeRepository 

Cách duy nhất tôi đã tìm thấy cho đến nay để xây dựng mọi thứ là để thực hiện một tên FileName, tên FileStreamWriterFactory, tên StreamRepository × 2 (một lần cho foo và một lần cho bar). Điều này có vẻ như rất nhiều công việc, vì vậy tôi hy vọng có giải pháp tốt hơn.

Tôi có thể tái kiến ​​trúc nếu cần, nó cảm thấy như một cách thanh lịch để nhanh chóng thêm vào việc phân tách các mục khi yêu cầu thay đổi. Tôi nhận ra rằng tất cả các lớp học của tôi đều khá cụ thể, nhưng tôi nghĩ rằng trách nhiệm duy nhất sẽ hỗ trợ điều này và trong trường hợp của chúng tôi, chúng tôi viết một loạt các ứng dụng nhỏ và có nhiều yêu cầu hơn để chúng tôi có thể thực hiện tốt. đặt xung quanh rằng tôi về cơ bản chỉ cần cấu hình lại cho các nhiệm vụ khác nhau.

Giải pháp
Remo Khủng bố sẽ nhận được tín dụng; của ông có lẽ là thực hành tốt nhất.

Những gì tôi thực sự đã làm là tạo tiện ích mới

public static bool WhenAnchester(this IRequest request, Func<IRequest, bool> conditions) 
{ 
    var parentContext = request.ParentContext; 
    if (parentContext == null) { 
      return false; 
    } 

    return conditions(parentContext.Request) || 
     parentContext.Request.WhenAnchester(conditions); 
} 

này sau đó cho tôi dễ dàng kiểm soát mà tập tin được tiêm vào mà kho.

kernel.Bind<string>().ToConstant("Foo.txt") 
    .When(x => x.Target.Name == "filepath" && 
       x.WhenAnchester(t => t.Target != null && t.Target.Name == "Dest1")); 

kernel.Bind<string>().ToConstant("Bar.txt") 
    .When(x => x.Target.Name == "filepath" && 
       x.WhenAnchester(t => t.Target != null && t.Target.Name == "Dest2")); 

Có lẽ một giải pháp tốt hơn, vì vậy tôi không cần thiết nên giới thiệu cho người khác, nhưng nó hoạt động tốt cho tôi.

+1

Các vùng chứa DI được cho là không ràng buộc các phụ thuộc từ các triển khai cụ thể, do đó các lớp chỉ dựa trên các giao diện. Và bạn muốn điều ngược lại, điều chúng tôi cố gắng tránh theo ý tưởng của IoC. – zerkms

+0

Tôi đang trao đổi một triển khai IAdd cho một cái khác và tôi đã làm như vậy chỉ được viết một lớp mới (tổng hợp IAdd) và bằng cách thay đổi gốc thành phần của tôi. Cấp, nó không phải là một dấu hiệu rất mạnh mẽ tôi đang sử dụng DI một cách chính xác, nhưng điều đó không có vẻ giống như một mã sniff với tôi. Biến chứng thực sự là do lớp của tôi không quan tâm, vì vậy tôi kết thúc với hai đồ thị phụ thuộc tương tự nhau và thành phần của tôi cần phải quan tâm (và nên) vì yêu cầu kinh doanh làm cho nó như vậy. Tôi có thể giới thiệu hai loại mới để phân biệt, nó có thể sạch hơn, nhưng cũng có nhiều thay đổi hơn. –

Trả lời