SOLID原則とパフォーマンスを考慮して)アプリケーション全体(市、州など)のドロップダウンリストを維持するための最良の方法は何ですか?
現在、リストの値を静的プロパティにロードし、同じように使用しています
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;
}
}
しかし、これが可能な最善のアプローチかどうかはわかりません。提案していただけませんか。
これはいくつかの異なる要因に依存します:
これらの質問への答えがわかっている場合は、特定のケースに最適な場所を自分で解決できると思います。これは、フォーム内のハードコードされたリスト、再利用可能なクラスまたは拡張可能なクラスのリストのいずれかであり、リソースファイル、構成ファイル、またはデータベースに格納されている可能性があります。同じ情報を2つの異なる場所に保存しないでください。
まず、アプリに必要なすべてのデータを提供するデータアクセスインターフェイスから始めます。許可されている郡を提供するための問題のメソッドのみを含む単純なバージョンを次に示します。
public interface IDataAccessProvider
{
Country[] GetCountries();
}
public class Country
{
public string Id { get; set; }
public string Name { get; set; }
}
そして、これがそのインターフェースの最初の実装です:
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>() { ... };
}
これが、アプリケーションキャッシュに物を出し入れするための静的ヘルパークラスです。アプリケーションキャッシュは、静的データなどに頼ることなく、データをアプリに保存してネットワーク/データベース/ fileIOなどに保存する優れた方法です。
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);
}
}
次に、そのDataAccessProviderクラスから、上記のキャッシュメソッドの使用方法を知っている新しいクラスを継承します。
public class CachedDataAccessProvider : DataAccessProvider
{
public override Country[] GetCountries()
{
return CacheHelper.RetrieveThroughCache("AppCountries", () => base.GetCountries());
}
}
これで、MVC ViewModelで、データプロバイダーインターフェイスのインスタンスをどこか下(ベースViewModelコンストラクター、コントローラーからのDIなど)から取得し、データプロバイダーのGetCountries()メソッドを呼び出すことができます。最初の呼び出しはデータベースから新しいものを取得し、その後の1日中のヒット(静的クラスのデフォルトはキャッシュ内の24時間です)は、キャッシュから直接取得します。 County[]
値をSelectListItemsに入力して、ドロップダウンを強化します。
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
};
}
}