Wednesday, 21 November 2012

Custom WCF Service in SharePoint

http://answers.oreilly.com/topic/1404-how-to-customize-wcf-services-in-sharepoint-2010/


Creating a Custom WCF Service in SharePoint Foundation

This topic has not yet been rated Rate this topic
Published: May 2010
This part of the walkthrough shows how to create a custom Windows Communication Foundation (WCF) service that allows users to revert list items to their previous versions. The version history of list items is not exposed through the other client APIs, and so this example creates a service that uses the server-side object model to provide this functionality to client applications.
The example shows how to create a custom WCF service in Microsoft Visual Studio 2010 as a Microsoft SharePoint Foundation project that you can deploy to any farm. In addition, because the SharePoint Foundation project type does not support WCF libraries by default, this example involves creating a WCF service library as an external project to generate the IService1 and Service1 .cs or .vb files for your project.
This example assumes that you completed the previous two parts of this walkthrough—Implementing the SharePoint Foundation REST Interface and Implementing the Client-Side Object Model—and created a Windows Forms Application that is used to implement the custom WCF service.
  1. To create a SharePoint Foundation project for the WCF service, open the ProjectTracker solution in Visual Studio. In Solution Explorer, click the solution. On the File menu, point to Add, and then click New Project. In the Installed Templates tab of the Add New Project dialog box, expand either the Visual Basic or Visual C#node, select SharePoint, select Empty SharePoint Project, and then type RevertService as the name of the project. Click OK.
  2. In the SharePoint Customization Wizard, verify that the correct local site is specified for debugging. Because sandboxed solutions do not support WCF services, select Deploy as a farm solution, and then click Finish.
  3. To create the external WCF project to obtain its IService1 and Service1 .cs or .vb files, click the ProjectTrackersolution again, and follow the same procedure as in Step 1 to open the Add New Project dialog box. Expand either the Visual Basic or Visual C# node, select WCF, select WCF Service Library, type WcfService as the name, and then click OK.
  4. Copy the generated IService1 and Service1 files into the RevertService project. Because you no longer need the WCF Service Library project, you can remove it from the solution by right-clicking the WCF Service Library and clicking Remove.
  5. Add references in the RevertService project to the System.Runtime.Serialization and System.ServiceModelWCF assemblies, and to Microsoft.SharePoint, the main assembly of the server object model. Right-click theRevertService project, click Add Reference, and select each of these assemblies on the .NET tab.
  6. To add a reference to Microsoft.SharePoint.Client.ServerRuntime, which contains the service factories that are provided by SharePoint Foundation, use the Browse tab of the Add Reference box to navigate to the Microsoft.SharePoint.Client.ServerRuntime.dll file in%Windows%\assembly\GAC_MSIL\Microsoft.SharePoint.Client.ServerRuntime, select the DLL, and then click OK.
  7. To specify the contract of your custom WCF service in IService1.cs (or IService1.vb), replace the auto-generated service contract with the following interface definition, where the Revert method accepts the name of the list in which to revert changes and the ID of the item to revert.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace WcfService
    {
        [ServiceContract]
        public interface IRevert
        {
            [OperationContract]
            void Revert(string listName, int listItemId);
        }
    }
    
  8. Specify the implementation of the service by replacing the auto-generated code of Service1.cs (Service1.vb) with the following code. The example uses the SharePoint Foundation object model to retrieve the list by its name, to retrieve the item to revert by ID, and to check for the presence of item versions and revert them back by one version:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    
    namespace WcfService
    {
        using Microsoft.SharePoint.Client.Services;
        using System.ServiceModel.Activation;
        using Microsoft.SharePoint;
    
        [BasicHttpBindingServiceMetadataExchangeEndpointAttribute]
        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
        public class RevertService : IRevert
        {
            public void Revert(string listName, int listItemId)
            {
                SPList oList = SPContext.Current.Web.Lists[listName];
    
                SPListItem oItem = oList.GetItemById(listItemId);
    
                if (oItem.Versions.Count > 1)
                {
                    oItem.Versions.Restore(1);
                }
            }
        }
    }
    
    In the previous example, the RevertService class has an attribute for binding,BasicHttpBindingServiceMetadataExchangeEndpointAttribute, which instructs the SharePoint Foundation service factory to automatically create a metadata exchange endpoint for the service.
  9. Now that the implementation of the service is ready, you can deploy the service to SharePoint Foundation. Right-click the RevertService project, point to Add, and click SharePoint Mapped Folder. In the Add SharePoint Mapped Folder dialog box, select ISAPI, and then click OK to map the ISAPI folder of the SharePoint Foundation hive to the RevertService project. If Visual Studio creates a RevertService subfolder in the ISAPI folder of the RevertService project, right-click the subfolder and click Remove to delete it.
  10. To create a registration file for your service in the ISAPI folder, click the ISAPI folder in your project, and on theProject menu, click Add New Item. Under Installed Templates, select General. Select Text File, name the fileRevert.svc, and then click Add.
  11. Add the following service declaration to Revert.svc, which specifies the SharePoint Foundation factories and the namespace that contains them. In the example, MultipleBaseAddressBasicHttpBindingServiceHostFactoryspecifies the service factory for the SOAP type of web service. The service class declaration also specifies the name of the service class and uses a token to specify the strong name of the assembly.
    <%@ServiceHost Language="C#" Debug="true"
        Service="WcfService.RevertService, $SharePoint.Project.AssemblyFullName$"
        Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    
    If you are creating the service in Visual Basic, specify VB instead of C# as the language, and in the Serviceattribute, include the name of your SharePoint Foundation project, as specified in step one, as follows:
    <%@ServiceHost Language="VB" Debug="true"
        Service="RevertService.WcfService.RevertService, $SharePoint.Project.AssemblyFullName$"
        Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    
  12. Because Visual Studio 2010 by default does not process the type of tokens used in the previous .svc file, you must add an additional instruction in the project file. Save all changes in your project, right-click theRevertService project, and then click Unload Project. Right-click the RevertService node again, click Edit RevertService.csproj or Edit RevertService.vbproj, and add a <TokenReplacementFileExtensions> tag as follows to the first property group in the .csproj or .vbproj file to enable processing of tokens in .svc file types.
    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
        <SchemaVersion>2.0</SchemaVersion>
        <ProjectGuid>{F455078E-8836-403A-9E63-5E5F21B5F694}</ProjectGuid>
        <OutputType>Library</OutputType>
        <AppDesignerFolder>Properties</AppDesignerFolder>
        <RootNamespace>RevertService</RootNamespace>
        <AssemblyName>RevertService</AssemblyName>
        <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
        <FileAlignment>512</FileAlignment>
        <ProjectTypeGuids>{BB1F664B-9266-4fd6-B973-E1E44974B511};{14822709-B5A1-4724-98CA-57A101D1B079};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
        <SandboxedSolution>False</SandboxedSolution>
        <TokenReplacementFileExtensions>svc</TokenReplacementFileExtensions>
      </PropertyGroup>
    . . . .
    
  13. After you add the previous tag, save the project and close the .csproj file. In Solution Explorer, right-click theRevertService project, and then click Reload Project.
  14. To deploy the custom web service to SharePoint Foundation, in Solution Explorer, right-click theRevertService project, and then click Deploy. Visual Studio compiles the project’s code, builds a WSP file, and deploys the file to the front-end web server.
  15. To use the custom web service from your ProjectTracker client application, right-click the Service Referencesnode of the application in Solution Explorer, and then click Add Service Reference. In the Add Service Reference dialog box, type the URL of your custom WCF service in the Address box, and specify MEX as the standard name for the metadata exchange endpoint, as follows:http://Server/sites/SiteCollection/MyWebSite/_vti_bin/Revert.svc. Click Go to download the service information, and then click OK to add the reference.
  16. To add a Revert button in Form1 that implements the custom service, right-click the form title bar next to theSave button, and then select Button in the drop-down list that appears.
  17. In the Properties window for the button, set DisplayStyle to Text, and type Revert as the value for the Textsetting.
  18. Double-click the Revert button and add to its Click event the following standard WCF proxy setup code with a call to your custom WCF service. Resolve references to assemblies by right-clicking red underlined elements in the code, pointing to Resolve, and accepting recommended assembly references for the System.ServiceModelnamespace and for the namespace of your custom WCF service (ProjectTracker.ServiceReference2).
    private void toolStripButton2_Click(object sender, EventArgs e)
    {
        // Set up proxy.
        BasicHttpBinding binding = new BasicHttpBinding();
        binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
        EndpointAddress endpoint =
            new EndpointAddress(websiteUrl + "/_vti_bin/Revert.svc");
        RevertClient proxy = new RevertClient(binding, endpoint);
        proxy.ClientCredentials.Windows.AllowedImpersonationLevel =
            System.Security.Principal.TokenImpersonationLevel.Impersonation;
    
        // Call web service.
        proxy.Revert("Projects", ((ProjectsItem)projectsBindingSource.Current).Id);
    
        // Refresh the UI.
        context.MergeOption = System.Data.Services.Client.MergeOption.OverwriteChanges;
    
        context.Projects.ToList();
        projectsBindingSource.ResetCurrentItem();
    }
    
    Notice in the Revert method call of the previous example that the name of the SharePoint Foundation list is specified, and that the Current property is used to return the ID of the currently selected item in the ProjectsDataGridView control. After the web service call, the code refreshes the user interface (UI) and re-retrieves data from SharePoint Foundation.
  19. Press F5 to run the client application, and test the web service by changing an item in the ProjectsDataGridView and clicking the Revert button.
