Step by Step SharePoint Service Applications : Part 1

If you missed the intro, check it out for some background on WHY you’d want to create a backend service library for SharePoint 2010. (Read it here!) It really isn’t for everyone—but if you’re creating enterprise scale applications for SharePoint 2010, the service architecture/framework is the right way to scale out your application.

To get stated, create a Class Library called “SuperCool.ServiceLibrary”. This will be the backend service library, and will also contain the proxy classes and client proxy.

At the heart of the service library is the SPIisWebServiceApplication. This class is your application instance, but it is NOT the backend WCF service that you will call. (We’ll cover that later.) This object is persisted in the Config database, and holds references to the WCF endpoints it serves as well as any databases you create. It will also be responsible for provisioning any jobs you define for your application.

The first three methods are what points the application to your backend WCF service (that we haven’t written yet), so you can ignore those for now but you’ve got to include them. The rest is pretty much boilerplate code, it sets up the application plumbing.

using System;
using System.Collections.Generic;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint;

namespace SuperCool.ServiceLibrary
{           
    /// <summary>
    /// The conceptual service application. 
    /// </summary>
    // This magic GUID is used to define the service application and match it with supported proxies
    [System.Runtime.InteropServices.Guid("ACE7BB07-1891-46e0-A7DD-0B23CD7ED90D")]
    [IisWebServiceApplicationBackupBehavior]
    public class SuperCoolServiceApplication : SPIisWebServiceApplication
    {       
        protected override string VirtualPath
        { get{ return “SuperCool.svc”; } }

        protected override string DefaultEndpointName
        { get { return “https”; } }

        protected override string InstallPath
        {
            get {return SPUtility.GetGenericSetupPath(@”WebServices\SuperCoolServiceApplication”); }
        }

        /// <summary>
        /// Target location admin is sent to from within CA when clicking on Service App or
        /// selecting it and picking Manage in the ribbon from CA > Manage Service Apps page.
        /// </summary>
        public override SPAdministrationLink ManageLink
        {
            get { return new SPAdministrationLink(
           “/_admin/SuperCoolServiceApplication/Manage.aspx?ApplicationId=” + this.Id.ToString(“N”)); }
        }
       
        public SuperCoolServiceApplication(){}

        public SuperCoolServiceApplication(string name, SPIisWebService service, SPIisWebServiceApplicationPool applicationPool)
            : base(name, service, applicationPool){}

        public override void Provision()
        {
            base.Provision();
            if (this.Id == Guid.Empty)
                this.Update();
           
            RegisterEndpoint(this, “https”, SPIisWebServiceBindingType.Https, “secure”);
             
            if (this.Service.Status != SPObjectStatus.Online)
            {
                //this.Service.Provision();
                this.Service.Status = SPObjectStatus.Online;
                this.Service.Update();
            }
            this.Status = SPObjectStatus.Online;
            this.Update();
        }

        public override void Unprovision(bool deleteData)
        {
            foreach (SPIisWebServiceEndpoint ep in this.Endpoints)
                ep.Delete();           
            base.Unprovision(deleteData);
        }

        private static void RegisterEndpoint(SPIisWebServiceApplication serviceApplication, string name, SPIisWebServiceBindingType binding, string relativeAddress)
        {           
            foreach (SPIisWebServiceEndpoint endpoint in serviceApplication.Endpoints)
                if (endpoint.Name == name)
                    return;
       
if (!string.IsNullOrEmpty(relativeAddress))
                serviceApplication.AddServiceEndpoint(name, binding, relativeAddress);           
            else
                serviceApplication.AddServiceEndpoint(name, binding);
         }
    }
}

The Provision method is the main method that sets things up. This method registers the endpoints, and is also where you’d provision any databases, jobs or additional resources that will be “owned” by the service application.

With that one class, we’ve got the guts of Service Application created. In the next few posts we’ll look at creating the service instance, the service proxy and client, and we’ll wire it up through the SharePoint solution.

(Where are we going with this? This will just be a sample app that spits out “hello, world”. But it’ll have a backend database and be centrally managed. I’ll leave it to you to come up with something interesting, something super-cool to add to this!!!)

Advertisement
This entry was posted in SharePoint. Bookmark the permalink.

4 Responses to Step by Step SharePoint Service Applications : Part 1

  1. Pingback: Step by Step SharePoint Service Applications : Part 2 (Plumbing) | Daniel Larson's Developer Blog

  2. Josh Gavant says:

    Hi Daniel-

    Thanks for the discussion on SPIisWebServiceApplications – interesting and important stuff!

    I think you’d be better off calling base.Provision() after registering your custom endpoints. Otherwise, the base Provision method actually creates a default http endpoint using the DefaultEndpointName you’ve set. Check out SPIisWebServiceApplication.Provision() in .NET Reflector to verify that. Looks like your code will actually result in a HTTP endpoint called HTTPS.

    I think you’d be best off calling this.AddServiceEndpoint() in the constructor for the new service application. You could also skip the whole RegisterEndpoints static method – just rely on the OOTB AddServiceEndpoint method.

    In any case thanks for discussing these topics! I’m learning a lot from your articles.

    Best,
    Josh

    • daniellarson says:

      Thanks Josh! Good tips for sure. It’s a bit tricky distilling down code samples and reflected code to come up with really simple template code– but in the end, it’s mostly re-usable template code. I’ll see if I can incorporate those suggestions into my published sample code. Hopefully I’ll get to completing this series with full source code this week!

      Thanks again, Daniel

  3. Pingback: Step by Step SharePoint Service Applications : Part 4 (Deploying the Solution) | Daniel Larson's Developer Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s