Frage

Wie implementiere ich das Singletonmuster in C #? Ich möchte, dass meine Konstanten und einige grundlegende Funktionen in sie setzen, wie ich die überall in meinem Projekt verwenden. Ich möchte, dass sie ‚Global‘ haben und nicht manuell jedes Objekt binden muss ich schaffen.

War es hilfreich?

Lösung

Wenn Sie nur einige globale Werte zu speichern und einige Methoden, die Staat nicht brauchen, müssen Sie nicht Singleton benötigen. So stellen Sie die Klasse und ihre Eigenschaften / Methoden statisch.

public static class GlobalSomething
{
   public static int NumberOfSomething { get; set; }

   public static string MangleString( string someValue )
   {
   }
}

Singleton ist besonders nützlich, wenn Sie eine normale Klasse mit Staat haben, aber Sie wollen nur eine von ihnen. Die Links, die andere zur Verfügung gestellt haben, sollten in der Erforschung der Singleton-Muster nützlich sein.

Andere Tipps

Singleton != Global. Sie scheinen für das Schlüsselwort static zu suchen.

Singletons nur Sinn machen, wenn beide diese Bedingungen erfüllt sind:

  1. Das Objekt muss global
  2. Es muss existieren immer nur eine einzigen Instanz des Objekts

Beachten Sie, dass # 2 bedeutet nicht, dass Sie würden wie das Objekt nur eine einzige Instanz haben - wenn das der Fall ist, ist es einfach instanziiert nur einmal - es bedeutet, dass es Muss (wie in es diese gefährlich für nicht wahr zu sein) immer nur eine einzige Instanz sein.

Wenn Sie globale möchten, stellen nur eine globale Instanz von einigen (nicht signleton) Objekt (oder machen es statisch oder was auch immer). Wenn Sie nur eine Instanz wollen, wieder, statisch ist dein Freund. Auch einfach instanziiert nur ein Objekt.

Das ist meiner Meinung nach sowieso.

Sie können wirklich eine Singleton-Implementierung vereinfachen, das ist, was ich benutze:

    internal FooService() { }        
    static FooService() { }

    private static readonly FooService _instance = new FooService();

    public static FooService Instance
    {
        get { return _instance; }
    }

Hmm, das scheint alles ein bisschen kompliziert.

Warum brauchen Sie ein Dependency Injection-Framework einen Singleton zu bekommen? ein IOC-Container verwendet, ist für einige Unternehmen App fein, (solange es natürlich nicht überstrapaziert wird), aber, ach, die fella nur aboiut Umsetzung des Musters wissen will.

Warum nicht immer eifrig instanziiert, dann ein Verfahren bereitzustellen, das die statische zurückgibt, die meisten der oben stehenden Code dann geschrieben weggeht. Folgen Sie dem alten C2 Sprichwort - DoTheSimplestThingThatCouldPossiblyWork ...

Ich würde Ihnen empfehlen, den Artikel lesen Exploring the Singleton Design Muster auf MSDN verfügbar. Es wird ausführlich auf die Merkmale des Rahmens, der das Muster einfach machen zu implementieren.

Als beiseite, würde ich die Zusammenhang Lesung Besuche auf SO über Singletons .

Das Ignorieren der Frage, ob oder nicht, sollten Sie die Singleton-Muster verwenden, die an anderer Stelle diskutiert wurde, würde ich ein Singleton wie folgt implementieren:

/// <summary>
/// Thread-safe singleton implementation
/// </summary>
public sealed class MySingleton {

    private static volatile MySingleton instance = null;
    private static object syncRoot = new object();

    /// <summary>
    /// The instance of the singleton
    /// safe for multithreading
    /// </summary>
    public static MySingleton Instance {
        get {
            // only create a new instance if one doesn't already exist.
            if (instance == null) {
                // use this lock to ensure that only one thread can access
                // this block of code at once.
                lock (syncRoot) {
                    if (instance == null) {
                        instance = new MySingleton();
                    }
                }
            }
            // return instance where it was just created or already existed.
            return instance;
        }
    }


