문제

C#에서 싱글 톤 패턴을 어떻게 구현합니까? 프로젝트의 모든 곳에서 사용하면 상수와 몇 가지 기본 기능을 넣고 싶습니다. 나는 그것들을 '글로벌'하고 싶고 내가 만든 모든 객체를 수동으로 바인딩 할 필요는 없습니다.

도움이 되었습니까?

해결책

글로벌 값을 저장하고 상태가 필요하지 않은 몇 가지 방법이 있다면 싱글 톤이 필요하지 않습니다. 클래스와 그 속성/방법을 정적으로 만들 수 있습니다.

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

   public static string MangleString( string someValue )
   {
   }
}

싱글 톤은 상태가 정상적인 클래스가있을 때 가장 유용하지만 그중 하나만 원합니다. 다른 사람들이 제공 한 링크는 싱글 톤 패턴을 탐색하는 데 유용해야합니다.

다른 팁

Singleton != Global. 키워드를 찾고있는 것 같습니다 static.

싱글 톤은 만 이해가됩니다 둘 다 이러한 조건 중에서 :

  1. 객체는 있어야합니다 글로벌
  2. 만 존재해야합니다 하나의 객체의 인스턴스

#2가 당신을 의미하지는 않습니다 처럼 단일 인스턴스 만있는 개체 - 그렇다면 단순히 한 번만 인스턴스화합니다. ~ 해야 하다 (사실이 아니라는 것은 위험합니다) 단일 인스턴스 일뿐입니다.

글로벌을 원한다면 일부 (비 Signleton) 객체 (또는 정적 또는 무엇이든)의 전역 인스턴스를 만드십시오. 하나의 인스턴스 만 원한다면 다시 정적은 친구입니다. 또한 단순히 하나의 객체 만 인스턴스화합니다.

어쨌든 내 의견.

싱글 톤 구현을 실제로 단순화 할 수 있습니다. 이것이 제가 사용하는 것입니다.

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

    private static readonly FooService _instance = new FooService();

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

흠,이 모든 것이 조금 복잡해 보입니다.

싱글 톤을 얻기 위해 종속성 주입 프레임 워크가 필요한 이유는 무엇입니까? 일부 엔터프라이즈 앱에서는 IOC 컨테이너를 사용하는 것이 좋습니다 (물론 과도하게 사용되지 않는 한), AH, Fella는 Aboiut가 패턴을 구현하는 것을 알고 싶어합니다.

항상 간절히 인스턴스화하지 말고 정적을 반환하는 메소드를 제공하지 않으면 위에 쓰여진 대부분의 코드가 사라집니다. 기존 C2 낙서를 따르십시오 -DothesImplest를 따라 가십시오.

기사를 읽는 것이 좋습니다 싱글 톤 디자인 패턴 탐색 MSDN에서 사용할 수 있습니다. 패턴을 구현하기가 간단하게 만드는 프레임 워크의 기능을 자세히 설명합니다.

제쳐두고, 나는 그것을 확인했다 싱글 톤에 관한 관련 독서.

다른 곳에서 논의 된 싱글 톤 패턴을 사용해야하는지 여부에 대한 문제를 무시하면 다음과 같은 싱글 톤을 구현할 것입니다.

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

    }

}

정적 싱글 톤은 느슨하게 결합 된 디자인을 원한다면 거의 반 패턴입니다. 가능한 경우 피하십시오. 이것이 매우 간단한 시스템이 아니라면 사용 가능한 많은 의존성 주입 프레임 워크 중 하나를 살펴 보는 것이 좋습니다. 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>();

허용 된 대답은 끔찍한 솔루션입니다. 그건 그렇고, 적어도 실제로 패턴을 구현 한 챕터를 확인하십시오.

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

}

이 패턴이 마음에 들지만 누군가가 비 싱턴 인스턴스를 만들지 못하게하는 것은 아닙니다. 때때로 팀의 개발자가 올바른 방법론을 사용하는 것과 영웅 길이로 이동하여 코드를 잘못 사용하지 못하게하는 것이 더 나을 수 있습니다.

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

이렇게하면 단일 인스턴스 (올바른 방식으로 인스턴스화)가 제공되며 효과적으로 게으 르며 정적 생성자는 빌드 ()가 호출 될 때까지 호출되지 않기 때문입니다.

당신이 설명하는 것은 단지 정적 기능과 상수입니다. ~ 아니다 싱글 톤. 싱글 톤 디자인 패턴 (거의 필요하지 않은)은 수업을 설명합니다. ~이다 처음 사용하면 자동으로 한 번만 인스턴스화하지만 한 번만 인스턴스화합니다.

게으른 초기화와 다중 인스턴스화를 방지하기 위해 점검을 결합합니다. 하드웨어 장치 주변의 래퍼와 같이 물리적으로 특이한 개념을 감싸는 클래스에만 유용합니다.

정적 상수와 함수는 바로 다음과 같습니다. 인스턴스가 필요하지 않은 코드.

"이 수업이 하나 이상 있으면이 수업이 중단 될까요?" 대답이 아니오 인 경우 싱글 톤이 필요하지 않습니다.

흠 ... 관련 기능이있는 상수는 거의 없습니다 ... 열거를 통해 달성되지 않습니까? 나는 당신이 방법으로 Java로 사용자 정의 열거를 만들 수 있다는 것을 알고 있습니다. 모든 것이 C#에서 동일하게 달성 할 수 있어야합니다. 직접 지원되지 않으면 개인 생성자가있는 간단한 클래스 싱글 톤으로 수행 할 수 있습니다.

상수가 의미 적으로 관련되어 있으면 열거 (또는 동등한 개념)를 고려해야합니다. const 정적 변수의 모든 장점을 얻게됩니다. + 컴파일러의 유형 검사를 유리하게 사용할 수 있습니다.

내 2 센트

개인적으로 나는 Unity와 같은 종속성 주입 프레임 워크를 위해 갈 것입니다. 모두 컨테이너에서 싱글 톤 항목을 구성 할 수 있으며 클래스 종속성에서 인터페이스 종속성으로 이동하여 커플 링을 향상시킵니다.

공개 생성자를 숨기고,이 전용 인스턴스를 유지하기 위해 개인 정적 필드를 추가하고, 정적 공장 메소드 (게으른 이니셜 라이저 포함)를 추가하여 단일 인스턴스를 반환합니다.

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

싱글 톤 패턴을 사용하여 프로젝트 수업을 작성했습니다. 사용하기가 매우 쉽습니다. 그것이 당신을 위해 효과가 있기를 바랍니다. 다음 코드를 찾으십시오.

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

C#에서는 (스레드 안전 및 게으른 초기화) 일 수 있습니다.

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());
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top