2010-04-06 28 views
8

Hoy me encontré con un problema y un amigo me recomendó usar una instancia global estática o, más elegantemente, un patrón singleton. Pasé unas horas leyendo sobre singletons, pero algunas cosas aún se me escapan.Uso de singleton en lugar de una instancia global estática

Antecedentes: Lo que intento lograr es crear una instancia de una API y usar esta única instancia en todas mis clases (en lugar de hacer una nueva conexión, etc.).

Parece que hay alrededor de 100 formas de crear un singleton pero con un poco de ayuda de yoda Encontré algunos ejemplos seguros para hilos. .so dado el siguiente código:

public sealed class Singleton 
{ 
    public static Singleton Instance { get; private set; } 

    private Singleton() 
    { 
     APIClass api = new APIClass(); //Can this be done? 
    } 

    static Singleton() { Instance = new Singleton(); } 
} 

cómo/dónde habría que crear una instancia de la clase y este nuevo cómo debe ser llamado desde una clase separada?

EDIT: Soy consciente de la clase Singleton se puede llamar con algo como

Singleton obj1 = Singleton.Instance(); 

pero iba a ser capaz de acceder a los métodos de la clase API (es decir obj1.Start.)? (No es que necesite hacerlo, solo pregunta)

EDIT # 2: Pude haber sido un poco prematuro al verificar la respuesta, pero tengo una pequeña cosa que todavía me está causando problemas. La API está lanzando muy bien, desafortunadamente ¿puedo lanzar dos instancias?

Nuevo Código

public sealed class SingletonAPI 
{ 
public static SingletonAPI Instance { get; private set; } 

private SingletonAPI() {} 

static SingletonAPI() { Instance = new SingletonAPI(); }  

// API method: 
public void Start() { API myAPI = new API();} 
} 

pero si trato de hacer algo como esto ...

SingletonAPI api = SingletonAPI.Instance; 
api.Start(); 
SingletonAPI api2 = SingletonAPI.Instance; // This was just for testing. 
api2.Start(); 

me sale un error que dice que no puedo iniciar más de una instancia.

+4

Usted debe agregue un constructor privado, para evitar que otra clase cree una instancia de una copia de su Singleton. –

+0

Gracias, me lo perdí. – Ryan

+0

No podrá invocar métodos en la clase api, ya que no se está exponiendo. –

Respuesta

9

¿Por qué no acaba de agregar una propiedad APIClass pública a su singleton?

public sealed class Singleton 
{ 
    public static Singleton Instance { get; private set; } 

    private APIClass _APIClass; 

    private Singleton() 
    { 
     _APIClass = new APIClass(); 
    } 

    public APIClass API { get { return _APIClass; } } 

    static Singleton() { Instance = new Singleton(); }  
} 

entonces su sitio vocación parece:

Singleton.Instance.API.DoSomething(); 

O si usted es el autor de la clase API, se podría hacer un producto único en sí, en lugar de envolverlo en un producto único:

public sealed class SingletonAPI 
{ 
    public static SingletonAPI Instance { get; private set; } 

    private SingletonAPI() {} 

    static SingletonAPI() { Instance = new SingletonAPI(); }  

    // API method: 
    public void DoSomething() { Console.WriteLine("hi"); } 
} 

llamada a la API:

SingletonAPI.Instance.DoSomething(); 
+1

@charles Muchas gracias, eso es exactamente lo que necesitaba. – Ryan

3

No creará una instancia de la clase: el patrón que está utilizando se crea básicamente la primera vez que se utiliza. La ventaja del método que está utilizando es que es seguro para subprocesos (solo creará una instancia una vez, sin importar cuántos subprocesos intente acceder), flojo (no creará instancias hasta que intente acceder a la clase Singleton), y simple en implementación.

Todo lo que necesita hacer para utilizar este es hacer:

Singleton.Instance.MyMethodOnSingleton(); 

O, alternativamente:

Singleton myInstance = Singleton.Instance; // Will always be the same instance... 
myInstance.DoSomething(); 
+0

también recomendaría Farstucker leer sobre singletons en msdn http://msdn.microsoft.com/en-us/library/ms998558.aspx – vittore

+0

Lo creas o no, lo leí. Supongo que estoy confundido sobre cómo crear una instancia de una clase completamente diferente y usarla globalmente. Agregué un código para ayudar a explicar lo que trato de hacer. – Ryan

5

Aquí es el official Microsoft approach.

La belleza del singleton es que puede usarlo y acceder a él en cualquier parte de su código sin tener que crear una instancia de la clase. De hecho que es que es la razón de ser, una sola instancia de una clase por ejemplo

Singleton.Instance.MyValue y Singleton.Instance.DoSomething();

Cuestiones relacionadas