For the complete Form1 code sample, see Complete SharePoint Foundation WCF Form1 Sample.

Static classes and singletons

Static classes and singletons both provide sharing of redundant objects in memory, but they are very different in usage and implementation. 

Static Class - You can not create the instance of static class. 
Singleton pattern - you can create one instance of the object and reuse it. 
Static classes- are loaded automatically by the .NET Framework common language runtime (CLR) when the program or namespace containing the class is loaded. 
Singleton instance is created for the first time when the user requested. 
Static Class class cannot have constructor. 
singleton class can have constructor.


http://www.dotnetperls.com/singleton-static



C# - Singleton Pattern vs. Static Classes

Problem: Store some common data in a singleton or static class about your program in an object array, which you store in a class. It saves state between usages and stores some caches, and must be initialized only once and shared in many code locations. Making a new object each time would be expensive.

Solution

This article covers the differences between the singleton design pattern and the static keyword on C# classes. Static classes and singletons both provide sharing of redundant objects in memory, but they are very different in usage and implementation.

Introducing the Singleton Pattern

Our ideal solution is called the singleton design pattern. Here is an implementation of a singletonthat I will use. As you know, a singleton is a single-instance object. It is highly efficient and very graceful. Singletons have a static property that you must access to get the object reference.
01./// <summary>
02./// Sample singleton object.
03./// </summary>
04.public sealed class SiteStructure
05.{
06./// <summary>
07./// Possible an expensive resource we need to only store in one place.
08./// </summary>
09.object[] _data = new object[10];
10. 
11./// <summary>
12./// Allocate ourselves. We have a private constructor, so no one else can.
13./// </summary>
14.static readonly SiteStructure _instance = new SiteStructure();
15. 
16./// <summary>
17./// Access SiteStructure.Instance to get the singleton object.
18./// Then call methods on that instance.
19./// </summary>
20.public static SiteStructure Instance
21.{
22.get return _instance; }
23.}
24. 
25./// <summary>
26./// This is a private constructor, meaning no outsides have access.
27./// </summary>
28.private SiteStructure()
29.{
30.// Initialize members, etc. here.
31.}
32.}

