2009-07-14 4 views
21

생성자에서 다른 객체에 대한 참조를 받아들이는 정적 클래스 또는 싱글 톤 클래스를 만들고 싶습니다. 정적 클래스가 있지만, 나는 생성자에서 매개 변수를 받아들이는 싱글 톤을 만들 수 있다고 생각했다. 지금까지 구문을 알아 내거나 인터넷 검색을하는 행운이 없었습니다. 이것이 가능한가? 그렇다면 어떻게해야합니까?C# 매개 변수를 받아들이는 생성자가있는 싱글 톤

초기 게시물에 예제가 없으므로 죄송합니다. 서둘러 썼습니다. 내 대답은 이미 답장을 받았지만 여기에 내가하고 싶은 일에 대한 설명이 있습니다.

특정 유형의 단일 인스턴스 (Singleton)를 만들고 싶지만 type은 다른 객체에 대한 참조를 보유해야합니다.

예를 들어, StringBuilder 개체를 소유하는 Singleton "Status"클래스와, 해당 StringBuilder를 화면에 쓰도록 호출 할 수있는 Draw() 메서드를 만들 수 있습니다. Draw() 메소드는 그릴 수 있도록 내 GraphcisDevice에 대해 알아야합니다. 그래서 나는이 작업을 수행 할 작업 :

public class Status 
{ 
private static Status _instance; 
private StringBuilder _messages; 
private GraphicsDevice _gDevice; 

private Status(string message, GraphicsDevice device) 
{ 
    _messages.Append(message); 
    _gDevice = device; 
} 

// The following isn't thread-safe 

// This constructor part is what I'm trying to figure out 
public static Status Instance // (GraphicsDevice device) 
    { 
    get 
     { 
     if (_instance == null) 
      { 
      _instance = new Status("Test Message!", device); 
      } 
     return _instance; 
     } 
    } 

public void UpdateMessage 
... 

public void Draw() 
    { 
    // Draw my status to the screen, using _gDevice and _messages 
    } 
} 

모든 코드를 통해, 내 상태 싱글을 검색하고 UpdateMessage() 메서드를 호출합니다.

private Status _status = Status.Instance; // + pass reference to GraphicsDevice 
_status.UpdateMessage("Foo!"); 

그런 다음 내 주요 클래스에서 나는 또한 그것을 싱글을 검색하고 그릴 :

_status.Draw(); 

네, 제가 싱글을 검색 할 때마다, 나는 전달하여 그렇게해야한다는 것을 의미 첫 번째로 Singleton을 인스턴스화하는 경우를 대비해서 GraphicsDevice에 대한 참조. 그리고 다른 방법을 사용하여 내 Singleton 클래스의 GraphicsDevice처럼 근본적인 것을 검색 할 수 있습니다. 예를 들어 다른 곳에 서비스를 등록하고 Status 클래스에서 해당 서비스를 가져올 수 있습니다. 이 예제는 꽤 고안된 것입니다 - 나는이 패턴과 같은 무언가가 일지 알아 내기 위해 노력하고 있습니다.

+1

내가 묻는 내용에 대한 설명이 추가되었습니다. –

답변

2

설명하는 것은 일반 싱글 톤입니다. 그것은 다음과 같습니다

public class SingletonProvider <T> where T:new() 
{ 
    SingletonProvider() {} 

    public static T Instance 
    { 
     get { return SingletonCreator.instance; } 
    } 

