In Part 5 of this series, we created a PowerShell cmdlet to enable SharePoint administrators to script deployment of our Calculator service application in a server farm.
In this article, we’ll create a custom setting that administrators can use to modify the behavior of our service application.
Specifically, we’ll create a new Precision setting, which is defined as the number of significant digits that are used to represent the result of a calculation.
To do this, we’ll first add the setting to our CalculatorServiceApplication class.
You might think that it would be challenging to create a setting that can be managed from a single location and made available to all servers in a server farm via a distributed multi-tier cache, but that’s actually the easiest part thanks to the SharePoint configuration object model:
The precision field (line 4) represents the current precision setting for the service application, and the Precision property (lines 6-22) implement a public property to get and set the field value.
The key to integrating with the SharePoint configuration object model is the [Persisted] attribute (line 3). This attribute instructs SharePoint to persist the field value in the SharePoint configuration database when the Update method is called, and to deserialize it when the class is read from the configuration database.
That’s all it takes for the field value to be available on all machines in the server farm and automatically cached on demand for runtime access!
NOTE: The Service Application Framework does not require service application settings to be stored in the SharePoint configuration database using the [Persisted] attribute described above. For example, if a service has an existing mechanism for storing settings, then that would be fine to use instead. However, you may find this persistence mechanism convenient in many cases.
Next, we’ll read this value at runtime and apply it to the result of our Add method:
First, we add a ServiceApplication property to look up and return the executing Calculator service application (lines 8-15).
NOTE: If we had implemented our contract as methods on the CalculatorServiceApplication, this step would be unnecessary, i.e., we could just use “this” to reference the current service application. However, in this example we’re assuming that we’re integrating an existing WCF service contract implementation with SharePoint.
Then, we get the precision setting from our service application using this.ServiceApplication.Precision (line 20) and use it to round our result (line 23).
NOTE: I couldn’t find a nice math function to round a number to an arbitrary precision, so I ended up converting the int to a string formatted to display the given precision and then converting the formatted string back to an int. Not something I’d recommend for production code.
It is important to note that the ServiceApplication lookup (line 13) and the Precision setting (line 2) objects are cached in memory by the SharePoint configuration object model and should not be cached again. This is a common implementation mistake and results in stale setting values. The reason is that SharePoint is smart about invalidating the cache and keeping it fresh when administrators make changes to settings, even from other machines in the server farm. If you cache the result of a lookup, the object will become stale and your application won’t see changes made by administrators until your service host process is recycled.
So, simply follow the pattern above and lookup the setting on every access to ensure that you are reading the most recent value.
Now let’s provide a way for the administrator to configure the setting. To do this, we’ll integrate with the “Manage” ribbon button on the Service Applications management page:
First, we’ll create a management ASPX page:
NOTE: I removed a bunch of standard page template goo for readability.
Then, the code-behind:
The interesting bit of code here is the ServiceApplication property (lines 24-32). Here we’re assuming that the URL used to navigate to the aspx page will include a querystring parameter named “id” with a value that matches the Guid identifier of the service application to be managed. This is necessary because, if you remember our discussion on service application topologies, there may be more than one of our Calculator service applications in a server farm. We parse the Guid parameter and use it to look up the specified service application using the configuration object model (line 30).
And finally, we’ll hook our new management page up to the ribbon by overriding the ManageLink property of our service application:
Note that we include the “id” querystring parameter in the URL required by our management page (line 7).
We’ve added a configurable setting and a page to manage it:
Administrators can create multiple service applications and configure each of them with a different setting.
However, we don’t have a way for administrators to script this new setting using PowerShell. We’ll take care of that next time.