2008-10-29 22 views
24

मैं सी # में सिंगलटन पैटर्न कैसे कार्यान्वित करूं? मैं अपने स्थिरांक और कुछ बुनियादी कार्यों को इसमें रखना चाहता हूं क्योंकि मैं अपने प्रोजेक्ट में उन सभी का उपयोग करता हूं। मैं उन्हें 'ग्लोबल' रखना चाहता हूं और उन्हें बनाए गए हर ऑब्जेक्ट को मैन्युअल रूप से बाध्य करने की आवश्यकता नहीं है।सी # में सिंगलटन को कैसे कार्यान्वित करें?

+1

मैं आपको लगता है वोटों को ध्यान में रखना चाहिए और अपने स्वीकृत उत्तर पर पुनर्विचार करना चाहिए। –

+0

मुझे नहीं पता - tvanfosson का जवाब प्रश्न के शरीर के लिए बहुत अच्छा है, भले ही यह शीर्षक के लिए न हो। तर्कसंगत रूप से एक दूसरे से मेल खाने के लिए शरीर या शीर्षक को बदलना सबसे अच्छा होगा :) –

+0

उस –

उत्तर

28

यदि आप कुछ वैश्विक मूल्यों को संग्रहित कर रहे हैं और कुछ विधियों को राज्य की आवश्यकता नहीं है, तो आपको सिंगलटन की आवश्यकता नहीं है। बस वर्ग और इसकी गुण/विधियों को स्थिर बनाएं।

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

    public static string MangleString(string someValue) 
    { 
    } 
} 

सिंगलटन सबसे उपयोगी है जब आपके पास राज्य के साथ सामान्य श्रेणी है, लेकिन आप केवल उनमें से एक चाहते हैं। अन्य जो लिंक प्रदान किए गए लिंक सिंगलटन पैटर्न की खोज में उपयोगी होना चाहिए।

+0

यदि आप केवल स्थिरांक बनाना चाहते हैं, तो 'कॉन्स्ट' कीवर्ड का उपयोग करें। स्टेटिक की आवश्यकता नहीं है। ध्यान रखें कि इस दृष्टिकोण का उपयोग करके, स्थिरांक सीधे असेंबली में रेखांकित हो जाते हैं। – bryanbcook

+1

यदि आप सचित्र के रूप में एक सेटटर विधि चाहते हैं तो कॉन्स्ट का उपयोग नहीं कर सकते हैं। कॉन्स का उपयोग करना इसे पढ़ता है। – tvanfosson

+0

एक वैश्विक के लिए जिसे हर किसी द्वारा पढ़ और लिखा जा सकता है .. मैं कम से कम एक न्यूनतम लॉक की सिफारिश करता हूं। – FOR

3

मैं आपको एमएसडीएन पर उपलब्ध लेख Exploring the Singleton Design Pattern लेख पढ़ने की सलाह दूंगा। यह ढांचे की विशेषताओं का विवरण देता है जो पैटर्न को लागू करने के लिए सरल बनाते हैं।

एक तरफ के रूप में, मैं related reading on SO regarding Singletons देखेंगे।

+0

+1, अच्छा लेख, सिंगलेटटन पैटर्न को कार्यान्वित करने के लिए कितना आसान तरीका:

 sealed class Singleton { private Singleton() {} public static readonly Singleton Instance = new Singleton(); } 
ArBR

+0

एमएसडीएन लिंक के लिए नया यूआरएल: http://msdn.microsoft.com/en-us/library/Ee817670%28pandp.10%29। एएसपीएक्स –

7

Singleton != Global। आप खोजशब्द static खोज रहे हैं।

4

Singletons केवल बनाने भावना अगर इन शर्तों के दोनों सत्य हैं:

  1. ऑब्जेक्ट होना चाहिए वैश्विक
  2. वहाँ केवल कभी एक एकल वस्तु का उदाहरण मौजूद होना चाहिए

ध्यान दें कि # 2 का मतलब यह नहीं है कि आप ऑब्जेक्ट की तरह केवल एक ही उदाहरण के लिए - यदि मामला है, तो बस इसे केवल एक बार तुरंत चालू करें - इसका मतलब है कि (जैसा कि, यह सच नहीं होना खतरनाक है) केवल एक ही उदाहरण हो।

