2011-07-19 6 views
5

Vì vậy, chúng ta hãy nói rằng tôi có một giao diện IThingFactory:Dependency Injection: Làm thế nào để cấu hình các ràng buộc giao diện cho gói

public interface IThingFactory 
{ 
    Thing GetThing(int thingId); 
} 

Bây giờ, chúng ta hãy nói rằng tôi có một thực hiện cụ thể để lấy Thing s từ một cơ sở dữ liệu. Bây giờ, chúng ta hãy nói rằng tôi có một triển khai cụ thể kết thúc tốt đẹp hiện có IThingFactory và kiểm tra sự hiện diện của Thing trong bộ nhớ cache trong bộ nhớ trước khi chạm vào gói IThingFactory. Một cái gì đó như:

public class CachedThingFactory : IThingFactory 
{ 
    private IThingFactory _wrapped; 
    private Dictionary<int, Thing> _cachedThings; 

    public CachedThingFactory(IThingFactory wrapped) 
    { 
     this._wrapped = wrapped; 
     _cachedThings = new Dictionary<int,Thing>(); 
    } 

    public Thing GetThing(int thingId) 
    { 
     Thing x; 
     if(_cachedThings.TryGetValue(thingId, out x)) 
      return x; 

     x = _wrapped.GetThing(thingId); 

     _cachedThings[thingId] = x; 

     return x; 
    } 
} 

Làm thế nào tôi có thể đối phó với một tình huống như thế này sử dụng dependency injection với một cái gì đó giống như, nói, Ninject, để tôi có thể cấu hình các container DI vì vậy mà tôi có thể tiêm hoặc loại bỏ một proxy caching như thế này , hoặc, nói, một cái gì đó mà đăng nhập, hoặc (chèn ở đây)?

Trả lời

5

Bạn có thể làm một cái gì đó dọc theo dòng:

Bind<IThingFactory>().To<DefaultThingFactory>().WhenInjectedInto<CachedThingFactory>(); 
Bind<IThingFactory>().To<CachedThingFactory>(); 

này sẽ cho phép người tiêu dùng không cần phải xác định một thuộc tính tên, và vẫn còn tương đối dễ dàng để tăng cường hơn nữa. Nếu sau này bạn muốn thêm lớp "trang trí" bổ sung để ghi nhật ký, bạn có thể làm:

Không đẹp nhất, nhưng nó hoạt động.

+0

Thậm chí không biết rằng một phương thức WhenInjectedInto() đã tồn tại. Cảm ơn! – FMM

2

Một trong những lợi ích của khung DI là bạn không phải làm những việc như thế này. Ninject có các phạm vi khác nhau mà bạn có thể sử dụng để xác định tuổi thọ của các đối tượng của bạn. Nó sẽ xử lý bộ nhớ đệm và các công cụ cho bạn.

đọc thêm ở đây: http://kohari.org/2009/03/06/cache-and-collect-lifecycle-management-in-ninject-20/

+0

Không chính xác những gì tôi đang hỏi. Tôi quen thuộc với phạm vi đối tượng của Ninject, và tôi đang tận dụng phạm vi yêu cầu và phạm vi singleton rất nhiều trong ứng dụng dựa trên MVC của tôi. Đề xuất của bạn giải quyết ví dụ giả tạo của tôi, nhưng bỏ lỡ điểm của câu hỏi. Làm thế nào để cấu hình một ràng buộc để tôi có thể "bọc" một giao diện, như trên? – FMM

+0

Một cái gì đó như thế này: 'BindToFactory (). InRequestScope(); ' – Mrchief

+0

Quên đề cập đến, nếu bạn sử dụng' BindToFactory() ', bạn cần kết nối nhà cung cấp của riêng mình - tinh chỉnh' CachedThingFactory' của bạn để thực hiện 'IProvider' (thêm tại đây https://github.com/ninject/ninject/ wiki/Nhà cung cấp% 2C-Nhà máy-Phương pháp-và-Kích hoạt-Bối cảnh). Bạn cũng có thể sử dụng phương thức '.ToMethod()'. – Mrchief

2

Tôi cho rằng bạn đang tìm kiếm tên ràng buộc, tài liệu ở đây:

https://github.com/ninject/ninject/wiki/Contextual-Binding

Bind<IThingFactory>().To<CachedThingFactory>().Named("TheCachedThing"); 
Bind<IThingFactory>().To<DefaultThingFactory >().Named("ThePureThing"); 

và sau đó

public CachedThingFactory([Named("ThePureThing")] IThingFactory wrapped) 
{ 
    this._wrapped = wrapped; 
    _cachedThings = new Dictionary<int,Thing>(); 
} 

và cho người tiêu dùng của CachedThingFactory

public ThingFactoryConsumer([Named("TheCachedThing")] IThingFactory thingFactory) 
{ 
    _thingFactory = thingFactory; 
} 
+0

Tôi đã quen thuộc với các ràng buộc có tên; Tuy nhiên, nó cảm thấy bẩn để trang trí các lớp học của tôi với các thuộc tính có kiểu gõ. – FMM

+0

Không hoàn toàn rõ ràng hình thức câu hỏi của bạn :-). Giá trị đọc: http://eeichinger.blogspot.com/2009/12/springnet-aop-behind-scenes-1.html từ một "trang trí" để "aop". – Andreas

+0

Thú vị đọc, cảm ơn! Giao diện IMethodInterceptor mà anh ta đưa ra trong blog tiếp theo cảm thấy thậm chí còn bẩn hơn, mặc dù =) – FMM