Static Class Example

In the following example, look carefully at how the static keyword is used on the class and constructor. Static classes may be simpler, but the singleton example has many important advantages, which I will elaborate on after this code block.
01./// <summary>
02./// Static class example. Pay heed to the static keywords.
03./// </summary>
04.static public class SiteStatic
05.{
06./// <summary>
07./// The data must be a static member in this example.
08./// </summary>
09.static object[] _data = new object[10];
10. 
11./// <summary>
12./// C# doesn't define when this constructor is run, but it will
13./// be run right before it is used most likely.
14./// </summary>
15.static SiteStatic()
16.{
17.// Initialize all of our static members.
18.}
19.}
You can use static classes to store single-instance, global data. The class will be initialized at any time, but it is my experience that it is initialized lazily, meaning at the last possible moment. However, you lose control over the exact behavior of the class by using a static class.

Singleton Advantages

Singletons preserve the conventional class approach, and don't require that you use the static keyword everywhere. They may be more demanding to implement at first, but will greatly simplify the architecture of your program. Unlike static classes, we can use singletons as parameters or objects.
1.// We want to call a function with this structure as an object.
2.// Get a reference from the Instance property on the singleton.
3.{
4.SiteStructure site = SiteStructure.Instance;
5.OtherFunction(site); // Use singleton as parameter.
6.}

Interface Inheritance

In C#, an interface is a contract, and objects that have an interface must meet all of the requirements of that interface. Usually, the requirements of the interface are a subset of the object in question. Here is how we can use a singleton with an interface, which in the example is called ISiteInterface.
01./// <summary>
02./// Stores signatures of various important methods related to the site.
03./// </summary>
04.public interface ISiteInterface
05.{
06.};
07. 
08./// <summary>
09./// Skeleton of the singleton that inherits the interface.
10./// </summary>
11.class SiteStructure : ISiteInterface
12.{
13.// Implements all ISiteInterface methods.
14.// [omitted]
15.}
16. 
17./// <summary>
18./// Here is an example class where we use a singleton with the interface.
19./// </summary>
20.class TestClass
21.{
22./// <summary>
23./// Sample.
24./// </summary>
25.public TestClass()
26.{
27. 
28.// Send singleton object to any function that can take its interface.
29.SiteStructure site = SiteStructure.Instance;
30.CustomMethod((ISiteInterface)site);
31.}
32. 
33./// <summary>
34./// Receives a singleton that adheres to the ISiteInterface interface.
35./// </summary>
36.private void CustomMethod(ISiteInterface interfaceObject)
37.{
38.// Use the singleton by its interface.
39.}
40.}
Now we can reuse our singleton for any of the implementations of interface-conforming objects. There may be 1, 2, or 10. We don't need to rewrite anything over and over again. We store state more conventionally, use objects by their interfaces, and can use traditional object-oriented programmingbest practices.

Conclusion

Here we can reuse code and control object state much easier. This allows you greatly improved code-sharing, and a far cleaner body of code. With less code, your programs will usually have fewer bugs and will be easier to maintain. One good book about this topic is called C# Design Patterns and is written by Judith Bishop.