यदि आप वैश्विक चाहते हैं, तो बस कुछ (गैर साइनलेटन) ऑब्जेक्ट का वैश्विक उदाहरण बनाएं (या इसे स्थैतिक या जो भी हो)। यदि आप केवल एक उदाहरण चाहते हैं, तो फिर, स्थिर आपका मित्र है। इसके अलावा, बस केवल एक वस्तु को तुरंत चालू करें।

वैसे भी मेरी राय है।

/// <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() { 

    } 

} 
3

किया जाए या नहीं आप सिंगलटन पैटर्न है, जो कहीं और चर्चा की गई का उपयोग करना चाहिए के मुद्दे की अनदेखी कर, मैं इस तरह एक सिंगलटन लागू करेगा एक कमजोर युग्मित डिजाइन चाहते हैं। यदि संभव हो तो से बचें, और जब तक कि यह एक बहुत ही सरल प्रणाली नहीं है, मैं http://ninject.org/ या http://code.google.com/p/autofac/ जैसे कई निर्भरता इंजेक्शन ढांचे में से एक को देखने की अनुशंसा करता हूं।

रजिस्टर करने के लिए/एक प्रकार autofac में एक सिंगलटन के रूप में विन्यस्त उपभोग आप की तरह कुछ करना होगा निम्नलिखित:

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

स्वीकार किए जाते हैं जवाब, वैसे एक भयानक समाधान है कम से कम लोग है जो वास्तव में लागू किया जाँच पैटर्न।

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

    private static readonly FooService _instance = new FooService(); 

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

दिलचस्प। मुहरबंद, अस्थिर, और ताला के उपयोग के बारे में एक संक्षिप्त विवरण देखना उपयोगी होगा। – DOK

+1

यह डबल-चेक लॉकिंग एल्गोरिदम है। आपको इसके साथ बहुत सावधान रहना होगा - एक पैर बाहर जगह (उदा। उदाहरण आवृत्ति अस्थिर बनाने में विफल) और यह थ्रेड-सुरक्षित नहीं है। सरल रूप लगभग हमेशा आवश्यक होते हैं, आमतौर पर अधिक कुशलता से आईएमओ। –

+1

ऊपर मेरे सरल सिंगलटन देखें, जॉन स्कीट सही है। – FlySwat

3

स्टेटिक सिंगलटन अगर आप काफी एक विरोधी पैटर्न है:

+0

स्वीकृत उत्तर एक सिंगलटन नहीं है, लेकिन वास्तव में जो मैं प्राप्त करना चाहता था। – Andre

4

आप वास्तव में एक सिंगलटन कार्यान्वयन को आसान बनाने में कर सकते हैं, यह मैं क्या उपयोग है। सिंगलटन डिज़ाइन पैटर्न (जिसे बहुत ही कम आवश्यकता है) एक वर्ग का वर्णन करता है कि तत्काल है, लेकिन केवल एक बार, स्वचालित रूप से, जब पहली बार उपयोग किया जाता है।

यह एकाधिक तत्कालता को रोकने के लिए आलसी प्रारंभिकरण को एक चेक के साथ जोड़ता है। यह केवल कक्षाओं के लिए वास्तव में उपयोगी है जो कुछ अवधारणा को लपेटते हैं जो भौतिक रूप से एकवचन है, जैसे एक हार्डवेयर डिवाइस के चारों ओर एक रैपर।

स्टेटिक स्थिरांक और कार्य केवल यही हैं: कोड जिसे किसी उदाहरण की आवश्यकता नहीं है।

अपने आप से यह पूछें: "क्या इस वर्ग को तोड़ दिया जाएगा यदि इसके एक से अधिक उदाहरण हैं?" अगर उत्तर नहीं है, तो आपको सिंगलटन की आवश्यकता नहीं है।

+0

इसे एक सच्चे सिंगलटन बनाने के लिए, मैंने 'इंस्टेंस' प्रॉपर्टी में 'नया' रखा होगा, केवल एक बार तुरंत चालू करने के लिए। – spoulson

+2

