Using a Database

Using a database to hold resources is a key feature of the Resource Application Block and turns resource management into an enterprise feature. The Resource Application Block, however, is a provider model for getting at resources from various different resource storage types and is thus not really responsible for getting the resources there in the first place. Having said that the provider model would not be complete unless there was some form of support for editing those resources. For this reason every resource provider type has been coded with an associated IResourceWriter to support resource editing of the resource storage type.

Using the Data Resource Provider requires a little more effort to setup than any of the other provider types.

Creating a Resource Database

Provided with the source code is a SQL script to create a Resource database (CreateResourceDatabase.sql) and a console command to run the script (CreateResourceDb.cmd). The command and script assume that Microsoft SQL Server is the database type and the script must be run on the machine that has SQL Server installed. The syntax of the console command is:

[Command Console]
C:\>CreateResourceDb.cmd {SQL instance name e.g. SQLEXPRESS}

Note: the parameter applied to the command, this represents the instance name of the installation of SQL Server that you want to use. If you are using the default instance then leave this parameter blank. if you are using Sql Express from a default install then you will need to use SQLEXPRESS.

The authentication model that you wish to use is left up to you. Now you need to configure the database using the Data Access Application Block. This block is added automatically in the Configuration Console as soon as you select the DataResourceProvider. Configure an appropriate ConnectionString to get at the database. See Configuration for more detail.

Adding and Editing Resources in the Database

This is done using the DataResourceWriter which implements the standard .NET Framework IResourceWriter interface. This means that it will work with any open source or commercially available resource editor. The Resource Application Block itself does not provide a resource editor of its own and I have a mind to provide one in a later release, or more probably, write an API to use the one that Guy Smith-Ferrier has provided with his book .NET Internationalization.

If you wish to use the resource writer in your code then the following code sample might help:

[C#]
// use the Data Access Application Block to create your database instance using the configured connection string, "ResourceDatabase" in this example
Database 	database = DatabaseFactory.CreateDatabase("ResourceDatabase");

// create a DataResourceWriter to use to write resources to this database, notice we are using the invariant (or neutral) culture
// and grouping the set of resources together with the base name of "MyResources"
DataResourceWriter dataResourceWriter = new DataResourceWriter(database, "MyResources", CultureInfo.InvariantCulture);

// the following code lines show how a variety of resource data types can be written to the database
// adding a string
dataResourceWriter.AddResource("TestString", "This is a string");
// adding an integer
int testInt = 27;
dataResourceWriter.AddResource("TestInteger", testInt);
// adding an icon
Icon testIcon = new Icon("C:\testicon.ico");
dataResourceWriter.AddResource("TestIcon", testIcon);
// adding an image
Bitmap testImage = new Bitmap("C:\testImage.bmp");
dataResourceWriter.AddResource("TestImage", testImage);
// adding an audio resource (or any BLOB for that matter)
FileInfo fi = new FileInfo("C:\audio.wav");
FileStream fs = fi.Open(FileMode.Open);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int)fs.Length);
dataResourceWriter.AddResource("TestSound", buffer);
// adding a Color object
dataResourceWriter.AddResource("TestColour", Color.Red);
// adding a Comment with a resource
ResourceDataNode resourceDataNode1 = new ResourceDataNode("TestString2", "This is a string value");
resourceDataNode1.Comment = "This is a comment to go with the resource TestString2";
dataResourceWriter.AddResource(resourceDataNode1.Name, resourceDataNode1);
// adding a file reference resource, this is a reference to a file rather than the file itself
ResourceFileRef resourceFileRef = new ResourceFileRef("test.bmp", typeof(Bitmap).AssemblyQualifiedName);
ResourceDataNode resourceDataNode2 = new ResourceDataNode("TestFileRef", resourceFileRef);
dataResourceWriter.AddResource(resourceDataNode2.Name, resourceDataNode2);
dataResourceWriter.Close();

// adding generic french resources
dataResourceWriter = new DataResourceWriter(database, "MyResources", new CultureInfo("fr"));
dataResourceWriter.AddResource("TestString", "Bonjour tout le monde");
dataResourceWriter.AddResource("TestInteger", 33);
dataResourceWriter.Close();

Getting at Database Resources

This is very easy and is nothing special at all, simply use the DataResourceProvider in the same fashion as you would for any other resource provider type.

Note: the base name is used to segregate resources into sets so that you don't need to read all the resources from the database each time.

Using Other Database Types

The Enterprise Library, in collusion with Enterprise Library Contrib now supports 8 different database types through the Data Access Application Block, however there are a few caveats to what you can configure from the Data Access Application Block.
  • the DataResourceProvider uses stored procedures so your database type must be able to support stored procedures or equivalent, currently however; it is only SQLite that does not have any equivalent to Store Procedures.
  • the table uses an auto-incrementing identifier for its primary key so your database must support an auto-increment feature, However, the ID column is not actually used so it is possible to simply remove the ID column altogether.
  • resource values are stored as Binary Large Objects in a VARBINARY data type, or any type that can hold a binary serialized byte array. If your database type cannot support BLOB's then it cannot be used.

Don't forget if any of the caveats affects your choice you have the source code for the supplied DataResourceProvider so that you could always write your own, then use the CustomResourceProvider to configure it.

The Resource Table

The Resource table has the following columns:

[SQL]
CREATE TABLE [dbo].[Resources](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[BaseName] [nvarchar](200) NOT NULL,
	[Culture] [varchar](10) NOT NULL,
	[Name] [nvarchar](200) NOT NULL,
	[Type] [varchar](200) NULL,
	[MimeType] [varchar](200) NULL,
	[Value] [varbinary(MAX)] NULL,
	[Comment] [nnvarchar](MAX) NULL,
    CONSTRAINT [PK_Resources] PRIMARY KEY NONCLUSTERED ([ID] ASC)
    WITH (
                     PAD_INDEX  = OFF, 
                     STATISTICS_NORECOMPUTE  = OFF, 
                     IGNORE_DUP_KEY = OFF, 
                     ALLOW_ROW_LOCKS  = ON, 
                     ALLOW_PAGE_LOCKS  = ON
                ) ON [PRIMARY]
) ON [PRIMARY]

Last edited Dec 17, 2009 at 4:11 PM by ewdev, version 3

Comments

No comments yet.