2012-07-24 3 views
1

PetaPoco에서 생성 된 Database.cs 코드는 4.0.3 버전입니다. 코드 아래 참조 : PetaPoco GetInstance()는 항상 새 인스턴스를 반환합니까?

public partial class postgresqlDB : Database 
{ 
    public postgresqlDB() 
     : base("postgresql") 
    { 
     CommonConstruct(); 
    } 

    public postgresqlDB(string connectionStringName) 
     : base(connectionStringName) 
    { 
     CommonConstruct(); 
    } 

    partial void CommonConstruct(); 

    public interface IFactory 
    { 
     postgresqlDB GetInstance(); 
    } 

    public static IFactory Factory { get; set; } 
    public static postgresqlDB GetInstance() 
    { 
     if (_instance!=null) 
      return _instance; 

     if (Factory!=null) 
      return Factory.GetInstance(); 
     else 
      return new postgresqlDB(); 
    } 

    [ThreadStatic] static postgresqlDB _instance; 

    public override void OnBeginTransaction() 
    { 
     if (_instance==null) 
      _instance=this; 
    } 

    public override void OnEndTransaction() 
    { 
     if (_instance==this) 
      _instance=null; 
    } 
..... 
..... <snip /> 

GetInstance() 기능을 살펴보면, 이유는 return new postgresqlDB()는 전용 변수 _instance에 할당되지 않습니다이다?

if (_instance != null) return _instance;이 사실이 아니기 때문에 GetInstance()을 호출 할 때마다 항상 새로운 인스턴스가 만들어집니다.

도움 주셔서 감사합니다.

+0

CommonConstruct() 코드가 있습니까? 나는 거기에 변수를 설정할 수도 있다고 가정합니다. –

+0

TT 템플릿을 통해 PetaPoco에 의해 생성 된 코드입니다. 상자 밖에서 이것이 전부입니다. 나는 왜 생성 된 코드에서'_instance'에 대한 할당이 없는지 궁금합니다. – Spongebob

답변

0

오늘은 PetaPoco에서도이 동작을 보았습니다. (일반적으로 사용하는 것이 즐겁기 때문에 모자는 제작자에게 전달됩니다!). 내 경우 항상 OP에서 알 수 있듯이 정확히 이유 비어에서

Console.WriteLine(RepositoryTableClass.repo.LastCommand); 

: 관련 상황에서, 내가 좋아하는 코드를 검토하기 위해 PetaPoco 통과 한 가장 최근의 SQL의 사본을 끌어 싶었다. 쓰레드 스태틱 마커는 원래 질문과 직각을 이룹니다. _instance 변수가 설정된 코드의 유일한 위치는 트랜잭션 지속 기간입니다. 결과적으로 저장소의 각 인스턴스는 기본적으로 사용 및 포기됩니다. (여러 개의 중복 쿼리/결과에 대해 단일 연결을 다시 사용하면 문제가 발생하지 않을 수 있습니다.)

어떤 경우이든 공장 패턴이 사용 가능하며 단일 Repo 인스턴스에 의존하도록 강제 할 수 있습니다 너 욕망이야. 같은 매우 간단한 팩토리 클래스를보십시오 : 당신이 그렇게 같은 모든 리포지토리 개체를 사용하기 전에

private class RepoFactory : postgresqlDB.IFactory 
{ 
     private static postgresqlDB repo = postgresqlDB.GetInstance(); 

     public postgresqlDB GetInstance() 
     { 
      return repo; 
     } 
} 

공장 설정 :

에 의해 확인으로 단일 저장소 인스턴스에 대해 리포지토리 개체를 사용하는 저를 활성화
postgresqlDB.Factory = new RepoFactory(); 

각 사용 후 마지막 명령에 대한 채워진 값을 가지고 ...

RepositoryTableClass.repo.LastCommand 
+0

당신의 접근법은 우리와 비슷합니다. – Spongebob

1

_instance 필드의 값을 ThreadStatic으로 지정했습니다. 즉, 각 스레드가 액세스 할 때 필드에 다른 값이 있음을 의미합니다. 항상 새로운 스레드와 함께 GetInstance가 호출되면 항상 새로운 값을 갖게됩니다. 즉, 매번 생성자를 호출합니다.

+0

나는 본다. 만약 어떤 이유로'GetInstance()'가 같은 스레드 내에서 여러 번 호출된다면 어떻게 될까요? 그런 다음이 시나리오에서 각 호출에서 항상 새로운'postgresqlDB' 인스턴스를 리턴 할 것입니다. – Spongebob

+0

같은 스레드에서 처음으로 생성자를 호출 한 다음 동일한 값을 반환합니다. 나중에 인스턴스 필드를 사용하는 대신 Lazy 을 사용하는 것이 좋습니다. –

+0

'GetInstance()'구현을 보면 'else return new postgresqlDB();'문을 사용하면 생성 된 인스턴스에 로컬 _instance' 변수를 설정하지 않는 것처럼 보입니다. 따라서 동일한 스레드에서라도 'postgresqlDB'의 새로운 인스턴스를 계속 반환하지 않습니까? – Spongebob

관련 문제