    /// <summary>
    /// This constructor must be kept private
    /// only access the singleton through the static Instance property
    /// </summary>
    private MySingleton() {

    }

}

Static Singletons ist so ziemlich ein Anti-Muster, wenn Sie eine lose gekoppelte Design wollen. Vermeiden Sie, wenn möglich, und es sei denn, dies ist ein sehr einfaches System ist, würde ich empfehlen, einen Blick auf eine der vielen Dependency Injection-Frameworks zur Verfügung, wie http://ninject.org/ oder http://code.google.com / p / Autofac / .

Zur Anmeldung / eine Art verbrauchen als Singleton in Autofac konfiguriert Sie so etwas wie das folgende tun würde:

var builder = new ContainerBuilder()
builder.Register(typeof(Dependency)).SingletonScoped()
builder.Register(c => new RequiresDependency(c.Resolve<Dependency>()))

var container = builder.Build();

var configured = container.Resolve<RequiresDependency>();

Die akzeptierte Antwort ist eine schreckliche Lösung, die durch die Art und Weise, zumindest die Chaps überprüfen, die das Muster tatsächlich umgesetzt.

public class Globals
{
    private string setting1;
    private string setting2;

    #region Singleton Pattern Implementation

    private class SingletonCreator
    {
        internal static readonly Globals uniqueInstance = new Globals();

        static SingletonCreator()
        {
        }
    }

    /// <summary>Private Constructor for Singleton Pattern Implementaion</summary>
    /// <remarks>can be used for initializing member variables</remarks>
    private Globals()
    {

    }

    /// <summary>Returns a reference to the unique instance of Globals class</summary>
    /// <remarks>used for getting a reference of Globals class</remarks>
    public static Globals GetInstance
    {
        get { return SingletonCreator.uniqueInstance; }
    }

    #endregion

    public string Setting1
    {
        get { return this.setting1; }
        set { this.setting1 = value; }
    }

    public string Setting2
    {
        get { return this.setting2; }
        set { this.setting2 = value; }
    }

    public static int Constant1 
    {
        get { reutrn 100; }
    }

    public static int Constat2
    {
        get { return 200; }
    }

    public static DateTime SqlMinDate
    {
        get { return new DateTime(1900, 1, 1, 0, 0, 0); }
    }

}

Ich mag dieses Muster, obwohl es nicht jemand nicht daran hindert, eine Nicht-Singleton-Instanz zu schaffen. Es kann manchmal besser sein kann, die Entwickler in Ihrem Team über die Verwendung der richtige Methodik vs. gehen zu heroischen Längen zu erziehen einige knucklehead zu verhindern, dass der Code in die falsche Art und Weise mit ...

    public class GenericSingleton<T> where T : new()
    {
        private static T ms_StaticInstance = new T();

        public T Build()
        {
            return ms_StaticInstance;
        }
    }

...
    GenericSingleton<SimpleType> builder1 = new GenericSingleton<SimpleType>();
    SimpleType simple = builder1.Build();

Dies gibt Ihnen eine einzelne Instanz (der richtige Weg instanziiert) und wird effektiv faul sein, da der statische Konstruktor erst gebaut genannt bekommt () aufgerufen wird.

Was Sie beschreiben, ist lediglich statische Funktionen und Konstanten, nicht ein Singleton. Das Singleton-Entwurfsmuster (die sehr selten benötigt) beschreibt eine Klasse, die ist instanziiert, aber nur einmal, automatisch, wenn zum ersten Mal verwendet.

Es kombiniert faul Initialisierung mit einem Scheck Mehrfachinstanzierung zu verhindern. Es ist nur wirklich nützlich für Klassen, die eine Vorstellung wickeln, die physisch Singular, wie ein Wrapper um ein Hardware-Gerät ist.

Statische Konstanten und Funktionen sind genau das:. Code, der nicht eine Instanz überhaupt nicht benötigt

