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.