Demonstration Scenario of Service Applications Share Point 2010

Understanding the Service Application Framework, in terms of its function and architecture, is relatively straightforward. However, taking this information and making use of it in a real world situation is a bit more involved. Conceptually, the purpose of the Service Application Framework is to make scalable, enterprise-ready services easy to maintain and consume. Although the architecture lays out how this will be done, at a nuts-and-bolts level, implementing this in a practical way introduces a fair amount of complexity. So that you can properly understand the workings of the framework and make use of it when creating your own service applications, let’s create a basic translation service. The service will be configured using the Manage Service Applications section of Central Administration and will be capable of being used by custom web parts within a site.

Prerequisite: Generating a New AppId
Our scenario makes use of the Microsoft Translation service that’s accessed via Bing.com. To make use of the Bing.com web service API, we first need to generate a unique AppId that can be used within our code.

Creating a New SharePoint Project
So that we can easily deploy our custom service to our SharePoint farm, we’ll make use of the deployment capabilities of Visual Studio 2010.

  1. In Visual Studio, choose File | New | Project. Select Empty SharePoint Project, and then type TranslatorDemo as the project name.
  2. In the SharePoint Customization Wizard dialog, enter the URL of the Central Administration site as the local site to be used for debugging.
  3. Select the Deploy As Farm Solution option, and then click Finish to complete the wizard.

Adding Server-side Configuration Classes
With our empty project up and running, our next step is to add server-side configuration classes for our custom service. Earlier I discussed these classes as being derived from SPService, SPServiceInstance, and SPServiceApplication. Since our service application will be deployed as a WCF service, we’ll make use of the inherited classes: SPIisWebService, SPIisWebServiceInstance, and SPIisWebServiceApplication. These classes provide WCF specific functionality, as you’ll see later

  1. Add a new folder named Server to the project. Within the Server folder, create a new class named Translation Service.cs. Add the following code:

    A few things are worth mentioning in this code snippet. First, notice the use of the Guid attribute and the default public constructor. Many of the classes that are used for storing and managing configuration data within the SharePoint platform are derived from SPPersistedObject. SPPersistedObject makes use of serialization to persist the object to the SharePoint configuration database and therefore requires a unique Guid for each type and a default constructor. Also notice that the TranslationService implements a singleton pattern. Each service is defined only once per farm, so using a singleton makes sense because the object will be retrieved from the farm’s services collection.

  2. Within the Server folder, add a new class named Translation Service Application.cs. Add the following code:

    In this code snippet, notice the overridden InstallPath and VirtualPath properties. As mentioned, our service will make use of WCF as a communications protocol. These properties must be overridden to provision correctly the WCF service that supports our custom service.

  3. Within the Server folder, add a new class named Translation Service Instance.cs. Add the following code:

    We now have the basics of our server-side configuration object model. Translation Service represents our service at the farm level, Translation Service Application represents a configured instance of our service at the farm level, and TranslationServiceInstance represents an instance of our service running on a particular server within the farm.

Adding Client-side Configuration Classes

Now that we have the basis of our server-side configuration object model, our next logical step is to add in our client objects.

NOTEFor the purposes of this demonstration, we’ll add both client and server within the same SharePoint project. If the server and client were designed to run on separate farms, a more appropriate deployment strategy might be to create two separate projects, allowing client and server binaries to be installed independently.

  1. Add a new folder named Client to the project. Within the Client folder, create a new class named Translation Service Application Proxy.cs. Add the following code:
  2. Add another class to the Client folder named Translation Service Proxy.cs. Add the following code:

Adding Windows Communication Foundation Components
With our client- and server-side components up and running, we can move on to look at how to deploy a WCF endpoint that can be used to communicate between client and server.

  1. Generally speaking, WCF endpoints should be installed within the %SPRoot% WebServices folder. (See Chapter 2 for details on configuring the %SPRoot% variable.) So that we can have our Visual Studio project automatically deploy to the WebServices folder, we first need to add a SharePoint Mapped folder. Choose Project | Add Share Point Mapped Folder. Then select Web Services from the dialog.
  2. In the WebServices mapped folder that’s been added to the Visual Studio project, create a new folder named TranslatorDemo. This new folder will ensure that our deployed files don’t conflict with files already installed on the server.
  3. Right-click the new Translator Demo folder and choose Add | New Item. Select WCF Service from the Visual C# category, as shown. Name the new service TranslatorService.cs.

    Adding Windows Communication Foundation Components

  4. Delete the app.config file that’s automatically added to the project, and then create a new web.config file in the TranslatorDemo folder. Add the following XML to the web.config file:

