如何在c#中创建一个完美的Singleton类? [英] How to create a perfect Singleton class in c#?

查看:122
本文介绍了如何在c#中创建一个完美的Singleton类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用Singleton类存储一些数据。据我所研究,单身班只能一次实例化。但它对我来说并不奏效有人可以更正我的代码:

  public class MvcApplication:System.Web.HttpApplication 
{
Singleton clientsessionidinstance = Singleton.GetInstance();
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}


public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute({resource} .axd / {* pathInfo} );
routes.MapRoute(
Default,//路由名称
{controller} / {action} / {id},//具有参数的URL
new {controller =Home,action =Index,id = UrlParameter.Optional},
new string [] {MVCPrj.Controllers}
);
}

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

LOGICcLASSES.Logic.Auth ca = new LOGICcLASSES.Logic.Auth();
clientsessionidinstance = Singleton.GetInstance();
clientsessionidinstance.ClientSessionID = ca.Login(new LOGICcLASSES.Entities.ClientAuthentication()
{
IP = HttpContext.Current.Request.ServerVariables [REMOTE_ADDR],
UserName = ConfigurationManager.AppSettings [ClientUserName],
Password = ConfigurationManager.AppSettings [ClientPassword]
});
}

protected void Application_AcquireRequestState(object sender,EventArgs e)
{
if(System.Web.HttpContext.Current.Session!= null)
{
if(!string.IsNullOrEmpty(clientsessionidinstance.ClientSessionID))
{
CurrentUserSession.Store< string>(ClientSessionID,clientsessionidinstance.ClientSessionID);
}
}
}
}

所以目标是这样,@ Application_Start 我必须登录一个帐户。然后我应该将返回字符串保存在 HttpContext.Current.Session 上。

不幸的是我无法访问 HttpContext.Current在 Application_Start 里面的.Session ,但是可以在 Application_AcquireRequestState 上。

我可以使用一个变量来保存返回的字符串,然后在 Application_AcquireRequestState 中使用它的值,但最大的问题是这个页面加载?两次,所以如果我使用一个变量,它将成为 null 在第二次加载但 Application_Start 仍然启动一次。

所以我来了一个Singleton类,但是我仍然在第二次加载时得到空值。



Singleton类:

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

命名空间MVCPrj.Areas.WebPage.Logic
{
public class Singleton
{
private static Singleton instance;

private Singleton(){}

public static Singleton GetInstance()
{
lock(typeof(Singleton))
{
instance = new Singleton();
}
return instance;
}

私有字符串_ClientSessionID;
public string ClientSessionID
{
get {return _ClientSessionID; }
set {_ClientSessionID = value; }
}
}
}

编辑



此代码在阅读 Singleton

  {
private static readonly object _mutex = new object();
private static volatile单例_instance = null;
private Singleton(){}

public static Singleton Instance
{
get
{
if(_instance == null)
{
lock(_mutex)
{
if(_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}

私人字符串_ClientSessionID;
public string ClientSessionID
{
get {return _ClientSessionID; }
set {_ClientSessionID = value;
}
}


解决方案

如果您使用的是.NET4,完美单身通常最好使用 System.Lazy



另请参阅此网页用于描述C#中的许多不同的单例模式及其各种优缺点。


I want to store some data with Singleton class. As far as I've studied, singleton class can be instantiated only for once. But it doesn't work for me. Can someone correct my code:

public class MvcApplication : System.Web.HttpApplication
    {
        Singleton clientsessionidinstance = Singleton.GetInstance();
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }


        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                new string[] { "MVCPrj.Controllers" }
            );
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            LOGICcLASSES.Logic.Auth ca = new LOGICcLASSES.Logic.Auth();
            clientsessionidinstance = Singleton.GetInstance();
            clientsessionidinstance.ClientSessionID = ca.Login(new LOGICcLASSES.Entities.ClientAuthentication()
            {
                IP = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"],
                UserName = ConfigurationManager.AppSettings["ClientUserName"],
                Password = ConfigurationManager.AppSettings["ClientPassword"]
            });
        }

        protected void Application_AcquireRequestState(object sender, EventArgs e)
        {
            if (System.Web.HttpContext.Current.Session != null)
            {
                if (!string.IsNullOrEmpty(clientsessionidinstance.ClientSessionID))
                {
                    CurrentUserSession.Store<string>("ClientSessionID", clientsessionidinstance.ClientSessionID);
                }
            }
        }
    }  

So the goal is this, @ Application_Start I have to log in an account. Then I should save the return string on HttpContext.Current.Session.
Unfortunately I can't access the HttpContext.Current.Session inside Application_Start but it is possible on Application_AcquireRequestState.
I can use a variable that will hold the returned string and then use its value inside the Application_AcquireRequestState, but the big problem is this, the page loads? twice, so if I will use a variable, it will become null at the second load but Application_Start is still initiated once.
So I came up using a Singleton class, but still I get null values on second load.

Singleton class:

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

namespace MVCPrj.Areas.WebPage.Logic
{
    public class Singleton
    {
        private static Singleton instance;

        private Singleton() { }

        public static Singleton GetInstance()
        {
            lock (typeof(Singleton))
            {
                instance = new Singleton();
            }
            return instance;
        }

        private string _ClientSessionID;
        public string ClientSessionID
        {
            get { return _ClientSessionID; }
            set { _ClientSessionID = value; }
        }
    }
}  

EDIT

This code works for me after reading Singleton

public class Singleton
{
    private static readonly object _mutex = new object();
    private static volatile Singleton _instance = null;
    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (_mutex)
                {
                    if (_instance == null)
                    {
                        _instance = new Singleton();
                    }
                }
            }
            return _instance;
        }
    }

    private string _ClientSessionID;
    public string ClientSessionID
    {
        get { return _ClientSessionID; }
        set { _ClientSessionID = value; }
    }
}

解决方案

If you are using .NET4 the "perfect singleton" is often best achieved using System.Lazy.

See also this web page for a description of many different singleton patterns in C# and their various pros and cons.

这篇关于如何在c#中创建一个完美的Singleton类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