asp.netアプリケーションで使用するために、クラスライブラリにキャッシュを正しく実装する
-
03-07-2019 - |
質問
asp.netアプリケーションで使用しているクラスライブラリにキャッシュを実装しています。
キャッシュを更新する静的メソッドを使用して、キャッシュオブジェクトをシングルトンパターンとして作成しました。これは、キャッシュが必要なデータのコレクションでメンバー変数/プロパティを実際にロードするだけです(もちろん、ロックロジックを取得します)。
を呼び出すだけでデータにアクセスできるので、良い方法だと思いましたMyCacheObject.Instance.MyDataCollection
キーでパーティション分割された非常に大量のデータを保存するために、新しいキャッシュオブジェクトを作成しています。私が言っていることは、新しいキャッシュを作成していますが、これはすべてのデータを一度にロードするのではなく、アクセスされたキーごとにコレクションを保存します。
MyOtherCacheObject.Instance.MyOtherDataCollection(indexkey)
今回は、ガベージコレクションに関する質問が提起されました。膨大な量のデータを保存しているので、突然gcされた場合は無駄になりませんか?これは単なるシングルトンパターンであるため、データがキャッシュに保持されることを保証するものは何もありません。
だから私の質問は-この状況を処理するためにキャッシュを実装するためのベストプラクティスは何ですか?私はこれに対する巨大で複雑なソリューションが本当に好きではなく、System.Webにキャッシュがあることは知っていますが、これは単なるクラスライブラリであるため、それは少し「オフ」のように見えますか?
解決
私の意見では、最良の解決策は次の特徴を持っているでしょう。
-
独自の記述を避けるために、プラットフォームが提供する利用可能なキャッシングサービスを使用します。
-
レイヤーを一貫させるために、クラスライブラリをSystem.Webに結合しません。
-
ただし、クラスライブラリがASP.NETアプリケーション内で実行されている場合、ソリューションは追加の構成とセットアップを必要とする別のキャッシュ実装(たとえば、Enterprise Library Caching Application Block)を必要としません。
したがって、実行中の環境に基づいて、クラスライブラリが異なるキャッシュ実装を使用できるようにするために、IoC戦略を使用します。
抽象キャッシュコントラクトを次のように定義するとします。
public interface ICacheService
{
AddItem(...);
}
System.Webに基づいた実装を提供できます:
public AspNetBasedCacheService : ICacheService
{
AddItem(...)
{
// Implementation that uses the HttpContext.Cache object
}
}
そして、その実装をシングルトンとして「公開」します。元のアプローチとの違いは、シングルトンが完全な「キャッシュオブジェクト」ではなく、ASP.NETキャッシュサービスベースの実装への単なる参照であることに注意してください。
public class ChacheServiceProvider
{
public static IChacheService Instance {get; set;}
}
遅延初期化を実行するか、アプリケーションの起動時に(global.asax.csで)chaching実装を初期化する必要があります
また、すべてのドメインコンポーネントは、System.Webに基づいて実装されていることを知らなくても、公開されたキャッシュサービスを使用できます。
// inside your class library:
IChacheService chache = CacheServiceProvider.Instance;
cache.AddItem(...);
これはおそらく最も単純なソリューションではないことに同意しますが、コードの分離と柔軟性を犠牲にすることなく、ASP.NETキャッシュの実装を活用することを目指しています。
あなたの質問を正しく理解できたと思います。
他のヒント
キャッシュがまだ参照を保持している限り、データはガベージコレクションされません。
また、シングルトンを使用しないでください。