2017-01-25 5 views
1

다음 코드와 명세서 및 해당 객체 처리의 범위에 대해 혼동스러워합니다.내부 사용 회원의 범위

using(DbFactory db = new DbFactory()) 
{ 
    Repository repo = new Repository<someobject>(db); 
    result = repo.Get(somecondition); 
} 

이 코드에서 블록 사용을 실행 한 후에는 DbFactory이 삭제됩니까?
repo 변수의 범위는 using 문 내부에서 사용됩니까?
DbFactoryRepository에 사용되며 DbFactory을 보유하는 멤버 변수가 있습니다. 이렇게 처리하면 DbFactory이 처리됩니까?

EDIT1 :

Repository repo; 
ResultObject result; 
using(DbFactory db = new DbFactory()) 
{ 
    repo = new Repository<someobject>(db); 
    result = repo.Get(somecondition); 
} 

public class Repository 
{ 
    private _dbFactory; 

    public Repository(DbFactory dbFactory) 
    { 
     _dbFactory = dbFactory; 
    } 
} 

는 이제 DbFactory이 사용하는 문 다음에 배치됩니다 것인가?

답변

8

repo 변수의 범위 (첫 번째 경우)는 using 문입니다. using 문 외부에 선언 할 수 없으므로 참조 할 수 없습니다.

변수를 선언하지 않았기 때문에 result 변수의 범위를 알 수는 없지만 적어도 "using 문보다 큽니다".

더 흥미로운 점은 result 값이 의미하는 객체가 얼마나 유용합니까? DbFactory이 삭제 된 것입니다. 이것은 구현에 따라 달라질 수 있습니다. 기본적으로 ... result 속성에 액세스하려면 추가 데이터베이스 쿼리가 필요합니다 (예 : 외래 키로 참조되는 객체를 가져 오는 경우). 실패 할 수도 있지만 이미 페치 된 것이 좋을 것입니다.

처분시기에 대해서는 DbFactoryusing 성명 끝에 처리됩니다. 이것은 쓰레기 수거와는 완전히 별개이며, 아마도 Repository 객체는 여전히 그것에 대한 참조를 가지지 만, 공장이 폐기 된 후에는 쓸모 없을 것입니다. 따라서 using 문 뒤에 호출하면 해당 코드가 팩토리에서 실제로 수행하는 작업과 처리 된 팩토리가 작동하는 방식에 따라 예외가 표시됩니다. 다시 처분은 가비지 수집이 아닙니다. Dispose 메서드를 호출하는 것입니다. CLR은 특별한 방법으로 신경 쓰지 않습니다.REPO는 일회용 인 경우

+0

질문을 수정했습니다. 나는 repo 변수가 using 문이나 DbContext를 사용한 후에 DbContext의 처분을 저장하고 repo가 ​​gc를 기다리는 것을 혼란스럽게 생각합니까? – Sreejith

+1

Dispose 메서드는 소멸자가 아니므로 Dispose 메서드가있는 경우 GC가 호출되지 않으므로 Dispose는 GarbageCollector와 아무 관련이 없습니다. – Vir

+0

@jonskeet 중대한 시점, 나는 처분의 그 타이밍을 찾고있다. – Sreejith

3

DbFactory가 삭제됩니까?

예.

using 문에서 사용되는 repo 변수의 범위는 어떻게됩니까?

repo의 범위가 포함되는 블록이므로 중괄호 쌍은 ('{', '}')가에 싸여있다.이 경우에, 신체에 일치 일어나는 귀하의 using 성명, 예.

+0

은 그래서'repo' 변수는 바로'DbFactory' 처분을 ​​보유하지 않습니다? – Sreejith

+0

@Rebornx 동일한 객체를 보유하므로 해당 객체가 삭제되고 저장소가 폐기 된 객체에서 지원되지 않는 작업을 사용하려고 시도하면 저장소가 작동하지 않습니다. – Servy

0

당신은 exampe을 위해, 또한 그것을 처리 할 수 ​​있습니다 :

using(DbFactory db = new DbFactory()) 
using(Repository repo = new Repository<someobject>(db)) 
{ 
    result = repo.Get(somecondition); 
} 
+0

나는 그것을 안다. 그러나 저장소를 일회용으로 만드는 것이 좋은 패턴입니까? – Sreejith

0

이 :

Repository repo; 
ResultObject result; 
{ 
    DbFactory db = new DbFactory() 
    repo = new Repository<someobject>(db); 
    result = repo.Get(somecondition); 
    db.Dispose(); 
} 

:

Repository repo; 
ResultObject result; 
using(DbFactory db = new DbFactory()) 
{ 
    repo = new Repository<someobject>(db); 
    result = repo.Get(somecondition); 
} 

이 하나와 동일 따라서 db 객체 자체가 wanish되지는 않지만 (저장소 인스턴스에서 참조가 폐기 될 것이므로 Disposed/Closed 상태가됩니다.) Depe DbFactory를 구현하면 코드가 손상 될 수 있습니다.

당신은 전체 코드를 제공하지 않았고 그것은 무엇을해야하지만 난 당신이이 방향으로 가야한다고 생각 :뿐만 아니라 DbFactory을 처분

  1. 이 저장소 개체는 IDisposable을 구현하고 그 안에 :

    public class Repository : IDisposable 
    { 
        private _dbFactory; 
    
        public Repository(DbFactory dbFactory) 
        { 
         _dbFactory = dbFactory; 
        } 
    
        public void Dispose() 
        { 
         _dbFactory.Dispose(); 
        } 
    } 
    
  2. 지금과 같이 사용 :

    ResultObject result; 
    using (Repository repo = new Repository(new DbFactory()) 
    { 
        result = repo.Get(somecondition); 
    } 
    

또는 사용하여 중첩 된 사용

using (DbFactory db = new DbFactory()) 
{ 
    using(Repository repo = new Repository(db)) 
    { 
     result = repo.Get(somecondition); 
    } 
}