At the time of writing, Visual Studio RC doesn’t automatically create a .svc file. This may be resolved in the final version of the product. If not, you’ll need to create a text file named TranslatorService.svc manually and add the following code:

  1. We’re using token replacement to insert the details of our assembly automatically into the WCF service file when the project is built. At the time of writing, token replacement in SharePoint projects doesn’t replace tokens in files with an .svc extension. To remedy this, we can manually modify the project file. Open the project file TranslatorDemo.cspoj using Notepad. Before the closing Project tag at the end of the file, add the following XML element:
  2. From our .svc file, we can see that our WCF service makes use of a ServiceHostFactory class. In the WebServices folder, add a new class named Application Host Factory .cs. Add the following code:
  3. As well as a host factory, we also need to add a host class. Create a new class file named Application Host.cs in the Translator Demo folder. Add the following code:

Implementing Translation Functionality
Now that we have set up most of the plumbing for our service, we can do a bit of work to implement our translation functionality. For the purposes of this demonstration, our service will simply accept an input string in English and will make use of Microsoft Translator to convert the text to French before returning the converted string to the caller.

  1. We need to modify the contract for our WCF server to accept the correct parameters. In the ITranslatorService.cs class, change the source code like so:
  2. With the contract changed, we can now update the implementation. Update the code in TranslatorService.cs as follows:
  3. Before we can add an implementation, we need a service reference to the Microsoft Translator service. Choose Project | Add Service Reference. In the Address box, and then click Go. Type the Namespace Microsoft.Translator, and then click OK to create the reference:

    Adding Windows Communication Foundation Components

  4. With the reference in place, update the implementation as shown next. Note the apiKey variable, which should contain a valid Bing API key discussed in the section “Prerequisite: Generating a New AppId.”

NOTESince we’ve adopted the namespace Microsoft.Translator for our service reference, it may be necessary to add using Microsoft.Translator to the code file. Visual Studio can do this automatically if you press SHIFT-ALT-F10 when the cursor is on a reference to the Microsoft.Translator object.

Installing Service Application Components
Service Application components can be installed in several different ways. The simplest method is to create a feature that will programmatically install the server and cient components for the application when activated.

  1. In the Solution Explorer pane, right-click the Features node and select Add Feature. Set the scope of the feature to Farm and type the title Demo Translation Service, as shown here:

    Installing Service Application Components

  2. So that we can add custom code that will execute when the feature is activated, right-click the Feature1 node and select Add Event Receiver.Uncomment the FeatureActivated override and add the following code:
  3. Although it’s not strictly necessary, we’ll also add some code to clean up our service application when the feature is deactivated. When developing services, having clean-up code is a good idea because it removes orphaned configuration information from the SharePoint configuration database that would be difficult to clean up otherwise. Uncomment the FeatureDeactivating override and add the following code:

    Our project is now in a state where it can be built and deployed to SharePoint. To create and deploy the package, choose Build | Deploy TranslatorDemo. If all is well, the package will be built and deployed to the farm. You can confirm that the package has deployed successfully by opening Central Administration and then selecting Manage Farm Features from the System Settings section. Our Demo Translation Service feature will appear in the list and should be activated.

Provisioning Service Application Instances
You’ve seen how to install both client and server components for our service. Before we can actually use the service, however, we need to provision a new instance of our service. As discussed earlier in the chapter, this instance will be represented by an object of type SPService Application—in our case, this will be the server-side Translation Service Applicationobject.

To configure our TranslationServiceApplication, we need details of the application pool under which the service will run. In this section, we’ll work through the steps necessary to create a user interface that will allow us to capture this information and make use of it to provision the application.
As you saw earlier, service applications are usually provisioned by clicking the New button on the Manage Service Applications page. Integration with the functionality available on the Manage Service Applications page is done by implementing the IServiceAdministration interface on the service class.

  1. Open the TranslationService.cs file and amend the class definition to implement the IServiceAdministration interface, as this code snippet shows:
    [System.Runtime.InteropServices.Guid("C9DD4A67-47FB-11D2-83E7-00C04F9902C1")] public sealed class TranslationService : SPIisWebService, IServiceAdministration
  2. Add the following additional code to the TranslationService.cs file to implement the methods required by the IServiceAdminstration interface:

