Vorrei iniziare con un'interfaccia di accesso ai dati che fornisce tutti i dati necessari alla tua app. Ecco una versione semplice con solo il metodo in questione per fornire le contee consentite:
public interface IDataAccessProvider
{
Country[] GetCountries();
}
public class Country
{
public string Id { get; set; }
public string Name { get; set; }
}
Ed ecco la prima implementazione di tale interfaccia:
public class DataAccessProvider : IDataAccessProvider
{
// gets them from dbase, file, xml, blah blah blah
// doesn't matter, just some resource that isn't hard coded
return new List<County>() { ... };
}
Ora, ecco una classe helper statica per inserire e uscire dalla cache dell'applicazione. Application Cache è un ottimo modo per archiviare i dati in un'app per salvare su rete / database / fileIO ecc., Senza dover ricorrere a statica e simili.
public static class CacheHelper
{
public static void Insert<T>(string cacheKey, T objToCache, double hoursBeforeExpiration)
{
if (objToCache != null && typeof(T).IsValueType && Nullable.GetUnderlyingType(typeof(T)) == null)
throw new Exception(string.Format("Dont add non-nullable stuff to the cache. Type: {0} KeyName: {1}", typeof(T), cacheKey));
var expire = DateTime.Now.AddHours(hoursBeforeExpiration);
HttpContext.Current.Cache.Insert(cacheKey, objToCache, null, expire, Cache.NoSlidingExpiration);
}
public static T Get<T>(string cacheItemName)
{
try { return (T)HttpContext.Current.Cache[cacheItemName]; }
catch { return default(T); }
}
public static T RetrieveThroughCache<T>(string keyName, Func<T> retrievalCall, double hoursBeforeExpiration = 1)
{
var objFromCache = CacheHelper.Get<T>(keyName);
if (objFromCache != null)
return objFromCache;
var objFromDataCall = retrievalCall();
Insert(keyName, objFromDataCall, hoursBeforeExpiration);
return objFromDataCall;
}
public static void Remove(string keyName)
{
HttpContext.Current.Cache.Remove(keyName);
}
}
Successivamente, ereditiamo da quella classe DataAccessProvider con una nuova classe che sa come usare i metodi di caching sopra:
public class CachedDataAccessProvider : DataAccessProvider
{
public override Country[] GetCountries()
{
return CacheHelper.RetrieveThroughCache("AppCountries", () => base.GetCountries());
}
}
Ora in MVC ViewModels, ottieni un'istanza dell'interfaccia del dataprovider da qualche parte in basso (costruttore ViewModel di base, DI dal controller, ecc. ecc.) e puoi semplicemente chiamare il metodo GetCountries () del dataprovider senza preoccuparti se è nella cache o non. La prima chiamata lo recupererà dal database, e i successivi hit nell'intero giorno (il valore predefinito nella mia classe statica è di 24 ore nella cache) lo prenderanno direttamente dalla cache. Puoi convertire i valori di County[]
in SelectListItems per alimentare i menu a discesa.
public class MyWhateverViewModel
{
public string SelectedCountryId { get; set; }
public IEnumerable<SelectListItem> GetCountryChoices()
{
var dataProvider = GetIDataProviderInstance(); // or pass as param in constructor, etc
return from country in dataProvider.GetCountries()
select new SelectListItem {
Text = country.Name,
Value = country.Id,
Selected = country.Id == SelectedCountryId
};
}
}