2013-11-27 3 views
0

У меня есть приложение asp.net. Я использую singleton pattern для разработки своего кода. Похожее ниже ...Singleton pattern in asp.net

public static class FactoryClass 
    { 
     private static Core obj = null; 
     private static readonly object padLock = new object(); 
     public static Core GetInstance() 
     { 
      lock (padLock) 
      { 
       if (obj == null) 
       { 
        obj = new Core(); 
       } 
      } 
      return obj; 
     } 
    } 

Эта реализация является потокобезопасной. Я хочу знать, правильна ли эта реализация или нет, в случае asp.net (несколько запросов будут иметь общий экземпляр). Пожалуйста, совет ...

+3

Смотрите также http://csharpindepth.com/articles/general/singleton.aspx –

+2

Какова ваша причина сделать что-то статическим singleton в asp.net? Есть ли что-то особенно дорогое, что этот класс будет делать? –

+0

Вы не комментируете Частный конструктор? –

ответ

0

Объем объекта с одной тонной областью будет находиться в домене приложения, что означает, что все сеансы будут использовать объект SingleTon в пределах этого домена приложения (bydefault).

Новый объект будет создан только в том случае, если у вас есть ферма с разными серверами.

Я предпочитаю блокировку только тогда, когда вам нужно построить объект, а не когда вы его вернете. Ниже приведен модифицированный код:

public static class FactoryClass 
{ 
    private static Core obj = null; 
    private static readonly object padLock = new object(); 

    public static Core GetInstance() 
    { 
     lock (padLock) 
     { 
      if (obj == null) 
      { 
       obj = new Core(); 
      } 
     } 
     return obj; 
     } 
} 
+0

Что такое использование частного contructor в singleton pattern? – JIKKU

+0

Я изменил код, мне нужен единый Core-объект, а не заводский. –

+2

эта реализация не является потокобезопасной, поскольку она не обеспечивает атомарность между нулевым тестом и вызовом конструктора. Вы можете взглянуть на http://csharpindepth.com/articles/general/singleton.aspx, как указано @HansKesting – jbl

0

Это зависит от того, какие данные хранятся в объекте типа Core. Скажем, некоторые данные конфигурации, которые вы хотите отдельно управлять (т. Е. Полностью отличаться от настроек в web.config), тогда это имеет смысл.

Однако, скажем, если веб-сайт является приложением корзины покупок ... и вы хотите сохранить объект пользователя таким образом ... скажем, что пользовательский объект содержит список предметов, которые он сохранил на карте. Это будет храниться в appdomain. Следовательно, это противоречит вашей реализации. Потому что вы хотите, чтобы ваша информация пользователя была привязана к входящему запросу, а не всему приложению. Следовательно, по запросу вам нужно будет запросить это хотя бы один раз ... (говоря в традиционном смысле, конечно).

Продолжая на том же примере, представьте, что вы хотите использовать объект пользователя таким образом: этот пользовательский объект используется внутри разных классов внутри вашего веб-приложения. Традиционно люди пишут код для доступа к db и создания объекта каждый раз, когда вам нужно использовать объект пользователя. Вместо этого вам нужен какой-то одноэлементный шаблон. В этом случае ваш пользовательский объект будет запрашиваться (и создан) из db один раз и повторно использоваться на протяжении всего срока службы запроса. Это возможно, если вы кешируете этот объект (после его создания) в кеш-контексте http ... т. Е. HttpContext.Current.Items["foo"]

Следующий код объясняет точку ...

public class AppUser 
{ 
    public string Username { get; set; } 
    public string[] Roles { get; set; } 

    public AppUser() 
    { 
     var appuser = HttpContext.Session["AppUser"] as AppUser; 
     if(appuser == null) 
      throw new Exception("User session has expired"); 
     Username = appuser.Username; 
     Roles = appuser.Roles; 
    } 
} 


public class WebAppContext 
{ 
    const string ContextKey = "WebAppContext"; 

    WebAppContext() { } //empty constructor 
    public static WebAppContext Current 
    { 
     get 
     { 
      var ctx = HttpContext.Current.Items[ContextKey] as WebAppContext; 
      if(ctx == null) 
      { 
       try 
       { 
        ctx = new WebAppContext() { User = new AppUser() }; 
       } 
       catch 
       { 
        //Redirect for login 
       } 
       HttpContext.Current.Items.Add(ContextKey, ctx);      
      }  
      return ctx;  
     } 
    } 

    public AppUser User { get; set; } 
} 

Ps: взяты из этого поста: a request level singleton object in asp.net

+0

@deostoll Код, о котором вы указали, относится к одному экземпляру на пользователя . Я спросил о том, как несколько пользователей обращаются к одному экземпляру – JIKKU

+0

@anish. Я дал пример сценария настроек конфигурации сайта (которые полностью отличаются от настроек в вашем web.config) в самом начале. Например. такой установки могут быть, например, баннерное изображение вашего сайта. Путь изображения можно установить в переменной уровня приложения (в вашем случае статическая переменная) – deostroll