    class SingletonCreator 
    { 
     static SingletonCreator() { } 

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

http://www.codeproject.com/KB/cs/genericsingleton.aspx

+4

응용 프로그램에 T 유형의 다른 인스턴스가 없다는 것을 어떻게 보장 할 수 있습니까? 이것은 실제로 싱글 톤이 아닙니다. –

+5

나는 질문을하는 사람이 이미 그 타입을 다른 것에 사용할 수 없다는 것을 이미 알고 있다고 생각합니다. 그는 칼을 물었고, 나는 그에게 무엇을해야하는지 말하지 않았다. –

+1

싱글 톤 은 싱글 톤 과 다른 유형이므로 중요하지 않습니다. 일반 싱글 톤은 싱글 톤을 만들기위한 기본 클래스 역할을하는 경우에만 의미가 있습니다. –

17

이것은 일반적으로 좋은 생각 간주됩니다 당신이 싱글 같은 래퍼에 배치 계획 객체 참조 또는 형식 인수를 받아들이려고하는 경우에 때문에 AppDomain에서 해당 유형의 유일한 인스턴스를 보유한다고 보장 할 수는 없습니다.

싱글 톤 패턴의 전체적인 점은 해당 유형의 인스턴스가 하나만 존재할 수 있도록 유형의 단일 인스턴스를 제어하는 ​​것입니다. 인스턴스를 전달할 수 있도록 허용하거나 일반 싱글 톤 공급자를 만드는 경우 인스턴스가 인 경우에만 인스턴스가 보장 될 수 없습니다.

공장에 전달하는 모든 유형 주위에 싱글 톤을 만들 수있는 SingletonFactory<T>이 있다고 가정 해 보겠습니다.즉 매우 편리 할 것 나를 이런 식으로 뭔가 할 수있는 것 :

SingletonFactory<Foo>.Instance; 

하지만이 일에서 저를 중지 :

Foo foo = new Foo(); 

아차,이 Foo 모양을 싱글이 더 이상 아니다 내가 원하는만큼의 인스턴스를 만들 수 있기 때문이다. 싱글 톤 패턴이 작동하려면 인스턴스를 제한해야하는 유형을 완전히 제어 할 수 있어야합니다. 이런 이유로 내 SingletonFactory<T>과 같은 것을 사용하면 안됩니다.

참고 :개체 인스턴스를 허용하는 비제 한 단독 개체도 마찬가지입니다. 내 앞의 예제에서 받아 들여지고 객체 참조를하는 싱글 톤 래퍼 (wrapper)가 왜 나쁜 생각인지 많은 비슷한 이유를 추정 할 수있을 것이다. 특별히 이런 모습을 요구하고 무엇

2

, 나는 생각 :

public sealed class Singleton { 
    static Singleton instance = null; 
    static readonly object padlock = new Object(); 
    Object o; 

    Singleton(Object _o) { 
     o = _o; 
    } 

    public static Singleton Instance(Object _o) { 
     lock (padlock) { 
      if (instance == null) { 
       instance = new Singleton(_o); 
      } 
      return instance; 
     } 
    } 
} 

Singleton s = Singleton.Instance(new Object()); 

가 이미 게시 된 일반 버전은하지만, 당신이 정말로 원하는 것을 생각한다.

1

개인 생성자가 필요하고 getInstance 메소드가 필요합니다.이 메소드는 누가 param을 수신해야하며 생성자는 private이어야하며 params도 가질 수 있지만 getInstance는 전달해야합니다. Btw, 너 뭐하고 있니? 실제 예가 도움이 될 수 있습니다. 당신이 할 수있는

0

한 것은 당신이 발견 싱글 샘플을 고수 단지 속성을 노출 (세터, 필요한 경우뿐만 아니라 게터를 추가)하고 제한해야하는 경우 MySingleton.Instance.MyReference = new MyObject();

처럼 사용 할 수있다 예를 들어, 참조가 설정되기 전에 싱글 톤 객체에 대한 모든 연산이 불법 일 필요가 있다면, 당신은 private boolean 플래그를 가질 수있다. 예를 들어 hasBeenIntialized와 MyReference setter는 플래그를 내부적으로 설정할 것이다. 다른 모든 메소드는 실행 시작시 플래그를 확인하고 hasBeenInitialized가 false 인 경우 메소드가 호출되면 예외를 발생시킵니다.

읽기 전용 동작이 필요한 경우 hasBeenInitialized가 true로 설정된 상태에서 다른 객체를 할당하려는 경우 MyReference setter에서 예외가 발생할 수 있습니다.