문제

"static readonly t instance = new t ();"를 사용하는 싱글 톤이 있습니다. 무늬. 그러나 T가 일회용 인 경우에 실행되었으며 실제로 단위 테스트를 위해 폐기해야합니다. 일회용 싱글 톤을 지원하기 위해이 패턴을 어떻게 수정할 수 있습니까?

내가 원하는 인터페이스는 다음과 같습니다.

var x = Foo.Instance;
var y = Foo.Instance; // x == y
...
x.Release(); // this causes the next Foo.Instance to return a fresh object
             // also, it assumes no further operations on x/y will be performed.

참고 - 패턴은 물론 스레드 안전이어야합니다.

편집하다 - 생산 코드의 목적 상, 이것은 진정한 싱글 톤입니다. 문제는 일부 파일을 잠그고 단위 테스트에서 청소를 위해 파일을 폐기해야한다는 것입니다.

또한 가능하면 재사용 할 수있는 패턴을 선호합니다.

도움이 되었습니까?

해결책

표시 Release ~처럼 internal 그리고 사용하십시오 InternalsVisibleTo 단위 테스트 어셈블리에만 노출되는 속성. 당신은 그렇게 할 수 있거나, 당신이 자신의 집회에있는 누군가가 그것을 부를 것이라는 조심이라면, 당신은 그것을 다음과 같이 표시 할 수 있습니다. private 반사를 사용하여 액세스하십시오.

싱글 톤에서 최종화기를 사용하십시오 Dispose 싱글 톤 인스턴스의 메소드.

생산 코드에서는 단지 언로드 만 AppDomain 싱글 톤의 처분을 유발합니다. 테스트 코드에서 전화를 시작할 수 있습니다. Release 당신 자신.

다른 팁

그 시점에서 나는 그것이 솔직히 말해서 더 이상 싱글 톤이라고 생각하지 않을 것이라고 생각합니다.

특히, 고객이 싱글 톤을 사용하는 경우 실제로는 자신이 처리해야한다고 기대하지 않을 것이며, 다른 사람이 그랬다면 놀랄 것입니다.

생산 코드는 무엇을할까요?

편집 : 당신이 정말로 당신이 정말로, 단위 테스트와 단위 테스트 (디자인 측면에서 의심스러운 소리, 솔직한 소리)의 경우 항상 반사를 사용하여 필드와 함께 바이올린을 만들 수 있습니다. 해야하는지 여부를 해결하는 것이 더 좋을 것입니다. 진짜 싱글 톤이어야하는지 또는 해야하는지 여부 진짜 그래도 일회용 - 두 사람은 거의 함께 가지 않습니다.

싱글 톤은 일회용이되어서는 안됩니다. 기간. 누군가 전화를 걸면 조기에 전화를 걸면 신청서가 다시 시작될 때까지 신청서가 나사로 나사합니다.

 public class Foo : IDisposable
  { [ThreadStatic] static Foo _instance = null;

    private Foo() {IsReleased = false;}

    public static Foo Instance
     { get
        { if (_instance == null) _instance = new Foo();
          return _instance;
        }
     }

    public void Release()
     { IsReleased = true;
       Foo._instance = null;
     }

    void IDisposable.Dispose() { Release(); }

    public bool IsReleased { get; private set;}

  }

클래스가 idisposable을 구현하면 (당신이 암시하는 것처럼) x.dispose ()로 전화하십시오.

중첩 된 게으른 싱글 톤을 사용할 수 있습니다 (참조 여기) 몇 가지 간단한 수정으로 :

public sealed class Singleton : IDisposable
{
    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            if (!Nested.released)
                return Nested.instance;
            else
                throw new ObjectDisposedException();
        }
    }

    public void Dispose()
    {
         disposed = true;
         // Do release stuff here
    }

    private bool disposed = false;

    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}

대상이 폐기 된 경우 객체의 모든 공개 방법/속성에 ObjectDisparedException을 던지는 것을 잊지 마십시오.

또한 Dispose가 호출되지 않는 경우 객체에 대한 Finalizer 메소드를 제공해야합니다. idisposable을 올바르게 구현하는 방법을 확인하십시오 여기.

단위 테스트의 경우 "매뉴얼"인스턴스를 사용할 수 있습니다 (그러나 객체를 인스턴스화하는 방법이 필요합니다).

귀하의 경우, 아마도 싱글 톤과 결합 된 공장 패턴 (추상/방법 - 케이스에 가장 적합한 것)을 더 잘 사용해야 할 것입니다.

싱글 톤이 중고 객체 (단위 테스트)를 제대로 배치했는지 테스트하려면 공장 방법을 사용하고 그렇지 않으면 싱글 톤 패턴을 사용하십시오.

그건 그렇고, 싱글 톤 소스 코드에 액세스 할 수 없거나 수정할 수없는 경우 다른 싱글 톤으로 래핑하고 새로운 논리 (프록시처럼)를 제공하는 것이 좋습니다. 과잉처럼 들리지만 실행 가능한 솔루션이 될 수 있습니다.

또한 액세스를 제어하려면 공장을 제공하고 객체가 폐기되지 않은 경우에만 클라이언트가 새 객체를 얻도록하십시오.

일회용 싱글 톤을 만드는 또 다른 옵션은 Sandcastle 's를 사용하는 것입니다. 하나씩 일어나는 것 수업에 대한 공물, 그런 다음 Castle Framework는 모든 일회용 싱글 톤 객체를 처분합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top