Step by Step SharePoint Service Applications : Part 4 (Deploying the Solution)

This is the fourth post in a series of writing a SharePoint Service Application. As stated in part 3, if you’ve missed the first posts, read those or this won’t make a lick of sense. (It may not make a lick of sense regardless!) Once again, note that creating a service application is OVERKILL for most things you’ll create for SharePoint. And while this example only spits out a simple “Hello World” type of sample, you can use this as “starter code” for a much more complex application.

For those who attended SharePoint Saturday in Denver last week, here’s the promised code, and thanks for coming to my session!

Here are the first four posts in this series:

Now that you have the guts in place, it’s time to create the deployment solution. Whenever you write complex SharePoint solutions, it’s best to keep the SharePoint project that creates the WSP file scoped to the deployment. Think of it ONLY as the Installer project for your SharePoint solution.

Since it’s been a while since I wrote the first posts (I am sorry if you’ve been waiting…), I am going to take the lazy approach here, and post the code for you to download and follow along. Rather than trying to walk you through creating it from scratch, simply download the source and I’ll talk you through the components.

DOWNLOAD THE SERVICE APPLICATION SOURCE HERE

In the source code you’ll see 2 project: the first is the SuperCoolServiceLibrary. This is the code for the service application, as discussed in the previous posts. The second is the SharePoint “installer” project which we’ll focus on in this post.

The WSP needs to contain the following mapped folder structure:

  • ADMIN (mapped folder {SharePointRoot}\Template\ADMIN)
    • SuperCoolServiceApplication
      • Default.aspx
      • Manage.aspx
  • Layouts (mapped folder {SharePointRoot}\Template\Layouts)
    • SuperCoolServiceApplication
      • Debug.aspx (just a test page)
  • WebClients (mapped folder {SharePointRoot}\WebClients)
    • SuperCoolServiceApplication
      • Client.config
  • WebServices (mapped folder {SharePointRoot}\WebServices)
    • SuperCoolServiceApplication
      • Web.config
      • SuperCool.svc

 

Let’s start with the most obvious. WebServices contains the WCF web service which will be the backend WCF service. Note that it needs a Web.config file as well as the .svc file.

Next up is WebClients. WebClients contains the client.config file which the configuration based channel factory will use to communicate to the backend service.

Then… the Layouts folder contains just a debug page which will exercise the Hello World method in the service.

Most importantly, you’ll need to include an installer feature which will create the instances and make available your service in the Manage Application Services page. That code looks like this (from installer.eventreceiver.cs):

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    SPFarm farm = SPFarm.Local;
    SPServer server = SPServer.Local;

    // check if the service has already been installed in the farm
    var service = farm.Services.GetValue<SuperCoolService>();
    if (service == null)
    {
        // create the service
        service = new SuperCoolService(farm);
        service.Status = SPObjectStatus.Online;
        service.Update();
    }

    // with the service added to the farm, see if there is a installed instance on the server...
    //   if not, create it
    SuperCoolServiceInstance serverSvcInstance = new SuperCoolServiceInstance(server, service);
    serverSvcInstance.Update(true);

    // install the service proxy into the farm if isn't already installed
    var serviceProxy = farm.ServiceProxies.GetValue<SuperCoolServiceProxy>();
    if (serviceProxy == null)
    {
        serviceProxy = new SuperCoolServiceProxy(farm);
        serviceProxy.Update(true);
    }
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
    SPFarm farm = SPFarm.Local;
    SPServer server = SPServer.Local;

    //Remove all instances
    var instance = server.ServiceInstances.GetValue<SuperCoolServiceInstance>();
    while (instance != null)
    {
        server.ServiceInstances.Remove(instance.Id);
        instance = server.ServiceInstances.GetValue<SuperCoolServiceInstance>();
    }    //Uninstall the service proxy
    var serviceProxy = farm.ServiceProxies.GetValue<SuperCoolServiceProxy>();
    if (serviceProxy != null)
    {
        farm.ServiceProxies.Remove(serviceProxy.Id);
    }

    //Remove service and jobs
    var service = farm.Services.GetValue<SuperCoolService>();
    if (service != null)
        farm.Services.Remove(service.Id);
}

In the Admin folder, you’ll need a default.aspx page which will be the UI to CREATE an instance of your service application. You can also include an admin page here as well.

The code behind from the default page in Admin contains the following code, which is used to create your service application:

var service = SPFarm.Local.Services.GetValue<SuperCoolService>();
if (service == null)
    throw new InvalidOperationException("The service is not installed.");