एक निजी स्थैतिक रीडोनली में पहले सेफिल्डइनिट चिह्नित है, यह असेंबली लोड होने पर एक बार तत्काल होगा, और फिर कभी नहीं होगा। – FlySwat

1

क्या आप का वर्णन कर रहे हैं केवल स्थिर कार्यों और स्थिरांक है, नहीं एक सिंगलटन:

1

hmmm ... संबंधित कार्यों के साथ कुछ स्थिरांक ... क्या यह बेहतर नहीं होगा कि enums के माध्यम से हासिल किया जा सके? मुझे पता है कि आप विधियों और सभी के साथ जावा में कस्टम एनम बना सकते हैं, वही सी # में प्राप्य होना चाहिए, अगर सीधे समर्थित नहीं है तो निजी कन्स्ट्रक्टर के साथ सरल वर्ग सिंगलटन के साथ किया जा सकता है।

यदि आपके स्थिरांक अर्थात् संबंधित हैं तो आपको enums (या समकक्ष अवधारणा) माना जाना चाहिए, आपको स्थिर स्थिर चर के सभी फायदे मिलेंगे + आप कंपाइलर की प्रकार की जांच के अपने लाभ के लिए उपयोग करने में सक्षम होंगे।

मेरे 2 प्रतिशत

0

, सार्वजनिक निर्माता छुपा यह केवल उदाहरण धारण करने के लिए एक निजी स्थिर क्षेत्र जोड़ने, और (आलसी प्रारंभकर्ता के साथ) एक स्थिर कारखाने विधि कहा कि एक उदाहरण

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

वापस जाने के लिए तक व्यक्तिगत रूप से मैं एक निर्भरता इंजेक्शन ढांचे के लिए जाना चाहूंगा, जैसे यूनिटी, वे सभी कंटेनर में सिंगलटन आइटम कॉन्फ़िगर करने में सक्षम हैं और कक्षा निर्भरता से इंटरफ़ेस निर्भरता तक बढ़कर युग्मन में सुधार करेंगे।

4

हम्म, यह सब कुछ जटिल लगता है।

सिंगलटन प्राप्त करने के लिए आपको निर्भरता इंजेक्शन ढांचे की आवश्यकता क्यों है? किसी आईओसी कंटेनर का उपयोग कुछ एंटरप्राइज़ ऐप के लिए ठीक है, (जब तक यह निश्चित रूप से अधिक उपयोग नहीं किया जाता है), लेकिन, आह, पैटर्न को कार्यान्वित करने के लिए अबूईट को जानना चाहता है।

हमेशा बेसब्री से तत्काल क्यों न करें, फिर एक विधि प्रदान करें जो स्थैतिक लौटाता है, ऊपर लिखा गया अधिकांश कोड तब चला जाता है। हालांकि यह एक गैर सिंगलटन उदाहरण बनाकर से किसी को रोकने नहीं करता है, DoTheSimplestThingThatCouldPossiblyWork ...

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

} 
2

मैं इस पैटर्न की तरह - पुराने सी 2 कहावत का पालन करें। कभी-कभी यह बेहतर हो सकता है कर सकते हैं सही कार्यप्रणाली बनाम वीर लंबाई करने के लिए जा रहा का उपयोग कर अपने कोड गलत तरीके से उपयोग करने से कुछ knucklehead को रोकने के लिए पर अपनी टीम में डेवलपर्स को शिक्षित करने के ...

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

यह आपको एक दे देंगे एकल उदाहरण (सही तरीके से तत्काल) और प्रभावी रूप से आलसी हो जाएगा, क्योंकि स्थैतिक कन्स्ट्रक्टर को कॉल() कहा जाता है जब तक कॉल नहीं किया जाता है।

0

मैंने सिंगलटन पैटर्न का उपयोग करके अपनी परियोजना के लिए एक कक्षा लिखी है। यह इस्तेमाल में बहुत आसान है। उम्मीद है कि यह आपके लिए काम करेगा। कृपया निम्नलिखित कोड पाएं।

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

अब तुम इस तरह अपने आवेदन में उपरोक्त कोड के लिए चर मूल्य निर्धारित कर सकते हैं ..

[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"); 
} 

और तुम इस तरह उन मान प्राप्त कर सकता ..

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(); 
    } 
संबंधित मुद्दे