Adding a Create Application Dialog
Although we’ve added the code required to provision a service application, we still need to capture parameters required for the configuration of the application. So that we can present a user interface for this, we can override the Get Create ApplicationLink method of the base SPService class, allowing us to return a custom URL to which users will be directed when creating an instance of our service.

  1. Add the following method to the TranslationService.cs class:
  2. So that we can create a page that will be automatically deployed to the %SPRoot% Template/Admin folder, we need to add another SharePoint-mapped folder to our project. Choose Project | Add SharePoint Mapped Folder, and then select Template/Admin from the dialog.
  3. In the Admin folder, add a new folder named TranslatorDemo.
  4. In the TranslatorDemo folder, add a new Application Page named CreateService. aspx, as shown:

    Adding a Create Application Dialog

    CAUTIONApplication Pages are automatically added to the Layouts folder. After the Admin/ TranslatorDemo folder has been created, drag the page into the folder. Because we want our CreateService page to appear as a dialog rather than a standard page, we need to make a few changes to the generated HTML, since dialog pages use a different master page and therefore have different placeholders.

  5. Edit the Page tag by deleting the Dynamic Master PageFile attribute and replacing it with this:
    MasterPageFile="~/_layouts/dialog.master"
  6. Delete the auto-generated content tags and replace them with this:

We can now deploy our project to see the effects of our changes. If we navigate to the Manage Service Applications page in Central Administration, we’ll be able to select Translation Service Application from the New button drop-down in the Service Applications tab. Our new CreateService page will be shown in a dialog ready to receive user input.

Capturing Application Pool Details
The SharePoint platform provides a number of user controls that can be used for capturing user input. If you use these controls rather than building input forms from scratch, it’s much easier to maintain a uniform user experience throughout the application. For our CreateService page, we’ll use three such user controls.

Directly following the Page element in the CreateService.aspx page, add the following tags:

Replace the Hello World text that we added to the Content3 content control with the following code:

With our controls in place, we can move on to work on the code-behind. In the CreateService.aspx.cs file, add the following code:

You should notice a few things in this code snippet. First, the use of SPLongOperation in CreateNewServiceApp. When lengthy operations are performed on page post backs, wrapping the code to be executed with a SPLongOperation object provides the user with an “In Progress” display and prevents timeouts from occurring. Using this approach is considered good practice for all configuration changes. The second thing to notice is the provisioning of the WCF service endpoint in the CreateServiceApplication method. The SPIisWebServiceApplication base class defines the AddServiceEndpoint method, which can be used to store endpoint configuration at the application level. When service instances are created, the endpoint configuration is replicated to each instance automatically.

Provisioning Service Instances
Although we now have enough code to capture the parameters required for our application and provision both the application and an appropriate proxy, we still need to do some work to ensure that service instances are created for our application. We can do this by overriding the Provision and Unprovision methods in our TranslationServiceApplication class.

  1. In the Translation Service Application.cs file, add the following code:
  2. NOTEIn this code snippet, we’re provisioning a single service instance for all service applications. In effect, the service instance is used to start and stop the service on individual servers. In some circumstances, it may be appropriate to create a separate service instance for each service application allowing more granular control. By overriding the Provision and Unprovision methods, we can implement service instances in a manner that exactly meets our specific requirements.

  3. We’ve now got everything we need to deploy and configure our custom service application. Choose Build | Deploy TranslatorDemo. As before, we can now create a new Translation Service Application from the Manage Service Application page. Our CreateService page contains the required controls to capture a unique name and an appropriate application pool, as shown:
  4. Provisioning Service Instances

  5. Navigate to the Manage Services On Server page in Central Administration, and notice that a new service named Demo Translation Service has been added, as shown next, allowing us to start and stop the service on a particular server.

Provisioning Service Instances
To see how the service has actually been implemented, use IIS Manager. Choose Start | Administrative Tools | Internet Information Services (IIS) Manager. Expand the SharePoint Web Services site to see a number of applications, which are the various service endpoints used by the Service Application Framework. Click through the list of endpoints, to find one containing our TranslatorService.svc endpoint, as shown here:

