2012-04-19 31 views
29

Vì vậy, tôi có một phương pháp tiếp xúc từ một dịch vụ WCF như vậy:Hướng dẫn cho Dispose() và Ninject

public GetAllCommentsResponse GetAllComments(GetAllCommentsRequest request) 
{ 
    var response = new GetAllCommentsResponse(); 

    using(_unitOfWork) 
     try 
     { 
      Guard.ArgNotNull(request, "request"); 

      var results = _unitOfWork.CommentRepository.Get(d => d.Id > 0).ToArray(); 

      //... Do rest of stuff here 
     } 
     catch (Exception ex) 
     { 
      response.Success = false; 
      response.FailureInformation = ex.Message; 
      Logger.LogError("GetAllComments Method Failed", ex); 
     } 

    return response; 
} 

Tôi có một đối tượng DataUnitOfWork toàn cầu (mà thực hiện IDisposable) đó được khởi tạo bởi Ninject qua một constructor Lập luận khi một cuộc gọi dịch vụ đi kèm trong. khi gỡ lỗi, nếu tôi sử dụng

using(_unitOfWork) 

đối tượng _unitOfWork được xử lý ngay lập tức sau khi đi ra khỏi phạm vi sau đó được gọi là một lần nữa bởi Ninject (mặc dù nó được đánh dấu là xử lý, vì vậy không có gì xảy ra.) Không có câu lệnh sử dụng, Ninject xử lý việc xử lý.

Tóm tắt câu chuyện dài, có quy tắc chung nào về điều này không? Tôi đã sợ hãi của toàn bộ điều IDisposable sau khi tất cả mọi thứ tôi đọc dường như chỉ ra không bao giờ sử dụng nó, hoặc sử dụng nó trong một số tình huống chiết trung, nhưng nó luôn luôn nhầm lẫn với tôi.

Bất kỳ đầu vào nào được đánh giá cao.

Ồ, cũng trong khi tôi đang ở đây gõ anyway, tại sao chính xác là có một cuộc gọi đến GC.SuppressFinalize() khi xử lý? Làm thế nào để vứt bỏ và hoàn thành khác nhau?

+0

Tìm thấy câu trả lời trong bài đăng tương tự: http://stackoverflow.com/questions/898828/c-sharp-finalize-dispose-pattern – Nate222

+0

'SuppressFinalize' cho hệ thống GC 'Đừng lo lắng về việc gọi' Hoàn tất' khi bạn đã xác định đối tượng là rác vì chúng tôi đã thực hiện dọn dẹp nhờ ai đó explicityl gọi là 'Vứt bỏ' trên đó. Nếu bạn không làm điều này, đối tượng vẫn còn trên hàng đợi finalizer và Dispose _will_ được gọi lại từ thread Finalizer. –

Trả lời

45

Tài liệu CLR quy định rằng bất kỳ ai tạo ra một đối tượng Dùng một lần đều chịu trách nhiệm gọi Dispose. Trong trường hợp này đối tượng được tạo ra bởi Ninject. Điều đó có nghĩa là bạn nên không phải gọi Dispose một cách rõ ràng.

Ninject phân phát mọi đối tượng dùng một lần có phạm vi khác ngoài InTransientScopeas soon as the scope object to which the created object is tied is collected by GC. Đó là lý do tại sao mọi đối tượng dùng một lần phải là Bind d với phạm vi không phải là InTransientScope(). Ví dụ. bạn có thể sử dụng InParentScope() từ the NamedScope extension sẽ bỏ đối tượng ngay khi đối tượng được đưa vào đó là rác được thu thập.

+2

Điều đó có nghĩa là trong các đối tượng 'IDisposable' của InRequestScope sẽ được xử lý ở cuối yêu cầu? – AgentFire

+0

Có, giả sử bạn đã làm mọi thứ đúng, bao gồm sử dụng mô-đun OncePerWebRequest –

+0

Theo như tôi có thể nói, ninject không bao giờ phân phối InSingletonScope. – trampster