Руководящие принципы для Dispose() и Ninject
Итак, у меня есть метод, открываемый из службы WCF:
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;
}
У меня есть глобальный объект DataUnitOfWork (который реализует IDisposable), который инстанцируется Ninject через аргумент конструктора, когда приходит вызов сервиса. При отладке, если я использую
using(_unitOfWork)
объект _unitOfWork утилизируется сразу после выхода из области видимости, а затем снова вызывается Ninject (хотя он был помечен как утилизированный, поэтому ничего не происходит). Без оператора using Ninject выполняет утилизацию.
Короче говоря, есть ли общее эмпирическое правило для этого? Меня пугает вся эта штука с IDisposable после того, как все, что я прочитал, кажется, говорит о том, что никогда не стоит его использовать, или использовать его в определенных эклектичных ситуациях, но это всегда сбивало меня с толку.
Любой вклад будет оценен по достоинству.
И еще, пока я тут печатаю, почему при утилизации нужно вызывать GC.SuppressFinalize()? Чем отличаются Dispose и Finalize?
В документации CLR говорится, что тот, кто создает объект Disposable, отвечает за вызов Dispose. В данном случае объект создается Ninject. Это означает, что вы не должны явно вызывать Dispose.
Ninject утилизирует каждый объект Disposable, который имеет другую область видимости, кроме
InTransientScope
как только объект области видимости, к которому привязан созданный объект, будет собран GC. Поэтому каждый объект Disposable должен бытьBind
с областью видимости, которая не являетсяInTransientScope()
. Например, вы можете использоватьInParentScope()
из расширения NamedScope, который утилизирует объект, как только объект, в который он внедрен, будет собран.