Singleton

2022. 2. 25. 00:00CSharp/Advance

반응형

클래스가 하나의 인스턴스만 갖도록 하고 이에 대한 전역 액세스 지점을 제공

 

문제

객체를 생성했지만 잠시 후 새 객체를 생성하기로 결정했다고 하자

새 개체를 받는 대신 이미 만든 개체를 다시 받기로 한다면...

 

생성자 호출 은 항상 새 개체를 의도적으로 반환 해야 하므로 이 동작은 일반 생성자로 구현할 수 없다 .

 

해결책

  • 다른 개체 가 Singleton 클래스와 함께 new 연산자 를 사용하지 못하도록 기본 생성자를 비공개로 설정 .
  • 생성자 역할을 하는 정적 생성 메서드를 생성. 
  • 내부적으로 이 메서드는 private 생성자를 호출하여 개체를 만들고 정적 필드에 저장. 
  • 이 메서드에 대한 다음 호출은 모두 캐시된 개체를 반환.

 

참조 : https://www.dofactory.com/net/singleton-design-pattern

예를 위하여 단순히 정의 한것이므로 참고만 바랍니다. 

 

Generic Singleton 의 구현

public class Singleton<T> where T : class, new()
{
    private Singleton() { }
    private static readonly Lazy<T> _lazy = new Lazy<T>(() => new T());
    private static object _lock = new object();
    public static T Instance { get { lock (_lock) { return _lazy.Value; } } }
}

사용법

public class Person
{
    public Person()
    {
        Id = Guid.NewGuid();
    }
    public Guid Id { get; init; }
}
public class Test : ITest
{
    public void Run()
    {

        var person1 = Singleton<Person>.Instance;
        var person2 = Singleton<Person>.Instance;

        person1.Id.ToString().Print();
        person2.Id.ToString().Print();


    }
}
//output
7f0575ed-5ef0-448c-86ee-689fefa67f48
7f0575ed-5ef0-448c-86ee-689fefa67f48

첫번째는 Instance 호출에 의해 내부 private constructor 를 실행한다. 

두번째 부터는 이미 생성된 값이 _lazy.Value 에 있으므로 해당 Value 를 단순 리턴한다. 

 

관련영상

https://youtu.be/D9e3EWIoC9Q

 

 

 

 

반응형

'CSharp > Advance' 카테고리의 다른 글

Refactoring - Encryption Hash Helper  (0) 2023.10.16
C# deadlock prevent  (0) 2023.06.23
Prototype  (0) 2022.02.24
Factory Method  (0) 2022.02.23
Builder  (0) 2022.02.22