2010-02-09 2 views
6

Я разрабатываю приложение для блога, которое предоставляет некоммерческие организации. Я хочу, чтобы каждая организация могла изменять свои собственные настройки блога. Я взял шаблон singleton (из BlogEngine.net) и изменил его. (Я понимаю, что это уже не одноэлементный шаблон.) Я протестировал этот подход и, похоже, отлично работает в среде разработки. Является ли эта модель хорошей практикой? Существуют ли проблемы, которые могут возникнуть, когда они помещаются в производственную среду?Является ли этот модифицированный C# singleton образцом хорошей практикой?

public class UserBlogSettings 
    { 
    private UserBlogSettings() 
    { 
     Load(); 
    } 

    public static UserBlogSettings Instance 
    { 
      get 
      { 
       string cacheKey = "UserBlogSettings-" + HttpContext.Current.Session["userOrgName"].ToString(); 
       object cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings; 
       if (cacheItem == null) 
       { 
        cacheItem = new UserBlogSettings(); 
        HttpRuntime.Cache.Insert(cacheKey, cacheItem, null, DateTime.Now.AddMinutes(1), 
              Cache.NoSlidingExpiration); 
       } 
       return (UserBlogSettings) cacheItem; 
      } 
    } 
}  

(части кода были опущены для краткости.)

Спасибо за любую помощь, комментарии и т.д.

ответ

5

Если его за сеанс, сохранить его в сессии, а не в кэше.

Кроме того, вы и понижающее приведение Приведение к базовому типу без причины здесь:

object cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings; 

это удаляет ненужные слепки

UserBlogSettings cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings; 
if (cacheItem == null) 
{ 
    cacheItem = new UserBlogSettings(); 
    HttpRuntime.Cache.Insert(cacheKey, cacheItem, null, 
         DateTime.Now.AddMinutes(1), 
         Cache.NoSlidingExpiration); 
} 
return cacheItem; 
+0

Это по организации пользователя (в отличие от пользователя) - так организация хуг может иметь много пользователей на сайте одновременно просматривать свой блог , –

+1

@geri Это имеет смысл. Помимо отливки, это неплохо. Вы уверены, что хотите только его кешировать в течение минуты? Рассмотрим время жизни объекта при создании/вставке его в кеш. – Will

+0

Спасибо за предложение кастинга - одноминутный кеш предназначен только для разработки. Как насчет статического экземпляра? Любые проблемы с этим? –

0

Я думаю, ваш хорошо в целом, но я хотел бы предложить работу если это становится необходимым (я знаю ... не оптимизируйте, пока вам это не понадобится).

я бы, вероятно, осуществить это с помощью метода, как это, чтобы получить настройки объекта:

public static UserBlogSettings getSettings(string orgName, Cache cache) { 
    // do the same stuff here, except using the method parameters 
} 

Причина этого заключается в том, что HttpContext.Current и HttpRuntime.Cache должны пройти через несколько циркуляций, чтобы получить дескрипторы текущий сеанс и кеш. Если вы вызываете это с страницы asp.net, у вас уже есть что-то в руке. Поэтому используйте те, которые у вас уже есть, а не просматривайте их снова.

3

Вы должны использовать блокировку, чтобы избежать возможных условий гонки:

private static Object lock_Instance = new Object(); 
    public static UserBlogSettings Instance 
    { 
     get 
     { 
      string cacheKey = "UserBlogSettings-" + HttpContext.Current.Session["userOrgName"].ToString(); 
      UserBlogSettings cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings; 
      if (cacheItem == null) 
      { 
       lock (lock_Instance) 
       { 
        // need to check again in case another thread got in here too 
        cacheItem = HttpRuntime.Cache[cacheKey] as UserBlogSettings; 
        if (cacheItem == null) 
        { 
         cacheItem = new UserBlogSettings(); 
         HttpRuntime.Cache.Insert(cacheKey, cacheItem, null, 
          DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration); 
        } 
       } 
      } 
      return cacheItem; 
     } 
    } 
Смежные вопросы