TekPub ビデオで見られるように、Jon Skeet のスレッドセーフな Singleton パターンを使用する Singleton クラスがあります。このクラスは、MVC 3 UI のドロップダウンのキャッシュされた参照データのリストを表します。
リスト データを取得するために、クラスは DAL の静的クラスで静的メソッドを呼び出します。
DALクラスにインターフェースを実装したいのですが、静的で静的メソッドが1つしかないため、作成するインターフェースがないため、明らかにできません。そのため、インターフェイスを実行できるように、静的実装を削除したいと考えています。
そうすることで、参照クラスからメソッドを静的に呼び出すことができなくなり、参照クラスがプライベート ctor を持つシングルトンであるため、インターフェイスを注入できなくなります。どうすればこれを回避できますか? インターフェイスを参照クラスに取得して、DI を使用し、モックで正常にテストできるようにするにはどうすればよいですか?
これが現在の形式の私のDALクラスです
public static class ListItemRepository {
public static List<ReferenceDTO> All() {
List<ReferenceDTO> fullList;
... /// populate list
return fullList;
}
}
これは私がそれをどのように見せたいかです
public interface IListItemRepository {
List<ReferenceDTO> All();
}
public class ListItemRepository : IListItemRepository {
public List<ReferenceDTO> All() {
List<ReferenceDTO> fullList;
... /// populate list
return fullList;
}
}
そして、これが私のシングルトン参照クラスです。静的メソッドへの呼び出しはCheckRefresh
呼び出しにあります
public sealed class ListItemReference {
private static readonly Lazy<ListItemReference> instance =
new Lazy<ListItemReference>(() => new ListItemReference(), true);
private const int RefreshInterval = 60;
private List<ReferenceDTO> cache;
private DateTime nextRefreshDate = DateTime.MinValue;
public static ListItemReference Instance {
get { return instance.Value; }
}
public List<SelectListDTO> SelectList {
get {
var lst = GetSelectList();
lst = ReferenceHelper.AddDefaultItemToList(lst);
return lst;
}
}
private ListItemReference() { }
public ReferenceDTO GetByID(int id) {
CheckRefresh();
return cache.Find(item => item.ID == id);
}
public void InvalidateCache() {
nextRefreshDate = DateTime.MinValue;
}
private List<SelectListDTO> GetSelectList() {
CheckRefresh();
var lst = new List<SelectListDTO>(cache.Count + 1);
cache.ForEach(item => lst.Add(new SelectListDTO { ID = item.ID, Name = item.Name }));
return lst;
}
private void CheckRefresh() {
if (DateTime.Now <= nextRefreshDate) return;
cache = ListItemRepository.All(); // Here is the call to the static class method
nextRefreshDate = DateTime.Now.AddSeconds(RefreshInterval);
}
}
}