[C#] Singleton monouso in C #


Answers

A quel punto non credo che lo considererei davvero un singleton, a dire il vero.

In particolare, se un cliente utilizza un singleton, non si aspetterebbe che debbano smaltirlo e sarebbero sorpresi se lo facesse qualcun altro.

Cosa farà il tuo codice di produzione?

EDIT: Se davvero, davvero bisogno di questo per i test unitari e solo per i test unitari (che suona discutibile in termini di design, per essere sinceri) allora si potrebbe sempre giocare con il campo usando la riflessione. Sarebbe più bello capire se dovesse essere davvero un singleton o se debba essere effettivamente usa e getta, i due raramente vanno insieme.

Question

Ho un singleton che usa la "static Readonly T Instance = new T ();" modello. Tuttavia, mi sono imbattuto in un caso in cui T è usa e getta, e in realtà deve essere smaltito per i test unitari. Come posso modificare questo modello per supportare un singleton usa e getta?

L'interfaccia che vorrei è qualcosa di simile:

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.

Nota: lo schema deve essere sicuro per i thread, ovviamente.

Modifica : per lo scopo del codice di produzione, questo è un vero singleton. Il fatto è che blocca alcuni file, quindi per la pulizia dei test unitari dobbiamo smaltirlo.

Preferirei anche uno schema che possa essere riutilizzato, se possibile.




Potresti usare un singleton pigro annidato (vedi qui ) con alcune semplici modifiche:

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();
    }
}

Ricordarsi di lanciare ObjectDisposedException in tutti i metodi / proprietà pubbliche dell'oggetto se è stato eliminato.

Dovresti anche fornire un metodo finalizzatore per l'oggetto, nel caso in cui non venga richiamato Dispose. Scopri come implementare correttamente IDisposable qui .




 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;}

  }



Un'altra opzione per creare un Singleton usa e getta è usare l'attributo [Singleton] di SandCastle per la tua classe, quindi Castle framework si occupa di eliminare tutti gli oggetti Singleton monouso