2014-09-18 2 views
2

, 내가와 같은 MVC 애플리케이션 내 리포지토리 개체를 인스턴스화하고 있습니다 :MVC 간단한 인젝터 및 단순 인젝터 문서 당으로 RegisterPerWebRequest

container.RegisterPerWebRequest<IUserRepository, SqlUserRepository>(); 
container.RegisterPerWebRequest<IOrderRepository, SqlOrderRepository>(); 

하지만 난 그냥 발견 한 문서도 상태 :

Simple Injector의 기본 동작과 달리 이러한 확장 메서드는 만들어진 인스턴스가 IDisposable을 구현할 때 이 처리되도록합니다.

https://simpleinjector.codeplex.com/wikipage?title=ObjectLifestyleManagement#PerWebRequest

질문 : RegisterPerWebRequest를 사용하는 경우이 그들이 웹 요청의 마지막에 배치받을 수 있도록 내 개체는 IDisposable을 구현해야, 뜻 (즉, 코드 아래)?

사이드 노트 : WebRequestLifestyle, RegisterInitializer, RegisterForDisposal을 사용하면 IDisposable을 구현하는 객체가 필요하다고 생각합니다.

아래의 예제 코드 (인터페이스 및 구현).

public interface IUserRepository : IDisposable 
{ 
    ... 
} 

public class SqlUserRepository : IUserRepository, IDisposable 
{ 
    ... 
    ... 
    ... 


    private bool disposed = false; 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!this.disposed) 
     { 
      if (disposing) 
      { 
       _context.Dispose(); 
      } 
     } 
     this.disposed = true; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
} 
+1

일반적으로 인터페이스에는 IDisposable이 구현되어서는 안됩니다. 귀하의 [구현은]해야합니다 (https://stackoverflow.com/questions/12259534/is-it-a-leaky-abstraction-if-implementation-of-interface-calls-dispose). 그렇지 않으면 구현 세부 사항이 누출되어 [의존성 반전 원리] (https://en.wikipedia.org/wiki/Dependency_inversion_principle)를 위반합니다. – Steven

+0

이 재 유출 알지 못했습니다. 나는 지금 본다. 감사. –

답변

4

공개 : SimpleInjector를 사용하지 않았습니다.

내가 읽은 것에서부터, 아니요, IDisposable을 구현할 필요가 없습니다.

기본적으로 등록 된 개체는 삭제되지 않습니다. 즉, SimpleInjector는 웹 요청이 아닌 다른 방법으로 객체를 등록하는 경우 Dispose()을 호출하지 않습니다.

그러나 RegisterPerWebRequest()을 사용하면 다른 경우를 지정하지 않는 한 객체가 IDisposable 인 경우 Dispose()이 호출됩니다.

+0

이것은 완전히 맞습니다. – Steven

+0

죄송합니다. 귀하의 성명서와 혼동합니다. "아니오, IDisposable을 구현할 필요가 없습니다." MVC 응용 프로그램에서 작업 할 때마다 각 웹 요청은 새로운 '세션'이므로 RegisterPerWebRequest를 사용할 때 저장소 개체에 IDispose를 구현해야하므로 Simple Injector가 메모리를 확보하고 해제 할 수 있습니다. –

+1

죄송합니다, 제 진술은 일반적인 것입니다. 내 말은, 일반적으로 수업은 ** IDisposable을 구현하지 못했다는 것입니다. 'IDisposable' 구현 여부는 당신에게 달려 있으며 객체에 달려 있습니다. 객체가'IDisposable'을 구현하면 Simple Injector가 웹 요청이 끝날 때 객체를 처리하게되므로 안심할 수 있습니다. –

5

여기에 몇 가지 참고 사항이 있습니다. 여기서 전체 처분 패턴을 구현하는 것으로 보이지만 SqlUserRepositorysealed을 만들면이 패턴을 단순화 할 수 있습니다. 이것은 당신이이 다음을 수행 할 수 있습니다 : SqlUserRepository 이후

public sealed class SqlUserRepository : IUserRepository, IDisposable 
{ 
    public void Dispose() 
    { 
     _context.Dispose(); 
    } 
} 

가 밀폐되어, 아무도 그것에서 파생 수 있으므로이 :

  • 가상 보호 폐기 (부울) 방법에 대한 필요가 없습니다 .
  • SuppressFinalize은 finalize 메서드가있는 경우에만 필요하기 때문에 호출 할 필요는 없지만 구현하지 않고 파생 형식이 없다고 확신하므로 호출하지 않아도됩니다.

이 당신이 _context에 처분을 위임되기 때문에 disposed 플래그를 할 필요도 없지만 여러 번 처리를 호출하는 탄력적이어야한다; 이는 IDisposable 계약에 정의되어 있습니다.

더 자세히는 해당 ​​컨텍스트 개체를 SqlUserRepository의 생성자에 삽입하면 SqlUserRepository에 일회용품을 구현할 필요가 전혀 없습니다.해당 컨텍스트를 웹 요청 라이프 스타일에 등록하기 만하면 Simple Injector가이를 처분합니다.

+2

예, dispose 무늬. 귀하의 조언은 환상적입니다! 감사! 내 처분 코드 수정하기. –

관련 문제