unity - singleton template c#
C#Singleton con constructor que acepta parámetros (5)
Esto generalmente se considera una mala idea porque si va a aceptar una referencia de objeto o un argumento de tipo que planea envolver en un envoltorio tipo singleton no puede garantizar que tenga la única instancia de ese tipo en el dominio de aplicación.
El objetivo principal del patrón de singleton es controlar una sola instancia de un tipo para que solo pueda existir una instancia de ese tipo. Si permite que se pase una instancia o si crea un proveedor singleton genérico, no puede garantizar que su instancia sea la única .
Digamos que tenía un SingletonFactory<T>
que me permitiría crear un Singleton alrededor de cualquier tipo que pase a la fábrica. Eso sería bastante útil y me permitiría hacer algo como esto:
SingletonFactory<Foo>.Instance;
Pero lo que me impide hacer esto también:
Foo foo = new Foo();
Vaya, parece que Foo
ya no es un singleton, ya que puedo crear tantas instancias como lo desee. Para que el patrón de singleton funcione, debe poder controlar completamente el tipo de las instancias que necesita restringir. Esta es la razón por la que no debe usar nada como mi SingletonFactory<T>
.
Nota: Lo mismo ocurre con un singleton no genérico que acepta una instancia de objeto. Estoy seguro de que puede extrapolar de mi ejemplo anterior muchas razones similares por las que un envoltorio Singleton que acepta y una referencia a objetos también sería una mala idea.
Quiero crear una clase estática o una clase singleton que acepte una referencia a otro objeto en su constructor. Las clases estáticas están fuera, pero pensé que podría crear un singleton que acepte parámetros en su constructor. Hasta ahora no he tenido la suerte de descifrar o buscar en Google la sintaxis. es posible? Si es así, ¿cómo lo hago?
Lo siento por ningún ejemplo en la publicación inicial, lo escribí en un apuro. Tengo la sensación de que mi respuesta ya está en las respuestas, pero aquí hay algunas aclaraciones de lo que quiero hacer:
Quiero crear una sola instancia de un tipo específico (dicho Singleton), pero esa única instancia del tipo necesita mantener una referencia a un objeto diferente.
Por ejemplo, me gustaría crear una clase de "Estado" de Singleton, que posee un objeto StringBuilder y un método Draw () al que se puede llamar para escribir dicho StringBuilder en la pantalla. El método Draw () necesita saber acerca de mi GraphcisDevice para poder dibujar. Entonces, qué quiero hacer esto:
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
}
}
En todo el código, recupero mi Status Singleton y llamo a su método UpdateMessage ().
private Status _status = Status.Instance; // + pass reference to GraphicsDevice
_status.UpdateMessage("Foo!");
Luego, en mi clase principal también recupero el singleton, y lo dibujo:
_status.Draw();
Sí, esto significa que dondequiera que recupere el singleton, debo hacerlo pasando la referencia al GraphicsDevice, en caso de que sea la primera vez que cree una instancia del Singleton. Y podría / usaría diferentes medios para recuperar algo tan fundamental como el GraphicsDevice en mi clase Singleton, por ejemplo, registrar un servicio en otro lugar y obtener ese servicio en la clase Status. Este ejemplo fue bastante artificial: estoy tratando de averiguar si algo como este patrón es posible en primer lugar.
Lo que estás describiendo es un Singleton genérico. Se parece a esto:
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();
}
}
Lo que estás pidiendo específicamente se ve así, creo:
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());
Sin embargo, sospecho que la versión genérica ya publicada es lo que realmente quieres.
Necesitas un constructor privado y luego un método getInstance, este método es quién debe recibir el parámetro, el constructor debe ser privado y también puede tener parámetros, pero getInstance debería pasarlo, no tú. Por cierto, ¿qué estás haciendo? Algún ejemplo real podría ayudar.
Una cosa que puede hacer es pegarse a la muestra de singleton que encontró y simplemente exponer una propiedad (el establecedor, si es necesario, agregar el captador también) y usarla como MySingleton.Instance.MyReference = new MyObject();
Si tiene que restringir el uso de su objeto singleton, por ejemplo, cualquier operación en el objeto singleton antes de que se establezca la referencia debe ser ilegal, puede tener un indicador booleano privado, por ejemplo, hasBeenIntialized y el configurador MyReference establecerá el indicador internamente. Todos los demás métodos verifican la bandera al comienzo de la ejecución y lanzan una excepción si se llama a algún método si hasBeenInitialized es falso.
Si necesita tener un comportamiento de solo lectura, puede lanzar una excepción en el configurador de MyReference si alguien quiere asignar un objeto diferente mientras hasBeenInitialized está establecido en verdadero.