ResourceManager

La classe ResourceManager consente di accedere agevolmente a risorse appropriate alla lingua in fase di esecuzione. Una ResourceManager gestisce più risorse da una fonte comune che presenta un determinato nome di radice. Più costruttori di classi forniscono il supporto per diversi scenari, incluso il recupero di risorse da assembly e file di risorse. Un metodo statico distinto supporta il recupero di risorse da file di risorse autonomi, quali le immagini. L'implementazione predefinita carica tutti i nomi delle risorse, quindi carica i valori su richiesta, memorizzandoli per un uso successivo. Questo metodo consente di utilizzare meno memoria rispetto alla classe ResourceSet, descritta più avanti in questa sezione, presupponendo che non tutte le risorse siano caricate. Tuttavia il recupero iniziale di una risorsa specifica potrebbe richiedere più tempo. Inoltre l'implementazione ResourceManager predefinita supporta la serializzazione degli oggetti. Infine gli oggetti ResourceManager consentono la ricerca delle risorse di fallback per lingue non associate ad alcun paese e indipendenti dall'area geografica quando non sono fornite risorse localizzate.

Un metodo semplice per l'enumerazione delle risorse, già esaminato in precedenza, è l'utilizzo di una ResourceReader. Verrà ora utilizzato la potente ResourceManager per eseguire più o meno la stessa operazione.

Listato 4a. Risorse con nome con 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());
...

Listato 4b. Risorse con nome con 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())
...

La prima cosa da notare è il metodo statico CreateFileBasedResourceManager che accetta tre argomenti: il file, il percorso e la necessità o meno di utilizzare un ResourceSet non predefinito. Nel codice si presuppone che il percorso sia la directory di base dell'applicazione, denominata AppBase. La seconda cosa da notare è la facilità con cui si recuperano le risorse di tipo stringa mediante il metodo GetString della classe ResourceManager.

È possibile utilizzare anche il metodo GetObject per recuperare una risorsa immagine. Nell'esempio precedente viene semplicemente scritto il valore del nome della risorsa, ma nelle due righe di codice che seguono, tratte dal file di esempio Graphic.cs, viene illustrato come utilizzare questo metodo per recuperare e visualizzare un'immagine grafica.

rm = new ResourceManager("Images", this.GetType().Assembly);
pictureBox1.Image = (System.Drawing.Image)rm.GetObject("flag");

Di seguito viene riportato l'equivalente Visual Basic dal file di esempio Graphic.vb:

rm = New ResourceManager("Images", Me.GetType().Assembly)
pictureBox1.Image = CType(rm.GetObject("flag"), System.Drawing.Image)

Nelle due istruzioni precedenti l'oggetto denominato flag viene caricato dal file di risorse Images, viene convertito in un tipo Image e il risultato viene assegnato alla proprietà Image della casella di immagine. L'effettivo caricamento naturalmente dipende dalla lingua utilizzata. Le risorse di una lingua non associata ad alcun paese provengono da quanto è stato specificato dall'opzione del compilatore, illustrata di seguito.

.../res:Images.resources,Images.resources...

In questo specifico caso, l'opzione del compilatore ha incorporato il file Un.jpg. Per le altre lingue, la bitmap è stata incorporata nell'assembly satellite corrispondente durante il processo di generazione.

ResourceManager funziona con tutti i dati serializzabili, vale a dire con le classi contrassegnate con l'attributo Serializable e che supportano l'interfaccia ISerializable. I tipi incorporati includono il tipo Image (e i tipi derivati Bitmap, Icon, Cursor e Metafile) e i tipi stringa. Poiché i parametri della stringa ResourceManager tengono conto della distinzione tra maiuscole e minuscole, lo stesso vale per tutti i nomi dei file di risorse e le chiavi delle risorse.

I file possono trovarsi in sottodirectory o file RESOURCES oppure possono essere incorporati negli assembly. Per trovare una risorsa in un assembly, ResourceManager accetta il nome dell'assembly in esecuzione, accoda ".resources" e il proprio numero di versione, Major.Minor, aggiunge l'impostazione internazionale corrente, aggiunge l'hash della chiave della firma per l'assembly in esecuzione corrente e indica alla cache dell'assembly di trovare l'assembly. Per informazioni su un'utile strumento per l'analisi delle richieste di associazione assembly/cache, fare riferimento alla documentazione relativa al visualizzatore registro associazione assembly (FusLogVW) nell'Appendice B: strumenti delle risorse.

**Nota   **Se si sceglie di implementare risorse autonome e separate in singoli file e si esegue un'applicazione basata sul Web, è possibile che si verifichi un blocco dei file causato da Microsoft Internet Information Services (IIS), che impedisce di aggiornare i file di risorse mentre l'applicazione è in esecuzione. Se invece si inseriscono le risorse in assembly satellite nella sottodirectory \bin dell'applicazione, il meccanismo di replica di IIS farà in modo che le nuove risorse vengano caricate automaticamente durante la creazione di un nuovo dominio applicazione per gestire le richieste Web successive.