For my presentation at TechEd Barcelona I've created a custom ResourceReader to read localized values from a database instead of using resource files or satellite assemblies. This can be done very easily. All the code can be found on my web site:
1. Create a DBResourceReader class that implements the interface IResourceReader. The important method with this interface is GetEnumerator() that returns an IDictionaryEnumerator that can be used to enumerate the resources of one language. With this method I've read data from the database, stored it inside a Hashtable, and returned the enumerator of this hashtable.
2. Create a DBResourceSet class that derives from ResourceSet. All that's needed is passing a DBResourceReader to the constructor of the base class ResourceSet.
3. Create a DBResourceManager class that derives from ResourceManager. In this class I'm using the ResourceSets property of the base class to store DBResourceSets of multiple cultures. The method InternalGetResourceSet() must be overridden, so that DBResourceSets are returned. This method is called by the base class ResourceManager when resources are read. Instead of reading resources from the database every time, ResourceSets are put into a Hashtable.