2008-10-01 10 views
8

Ich implementiere einen Cache in einer Klassenbibliothek, die ich in einer asp.net-Anwendung verwende.Cache in einer Klassenbibliothek für die Verwendung in einer asp.net-Anwendung ordnungsgemäß implementieren

Ich habe mein Cache-Objekt als Singleton-Muster mit einer statischen Methode erstellt, um den Cache zu aktualisieren, der wirklich nur eine Elementvariable/-Eigenschaft mit einer Sammlung von Daten lädt, die ich im Cache speichern muss. Habe ich es eine schöne Art und Weise war zu gehen, da ich nur durch meine Daten zugreifen kann

MyCacheObject.Instance.MyDataCollection 

Aufruf Ich bin ein neues Cache-Objekt erstellt eine ziemlich große Menge an Daten, die von einem gewissen Schlüssel aufgeteilt zu speichern. Was ich sage ist, dass ich einen neuen Cache erstelle, aber dieser lädt nicht alle Daten auf einmal, sondern speichert eine Sammlung für jeden Schlüssel, auf den zugegriffen wird.

MyOtherCacheObject.Instance.MyOtherDataCollection(indexkey) 

Diesmal wurde die Frage nach Garbage Collection aufgeworfen. Da ich eine riesige Menge an Daten speichere, wäre es keine Verschwendung, wenn es plötzlich gc'te? Da es nur ein Singleton-Muster ist, gibt es nichts, was sicherstellt, dass Daten im Cache verbleiben.

Also meine Frage ist - Was ist Best Practice für die Implementierung eines Cache, um diese Situation zu behandeln? Ich mag wirklich keine große komplexe Lösung, und ich weiß, dass es in System.Web Caching gibt, aber das scheint ein bisschen "aus", da dies nur eine Klassenbibliothek ist, oder was denkst du?

Antwort

9

Meiner Meinung nach, wäre die beste Lösung, die die folgenden Eigenschaften hat:

  • Verwendet den zur Verfügung von der Plattform zur Verfügung gestellt Caching-Service versuchen, Ihre eigenen zu vermeiden, zu schreiben.

  • Koppelt Ihre Klassenbibliothek nicht mit System.Web, damit die Ebenen kohärent sind.

  • Wenn die Klassenbibliothek jedoch in einer ASP.NET-Anwendung ausgeführt wird, sollte für die Lösung keine weitere Caching-Implementierung erforderlich sein (z. B. Caching Application Block der Enterprise Library), die zusätzliche Konfiguration und Einrichtung erfordert.

Also, ich würde eine IoC Strategie verwenden, um die Klassenbibliothek zu ermöglichen, verschiedene Caching-Implementierungen zu verwenden, bezogen auf die Umwelt, auf dem es läuft.

Angenommen, Sie Ihren Abstract Caching Vertrag definieren als:

public interface ICacheService 
{ 
    AddItem(...); 
} 

Sie eine Implementierung auf System.Web Basis bieten könnten:

public AspNetBasedCacheService : ICacheService 
{ 
    AddItem(...) 
    { 
     // Implementation that uses the HttpContext.Cache object 
    } 
} 

Und dann, dass die Umsetzung hat 'veröffentlicht' als Singleton. Beachten Sie, dass der Unterschied zu Ihrem ursprünglichen Ansatz darin besteht, dass der Singleton nur ein Verweis auf die ASP.NET-Cache-Dienst-basierte Implementierung ist, anstatt auf das vollständige "Cache-Objekt".

public class ChacheServiceProvider 
{ 
    public static IChacheService Instance {get; set;} 

} 

würden Sie haben die chaching Implementierung initialisieren entweder durch verzögerte Initialisierung durchgeführt wird, oder beim Start der Anwendung (in global.asax.cs)

Und jeder Domänenkomponente der Lage wäre, die veröffentlichte Caching-Dienst zu verwenden ohne zu wissen, dass es basierend auf System.Web implementiert ist.

// inside your class library: 
IChacheService chache = CacheServiceProvider.Instance; 
cache.AddItem(...); 

Ich bin damit einverstanden, dass es wahrscheinlich nicht die einfachste Lösung ist, aber ich bin mit dem Ziel Vorteile der ASP.NET Cache-Implementierung für die Aufnahme ohne Code zu opfern Entkopplung und Flexibilität.

Ich hoffe, ich habe Ihre Frage richtig verstanden.

+0

Ich mag was du bekommst (obwohl ich einen langen Weg gehen würde, um IoC zu vermeiden). Sie bringen einige gute Ideen auf, mit denen ich jedoch laufen kann. Danke –

+0

Sie könnten auch eine Unterstützungsvariable hinzufügen und eine Sperre für diese Variable ausführen, wenn der Satz ausgeführt wird. Mein Bauchgefühl sagt, dass es einige Threading-Probleme verhindern könnte. –

1

Die Daten werden nicht gesammelt, solange der Cache noch einen Verweis darauf enthält.

Verwenden Sie auch niemals Singletons.

+0

aber ich fürchte, das Cacheobject würde gc'ed nicht die Daten, die es zwischenspeichert. –

+1

anstatt einen Singleton zu verwenden, um meinen Cache zu halten, was wäre ein besserer Ansatz? –

+0

Warum sollte das Cache-Objekt Müll gesammelt werden? Solange es einen Hinweis darauf gibt, kann dies nicht passieren. –