La memorizzazione di dati che raramente cambia in memoria è un buon candidato per un singleton / cache?

1

Ho una classe chiamata DataPoint che è definita come la seguente. Attualmente, passa attraverso ogni proprietà su un oggetto e in base a DataPoint , esegue alcune formattazioni come padding, trimming, ecc. Prima di salvare il record nel database. L'attuale implementazione makes a database call for each property che è lenta, quindi il mio primo passo è quello di ottenere tutto in una raccolta in memoria. Cos'altro posso fare qui sotto? È un buon candidato per un singleton dato che i dati cambiano raramente e / o è possibile memorizzarlo nella cache (se sì, come)?

public class DataPoint
{
    public string Name {get;set;}
    public string Justification {get;set;}
    public int MaxLength {get;set;}
    public string Format {get;set;}


    public DataPoint GetDataPoint(string name)
    {
        var dataPoint =
            db.Query<DataPoint>("SELECT * FROM DataPoint WHERE name = @name", new {name}).FirstOrDefault();

        return dataPoint;
    }

    public T FormatObj<T>(T obj)
    {
        foreach (var propertyInfo in typeof(T).GetProperties())
        {
            var dataPoint = GetDataPoint(propertyInfo.Name);

            //Do formatting on obj Properties such as setting values, etc...
        }

        return obj;
    }

}
    
posta xaisoft 26.03.2015 - 05:59
fonte

2 risposte

1

Puoi usare Memory Cache. Io uso la cache della memoria per memorizzare i dati raramente o al momento specifico.

Ecco un esempio:

public static T GetCache<T>(string key, Func<T> initializer) where T : new() {
    if (!MemoryCache.Default.Contains(key)) {
        try {
            T data = initializer();
            AddData(key, data);
            return (T)MemoryCache.Default[key];
        } catch (Exception ex) {
            LogHelper.WriteError(MethodBase.GetCurrentMethod(), ex);
            return default(T);
        }
    }
    return (T)MemoryCache.Default[key];
}

public static void AddData(string key, object data) {
    if (data == null) {
        return;
    }
    var cacheTime = int.Parse(ConfigurationManager.AppSettings["CachingExpiredTime"]);
    AddData(key, data, cacheTime);
}

private static void AddData(string key, object data, int cacheMinute) {
    if (data == null) {
        return;
    }
    var policy = new CacheItemPolicy { AbsoluteExpiration = DateTime.Now.AddMinutes(cacheMinute) };
    MemoryCache.Default.Add(new CacheItem(key, data), policy);
}
    
risposta data 26.03.2015 - 06:19
fonte
0

Direi di no. Raramente un singleton è la risposta. Se non credi fai una rapida ricerca su singleton anti pattern. Il problema principale è che è difficile il codice di test unitario che utilizza un singleton.

Un approccio molto più flessibile è l'inversione del modello di controllo. Fondamentalmente si farebbe in modo che la classe che userebbe la cache dipenda da un'istanza IDataPoint nel costruttore e quindi si trovi nel punto di chiamata per decidere come creare o riutilizzare e quale implementazione di IDataPoint desidera fornire.

    
risposta data 26.03.2015 - 07:43
fonte

Leggi altre domande sui tag