Question:
Do you know anything about…
…in the SDK that under the Microsoft.SharePoint.Administration namespace that “The new hierarchical object store provides a common framework for third-party applications to manipulate and store administrative data”…
Can we use this to store our own data?
Answer:
Yes! Unfortunately, the documentation is pretty weak in this area. The hierarchical object store is the mechanism by which WSS itself uses to store information about the farm, web applications, features, etc. The great thing is that you, the developer, can also use the store to build and store information.
How does it work?
It's a two step process...
- Create a class which inherits from
Microsoft.SharePoint.Administration.SPPersistedObject
- Use the Administration namespace to add, retrieve, or remove the object from the
store
Let's take a look custom class designed to hold some values...
/// <summary>
/// Class - The Counter class is simple class that is used to store a numeric value
/// </summary>
public class Counter : Microsoft.SharePoint.Administration.SPPersistedObject {
[Microsoft.SharePoint.Administration.Persisted]
public int Number = 99;
/*
// ----------------------------------------------------------------------
// Note: PersistedAttribute cannot be use with properties. Boo! V4? Please?
// ----------------------------------------------------------------------
public int Number {
get {
return number;
}
set {
number = value;
}
}
*/
// ----------------------------------------------------------------------
// Note: A default public constructor is necessary for serialization.
// If not provided, WSS will not be able to utilize this class.
// ----------------------------------------------------------------------
public Counter () {
} // End of Counter constructor
// ----------------------------------------------------------------------
// Parameterized constructor is called by WSS runtime to initialize the class
// ----------------------------------------------------------------------
public Counter (string name, SPPersistedObject parent, Guid guid) : base (name,parent, guid) {
} // End of Counter constructor
} // End of Counter class
Now interact with the class...
// Designate a Guid value that uniquely represents my Counter object...
Guid storeGuid = new Guid ("{3C5C252B-6D11-4bc5-8DE6-E9D292D49BB5}");
// Designate which server will be utilized...
SPServer server = new SPServer ("westgate");
// Create a Counter object that is a child of the server farm...
// ----------------------------------------------------------------------
// Notes:
// 1 - the object can be parented against any other SPPersistedObject, in this
example the object is child of the farm
// 2 - the object must have a unique, non-changing Guid that identifies the object
within the entire scope of WSS
// ----------------------------------------------------------------------
Counter counter = new Counter ("My Counter", server.Farm, storeGuid);
// Update the field to a non-default value of 99...
counter.Number = 10000;
// Saves the object and push it out to all servers...
counter.Update();
// Now use a new object to prove the value was stored on the server...
Counter echo = (Counter) server.Farm.GetObject (storeGuid);
// Verify the object was stored with a non-default value...
System.Diagnostics.Debug.WriteLine ("This counter value should be 10,000: " + (echo.Number == 10000));
// Now delete the object...
echo.Delete ();
// And perform cleanup...
echo.Unprovision ();
There are few points worth mentioning...
- The PersistedAttriubute
class can only be used on fields. It would be nice to use
properties instead of fields but right now we're limited to fields...
- Two constructors are required in the SPPersistedObject-derivative
class. A public, default constructor and the parameterized form.
As you can imagine, there are a lot of possibilities with the hierarchical
store. Your objects can be parented against the farm, web application,
custom classes, etc.
Happy coding,
-Maurice