Elenchi a discesa Maintaing per l'applicazione

3

Quale sarebbe l'approccio migliore per mantenere gli elenchi a discesa per l'intera applicazione (come città, stato, ecc.) tenendo conto dei principi SOLIDI e delle prestazioni?

In questo momento sto caricando i valori della lista in una proprietà statica e usando lo stesso tipo

public int DestCountry { get; set; }

private string _CountryText;
public string CountryText
{
    get
    {
        if (this.DestCountry > 0)
        {
            _CountryText = Lists.CountryList.Find(x => x.Value == Convert.ToString(this.DestCountry)).Text;
        }
        return _CountryText;
    }
}

Ma non sono sicuro che questo sia l'approccio migliore possibile. La prego di suggerire.

    
posta gvk 08.09.2015 - 13:55
fonte

2 risposte

2

Questo dipende da diversi fattori:

  • prima, chi è responsabile della loro manutenzione (lo sviluppatore dell'applicazione, l'utente, alcuni utenti esperti, un amministratore)?
  • l'elenco è fissato per una versione dell'applicazione, oppure esiste un obbligo di modificare tali valori senza fornire una nuova versione?
  • sono quei testi veramente fissi in una lingua, o ti aspetti che siano localizzati?
  • è l'elenco di valori necessari solo in un modulo / finestra di dialogo / classe o l'elenco sarà necessario in diversi punti dell'applicazione?
  • se è necessario in luoghi diversi, è necessario sempre esattamente nello stesso modo, o sarà talvolta necessario in modi modificati? Ad esempio, deve essere esteso, a seconda del contesto?
  • se il valore del menu a discesa scelto deve essere memorizzato da qualche parte (ad esempio, in un database), come verrà memorizzato? Come un testo fisso? Come un indice? Dove avverrà la mappatura index-to-text?

Se conosci la risposta a queste domande, sono sicuro che puoi lavorare da solo dove il posto migliore è per il tuo caso specifico. Può essere un elenco codificato nel modulo, un elenco in una classe riutilizzabile o estensibile, può essere memorizzato in un file di risorse, in un file di configurazione o in un database. Evita semplicemente di memorizzare le stesse informazioni in due posti diversi.

    
risposta data 08.09.2015 - 14:21
fonte
2

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 
               };
    }
}
    
risposta data 08.10.2015 - 21:33
fonte

Leggi altre domande sui tag