Я разрабатываю приложение блога, совместно использованное некоммерческими организациями. Я хочу, чтобы каждая организация смогла изменить их собственные настройки блога. Я взял шаблон "одиночка" (из BlogEngine.net) и изменил его. (Я понимаю, что это больше не шаблон "одиночка".) Я протестировал этот подход, и это, кажется, хорошо работает в среде разработки. Действительно ли этот шаблон является хорошей практикой? Есть ли проблемы, которые могут возникнуть, когда это помещается в продуктивную среду?
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;
}
}
}
(Части кода были опущены для краткости.)
Спасибо за любую справку, комментарий, и т.д.
Если для каждого сеанса, сохраните его в сеансе, а не в кэше.
Кроме того, здесь вы без причины выполняете восходящее и понижающее преобразование:
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;
Я думаю, у вас все хорошо, но я бы посоветовал повысить производительность, если это станет необходимым (я знаю ... не оптимизируйте, пока вы действительно нужно).
Я бы, вероятно, реализовал это с помощью такого метода, чтобы получить объект настроек:
public static UserBlogSettings getSettings(string orgName, Cache cache) {
// do the same stuff here, except using the method parameters
}
Причина в том, что HttpContext.Current и HttpRuntime.Cache должны пройти несколько циклов, чтобы получить дескрипторы для текущего сеанса и кэша. . Если вы вызываете это со страницы asp.net, у вас уже есть все необходимое. Так что используйте те, которые у вас уже есть, вместо того, чтобы искать их снова.
Вам нужно использовать блокировку, чтобы избежать возможных гоночных условий:
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;
}
}