2012-12-06 21 views
6

Tôi tự hỏi làm cách nào để quản lý một đối tượng bằng DI. Giả sử tôi có một lớpQuản lý các lớp Dùng một lần Sự phụ thuộc Tiêm

class Foo : IFoo, IDisposable 
{ 
    // ... 
} 

Sau đó, lớp này được tiêm vào lớp khác

class Bar 
{ 
    public Bar(IFoo foo) 
    { 
     this.Foo = foo 
    } 

    IFoo Foo { get; set; } 
} 

Sau đó, tôi ràng buộc này trong một số phạm vi (ví dụ của tôi sử dụng MVC và Ninject)

this.Bind<IFoo>().To<Foo>().InRequestScope(); 

tôi Tôi tự hỏi, vì khuôn khổ Dependency Injection xử lý vòng đời của Foo, tôi có nên triển khai IDispoable trong Bar không? Suy nghĩ của tôi là DI đang quản lý vòng đời của Foo, vì vậy đừng chạm vào nó, trong trường hợp một lớp khác đang sử dụng Foo. Ngoài ra, vì đối tượng dùng một lần được chuyển thành Bar làm tham số hàm tạo, Bar không quấn đối tượng dùng một lần, vì vậy không biết người gọi Bar muốn sử dụng Foo sau Bar là rác được thu thập. Thê nay đung không?

+1

Nicholas Blumhardt có bài đăng tuyệt vời về chủ đề này, sử dụng Autofact làm ví dụ nhưng áp dụng chung trong http://nblumhardt.com/2011/01/an-autofac-lifetime-primer/ – fsimonazzi

+0

Nhìn vào một số bài viết MSDN, dường như Microsoft sẽ thực hiện cả hai: http://msdn.microsoft.com/en-us/library/yhfzs7at%28v=vs.110%29 (StremReader) "Đối tượng StreamReader gọi Dispose() trên đối tượng Luồng được cung cấp khi StreamReader .Dispose được gọi là " nhưng http://msdn.microsoft.com/en-us/library/z7ha67kw%28v=vs.110%29 (Bitmap)" Bạn phải giữ luồng mở trong suốt thời gian của Bitmap. " – Michael

Trả lời

3

Có giả định của bạn là chính xác. Ninject sẽ vứt bỏ đối tượng cho bạn.

+0

Tôi nhận ra điều này khi thử nghiệm. Tôi đoán câu hỏi chính của tôi là ai chịu trách nhiệm xử lý một vật thể. Kết luận của tôi dựa trên tìm kiếm là đối tượng đã tạo ra đối tượng dùng một lần có trách nhiệm xử lý nó. Vì vậy, trong trường hợp này Ninject. – Michael

3

Đây là vấn đề chung về quản lý tuổi thọ. Nguyên tắc cơ bản là người tạo ra một đối tượng có quyền sở hữu của cá thể đó. Chủ sở hữu nên xử lý/hủy bỏ trường hợp đó. Quyền sở hữu có thể được chuyển cho người khác, điều này khiến cho 'người khác' chịu trách nhiệm phá hủy trường hợp đó.

Trong trường hợp của bạn, trường hợp Foo không được tạo bởi Bar, do đó, thanh không chịu trách nhiệm xử lý trường hợp đó. Kể từ khi Ninject tạo ra trường hợp đó cho bạn, nó chịu trách nhiệm dọn dẹp của nó.

Quyền sở hữu có thể được chuyển đi nhưng điều này phải rõ ràng. Một ví dụ tốt về qua quyền sở hữu rõ ràng là các mẫu thiết kế Nhà máy:

IFoo CreateNewFoo(); 

Mặc dù phương pháp này tạo ra IFoo trường mới, nó là khá rõ ràng rằng ông vượt qua quyền sở hữu lại cho người gọi.

Một ví dụ điển hình về cách thức chuyển quyền sở hữu BAD là lớp StreamReader của .NET. Phải mất một đối tượng dùng một lần trong constructor của nó, nhưng nó có quyền sở hữu. Mặc dù tài liệu nói rằng lớp phân phối đối tượng đã cho, hành vi này làm mê hoặc nhiều nhà phát triển, bởi vì nó đi ngược lại quy tắc chung về quyền sở hữu. Microsoft cuối cùng đã khắc phục điều này trong .NET 4.5 bằng cách thêm một quá tải ctor cho phép ngăn chặn việc xử lý luồng đã cho.

Các vấn đề liên quan