Provisioning Service Instances

Using Service Application in Front-end Components
We’ve done most of the work to build and deploy a custom service application. To see the fruits of our labor in action, our next step is to create a simple web part that will make use of our service.

  1. Add a new Visual Web Part to our SharePoint project by choosing Project | Add New Item. Select Visual Web Part from the dialog and name of the web part TranslationWebPart.
  2. A user control file named TranslationWebPartUserControl.ascx will be added to the project automatically. Add the following code to the user control file:
  3. In the code-behind file for the user contol (Translation WebPart UserControl.ascx.cs), addthe following code:

    This code snippet makes use of SPServiceContext to retrieve the default service proxy that matches our translation service. With a reference to a proxy object, the code then calls the Translate method to retrieve the appropriate results.

Calling Service Applications
As the code stands at the moment, an error will be flagged in Visual Studio, because the Translate method does not yet exist on the proxy class. Let’s move on to look at how that can be implemented.
Our TranslationServiceProxy class currently contains a basic implementation of a proxy class. However, it doesn’t contain any custom methods that can be used to invoke the functionality of our custom application. Since we’re using WCF as our communications mechanism, we first need to create a WCF proxy class. We can create this class by creating an instance of the service and then using svcutil.exe to generate the proxy automatically. However, for the purposes of this demo, we can manually create it as follows:In the Client folder, add a new class named TranslationServiceClient.cs. Add the following code:

In the TranslationServiceApplicationProxy.cs file, add the following code:

This code snippet makes use of the SPRoundRobinServiceLoadBalancer. Earlier in this, the workings of the topology service were covered, along with how a proxy service could query the topology service for a list of endpoints for a particular service and then make use of the list to provide load-balancing capabilities. The SPIisWebServiceApplicationProxy class on which our proxy is based requires that this type of functionality be implemented. Although the class exposes a ServiceEndpointUri property, the value returned is not the URI of a particular endpoint, but is the URI for the service application—only by using the topology service can a list of real endpoints be retrieved. The SPRound Robin Service Load Balancer handles this automatically, and as you can see from the code, it will provide an appropriate endpoint address for each operation.
We’re now ready to build and deploy our sample application. As before, choose Build | Deploy TranslatorDemo in Visual Studio. After the project has been deployed, navigate to the Manage Service Applications page in Central Administration and create a new instance of the Translation Service Application. With the service up and running, we can add our custom web part to a page and check that things are working as expected.

NOTEBecause we set up our project to target the Central Administration site for debugging, the web part will not be installed on other site collections. In a real-world situation, our web part would be created in a separate project and deployed to front-end servers. If all is well, our web part will be displayed and will translate text as shown:

Calling Service Applications

Managing Service Applications

So far, we’ve created, installed, and provisioned service applications. One important area that hasn’t been covered is how to manage existing applications. In this section, we’ll look at how we can add a management page for our translation service and how we can pick up properties gathered from our management page and make use of them in the implementation of our service. In much the same way that we added our CreateService page earlier, adding a management page is also a case of overriding a method. This time it’s the ManageLink method on the SPServiceApplication class.

TIP You SPService Application roxy class.

  1. In the TranslationServiceApplication.cs class, add the following code:
  2. Add a new Application Page to the Admin / TranslatorDemofolder.Name the page ManageService.aspx.
  3. This time, we’ll use the default master page rather than showing the page as a popup dialog. Add the following code to the page:
  4. Add the following code to the code-behind
  5. file (ManageService.aspx.cs):

We’ve now implemented our ManageService page. By deploying the application and creating a new instance of the Translation Service Application, we can see that our application name now appears as a hyperlink in the Manage Service Application page in Central Administration and the Manage button is enabled in the ribbon when our application is selected. By navigating to the Manage Translation Service page, we have the option to configure an alternative language, as shown here:

Managing Service Applications

Reading Service Application Properties

Although we’ve implemented a user interface to capture properties for our custom application, our service implementation needs to be modified to make use of these properties. In the TranslatorService.cs file, update the Translate method as follows: public string Translate(string input)

With this final code cange in place, we can deploy our application and confirm that everything works as expected. By changing the alternative language value in our ManageService page, we can control which language is used for translations for all users of our service.


All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

Share Point 2010 Topics