//// Get the service proxy object
SuperCoolServiceProxy serviceProxy = SPFarm.Local.ServiceProxies.GetValue<SuperCoolServiceProxy>();
if (null == serviceProxy)
    throw new InvalidOperationException("The service proxy is not installed.");

var appPoolInput = this.applicationPoolSection as IisWebServiceApplicationPoolSection;
using (SPLongOperation operation = new SPLongOperation(this))
{
    operation.Begin();

    SPIisWebServiceApplicationPool pool = null;
    pool = appPoolInput.GetOrCreateApplicationPool();
    if (pool == null)
        throw new ConfigurationErrorsException("Could not find an application pool to use!!!");

    var app = new SuperCool.ServiceLibrary.SuperCoolServiceApplication(
            this.serviceNameInput.Text, service, pool);

    app.Update(true);

    app.Provision();

    var serviceAppProxy = new SuperCoolServiceApplicationProxy("Super Cool Service Proxy Thingamajig",
        serviceProxy, app.Uri);
    serviceAppProxy.Provision();
    SPServiceApplicationProxyGroup.Default.Add(serviceAppProxy);
    SPServiceApplicationProxyGroup.Default.Update();

    //Start the service instance
    var server = SPServer.Local;
    var instance = server.ServiceInstances.GetValue<SuperCoolServiceInstance>();
    if (instance == null)
    {   //It should be created during feature activation, but if we can't find it  - create it here.
        instance = new SuperCoolServiceInstance(server, service);
        instance.Update(true);
    }
    if (instance != null && instance.Status != SPObjectStatus.Online)
        instance.Provision();
}
this.SendResponseForPopUI();

In case you missed the link, DOWNLOAD THE SERVICE APPLICATION SOURCE HERE. Then you can play along!!! I’ll post more notes on this in the coming weeks after the Thanksgiving celebrations die down.

To all of you, Happy Thanksgiving, and may you have a great season of the holy days.

Daniel Larson

Advertisement
This entry was posted in Programming, SharePoint and tagged , . Bookmark the permalink.

12 Responses to Step by Step SharePoint Service Applications : Part 4 (Deploying the Solution)

  1. Hey Dan!

    Really great to see the final downloadable version of this. I really was disappointed I didn’t make it down to SPSDenver to see your talk. Did it get recorded?

    -JV

  2. Hi Daniel,

    Great article series

    I became interesting in a specific part of your article. When you wrote about a golden SharePoint development rule “WSPs are ONLY for Deployment” I don´t understand very well your goal because when o read your last article you add a lot of files in the deploy, like a ASPX files and so on. In part o got what you mean, it´s about code, your C# should be in a separated Solution and DLLs. Is it true?

    Do you have any article that I can find more information about that rule It´s because recently I change our SharePoint reusable process to create multiples WSPs and control all versions individually for each reusable feature.

    Your words is a really mindset change for me but I don´t have a good experience in Product Development instead we are solution provider.

    Thanks

    • daniellarson says:

      WSPs are for deployment… and part of that includes pages, .webpart files, features, that type of thing. But we try to keep as much as possible OUT of the WSP and in class libraries (dlls). Keep in mind as well that sample code is only sample code. :) And of course, it’s only a generalized rule, but it does tend to make your code scale better.

  3. Rohidas says:

    Hi Dan,

    How to take the NewsGator community Backup so that i can see the NewsFeeds which are there in the new location.

    Thanks,
    Rohidas

  4. Gig says:

    Hi Dan,
    I’m not able to download the code. It’s only an issue from my side?
    Is the service ready to be consumed from another farm? Are there some additional steps to be performed?

    Thanks

    • daniellarson says:

      Gig, the code download link is to a public folder on my Windows Live SkyDrive. You may need to log on to Windows Live to download it. You could consume the service from a remote farm if you have the chops.

  5. Alfa says:

    I Dan,

    I used your example to publish a custom service on my SP machine.
    Now when I try to connect to the service from another machine I get the message “no items to display in this view”. Any idea?

    Thanks,
    Alfa

  6. Pingback: SharePoint 2010 – Custom Service Application : « Project starter » avec base de données

  7. Pingback: SharePoint 2010 – Custom Service Application : “Project starter project” with SQL backend

  8. Pingback: SharePoint 2010 – Custom Service Application : “Project starter project” with SQL backend

  9. Pingback: SharePoint 2010 – Custom Service Application : “Starter project” with SQL backend

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