Stellen Sie sich diese: „Wird diese Klasse brechen, wenn es mehr als eine Instanz es ist?“ Wenn die Antwort nein ist, müssen Sie nicht einen Singleton benötigen.

hmmm ... Nur wenige Konstanten mit ähnlichen Funktionen ... wäre das nicht besser durch Aufzählungen erreicht werden? Ich weiß, dass Sie eine benutzerdefinierte Enum in Java mit Methoden erstellen und alle sollen die gleiche in C # erreichbar sein, wenn nicht direkt, dann mit einfacher Klasse Singleton mit privatem Konstruktor getan werden kann, unterstützt werden.

Wenn Sie Ihre Konstanten semantisch verwandt sind, sollten Sie als Aufzählungen (oder gleichwertig Konzept), werden Sie alle Vorteile der const statischen Variablen gewinnen + Sie die Typprüfung des Compilers zu Ihrem Vorteil nutzen können.

Meine 2 Cent

Persönlich würde ich für einen Dependency Injection-Framework gehen, wie Unity, alle von ihnen sind in der Lage Singleton Elemente im Container zu konfigurieren und Kopplung von einer Klasse, indem der Abhängigkeit verbessern würden die Abhängigkeit zu verbinden.

Mit dem öffentlichen Konstruktor versteckt, das Hinzufügen eines privaten statischen Feld diese einzige Instanz zu halten, und das Hinzufügen einer statischen Factory-Methode (mit faulen initializer), dass einzelne Instanz zurück

public class MySingleton   
{  
    private static MySingleton sngltn; 
    private static object locker;  
    private MySingleton() {}   // Hides parameterless ctor, inhibits use of new()   
    public static MySingleton GetMySingleton()       
    {     
        lock(locker)
            return sngltn?? new MySingleton();
    }   
}

Ich habe eine Klasse für mein Projekt mit Singleton-Muster geschrieben. Es ist sehr einfach zu bedienen. Hoffe, es wird für Sie arbeiten. Sie finden den Code folgen.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TEClaim.Models
{
public class LogedinUserDetails
{
    public string UserID { get; set; }
    public string UserRole { get; set; }
    public string UserSupervisor { get; set; }
    public LogedinUserDetails()
    {

    }

    public static LogedinUserDetails Singleton()
    {
        LogedinUserDetails oSingleton;

        if (null == System.Web.HttpContext.Current.Session["LogedinUserDetails"])
        {               
            oSingleton = new LogedinUserDetails();
            System.Web.HttpContext.Current.Session["LogedinUserDetails"] = oSingleton;
        }
        else
        {              
            oSingleton = (LogedinUserDetails)System.Web.HttpContext.Current.Session["LogedinUserDetails"];
        }

        //Return the single instance of this class that was stored in the session
        return oSingleton;
    }
}
}

Jetzt können Sie Variablenwert für den obigen Code in Ihrer Anwendung wie folgt gesetzt werden ..

[HttpPost]
public ActionResult Login(FormCollection collection)
{
  LogedinUserDetails User_Details = LogedinUserDetails.Singleton();
  User_Details.UserID = "12";
  User_Details.UserRole = "SuperAdmin";
  User_Details.UserSupervisor = "815978";
  return RedirectToAction("Dashboard", "Home");
}

Und Sie können diejenigen Werte wie folgt abrufen ..

public ActionResult Dashboard()
    {
        LogedinUserDetails User_Details = LogedinUserDetails.Singleton();
        ViewData["UserID"] = User_Details.UserID;
        ViewData["UserRole"] = User_Details.UserRole;
        ViewData["UserSupervisor"] = User_Details.UserSupervisor;

        return View();
    }

In c # könnte es sein (sicher sowie faul Initialisierung Gewinde):

public sealed class MySingleton
{
    static volatile Lazy<MySingleton> _instance = new Lazy<MySingleton>(() => new MySingleton(), true);
    public static MySingleton Instance => _instance.Value;
    private MySingleton() { }
}
public class Singleton
{
   private static Singleton _instance;
   public static Singleton Instance => _instance ?? (_instance = new Singleton());
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top