ResourceManager
Die ResourceManager-Klasse bietet zur Laufzeit einen komfortablen Zugriff auf Ressourcen für die entsprechende Kultur. Ein ResourceManager verwaltet mehrere Ressourcen über eine allgemeine Quelle, die einen bestimmten Stammnamen besitzt. Mehrere Klassenkonstruktoren bieten Unterstützung für verschiedene Szenarien, einschließlich Abrufen von Ressourcen aus Assemblies und Ressourcendateien. Eine separate, statische Methode unterstützt den Abruf von Ressourcen aus eigenständigen Ressourcendateien, wie z. B. Bildern. Die Standardimplementierung lädt zunächst alle Ressourcennamen. Anschließend lädt sie die Werte auf Abruf und speichert sie für eine spätere Verwendung. Dadurch wird weniger Arbeitsspeicher benötigt als bei der ResourceSet-Klasse, die weiter hinten in diesem Abschnitt erläutert wird. Dabei wird davon ausgegangen, dass nicht alle Ressourcen geladen werden, das erste Abrufen einer bestimmten Ressource aber längere Zeit in Anspruch nimmt. Außerdem unterstützt die ResourceManager-Standardimplementierung eine Objektserialisierung. Schließlich suchen ResourceManager-Objekte nach regionsunabhängigen und neutralen Kulturen, wenn bestimmte lokalisierte Ressourcen nicht zur Verfügung stehen.
Sie haben sich mit einem ResourceReader bereits einen einfachen Mechanismus zum Auflisten von Ressourcen angesehen. Jetzt verwenden Sie den leistungsstarken ResourceManager, um ungefähr die gleiche Aufgabe auszuführen.
Auflistung 4a. Benannte Ressourcen mit ResourceManager (ResWrite.cs)
...
ResourceManager rm = ResourceManager.
CreateFileBasedResourceManager("sample", ".", null);
Console.WriteLine(rm.GetString("test1"));
Console.WriteLine(rm.GetString("test2"));
Console.WriteLine(rm.GetString("test3"));
Console.WriteLine(rm.GetString("test4"));
Console.WriteLine(rm.GetObject("test5").ToString());
...
Auflistung 4b. Benannte Ressourcen mit ResourceManager (ResWrite.vb)
...
Dim rm As ResourceManager = ResourceManager.
CreateFileBasedResourceManager ("sample", ".", Nothing)
Console.WriteLine(rm.GetString("test1"))
Console.WriteLine(rm.GetString("test2"))
Console.WriteLine(rm.GetString("test3"))
Console.WriteLine(rm.GetString("test4"))
Console.WriteLine(rm.GetObject("test5").ToString())
...
Als erstes ist die statische CreateFileBasedResourceManager-Methode zu beachten, die mit drei Argumenten arbeitet: der Datei, der Position und der Angabe, ob ein anderes ResourceSet als der Standardwert verwendet werden soll. (Der Code geht davon aus, dass es sich bei der Position um das Basisverzeichnis AppBase der Anwendung handelt.) Als nächstes lässt sich feststellen, wie leicht sich Zeichenfolgenressourcen mit der GetString-Methode der ResourceManager-Klasse abrufen lassen.
Sie können die GetObject-Methode auch verwenden, um eine Bildressource abzurufen. Beim vorangehenden Beispiel wird der Wert des Ressourcennamens lediglich geschrieben, die beiden folgenden Codezeilen (die aus der Beispieldatei Graphic.cs stammen) zeigen jedoch, wie diese Methode zum Abrufen und Anzeigen einer Grafik verwendet werden kann:
rm = new ResourceManager("Images", this.GetType().Assembly);
pictureBox1.Image = (System.Drawing.Image)rm.GetObject("flag");
Das Visual Basic-Äquivalent der Beispieldatei Graphic.vb sieht wie folgt aus:
rm = New ResourceManager("Images", Me.GetType().Assembly)
pictureBox1.Image = CType(rm.GetObject("flag"), System.Drawing.Image)
Die beiden vorhergehenden Anweisungen laden das Objekt namens flag aus der Ressourcendatei Images, wandeln es in den Typ Image um und weisen das Ergebnis der Image-Eigenschaft des Bildfeldes zu. Was tatsächlich geladen wird, hängt selbstverständlich von der verwendeten Kultur ab. Wie hier gezeigt, werden die Ressourcen bei neutralen Kulturressourcen entsprechend den Angaben der Compileroption verwendet:
.../res:Images.resources,Images.resources...
In diesem speziellen Fall hat die Compileroption die Datei Un.jpg eingebettet. Für andere Kulturen wurde die Bitmap während des Erstellungsprozesses in die entsprechende Satellitenassembly eingebettet.
Der ResourceManager arbeitet mit serialisierten Daten, d. h. mit den Klassen, die mit dem Serializable-Attribut gekennzeichnet sind und die ISerializable-Schnittstelle unterstützen. Die integrierten Typen enthalten den Typ Image (und die von Bitmap, Icon, Cursor und Metafile abgeleiteten Typen) sowie die Zeichenfolgentypen. Beachten Sie, dass die ResourceManager-Zeichenfolgenparameter zwischen Groß- und Kleinschreibung unterscheiden. Dies bedeutet, dass bei den Namen von Ressourcendateien und bei den Ressourcenschlüsseln ebenfalls zwischen Groß- und Kleinschreibung unterschieden wird.
Dateien können in Unterverzeichnissen oder RESOURCES-Dateien gespeichert oder in Assemblies verpackt sein. Um eine Ressource in einer Assembly zu suchen, nimmt ResourceManager den Namen der ausführenden Assembly, hängt .resources und seine eigene Haupt- und Nebenversionsnummer (Hauptversion.Nebenversion) an, fügt das aktuelle Gebietsschema ein, fügt den Hash für den Signaturschlüssel der aktuellen ausführenden Assembly hinzu und weist den Assemblycache an, diese Assembly zu suchen. Die Beschreibung eines nützlichen Tools zum Verfolgen von Anforderungen für Assemblycachebindungen finden Sie in der Dokumentation zum Assembly Binding Log Viewer-Tool (FusLogVW.exe) in Anhang B: Ressourcentools.
**Hinweis **Wenn Sie eigenständige, flexible Ressourcen in einzelnen Dateien implementieren möchten und eine Anwendung auf Webbasis ausführen, können Dateien durch Microsoft Internet-Informationsdienste (IIS) gesperrt werden, so dass Sie die Ressourcendateien nicht aktualisieren können, während die Anwendung ausgeführt wird. Wenn Sie die Ressourcen stattdessen im Unterverzeichnis \bin der Anwendung in Satellitenassemblies stellen, stellt der IIS Shadow-Copy-Mechanismus sicher, dass die neuen Ressourcen automatisch beim Erstellen einer neuen Anwendungsdomäne geladen werden, um nachfolgende Webanforderungen zu bearbeiten.