SharePoint2010 Custom Service

Create Custom Service Classweb

Service類用來定義這個自定義「Service」,也是各類功能的入口點。它繼承SPIisWebService,並實現IServiceAdministration(以接入到管理系統中)。shell

[Guid("E828358E-E24C-4D78-BE87-C69D458766F4")]數據庫

public class KaneboyService : SPIisWebService, IServiceAdministrationapp

Service類一般實現二個構造函數:ide

  • 默認構造函數
  • 一個參數爲SPFarm對象的構造函數

public KaneboyService() { }函數

 

public KaneboyService(SPFarm farm) : base(farm) { }ui

IServiceAdministration的方法:orm

  • CreateApplication():建立一個SPServiceApplication對象。只有在經過運行psconfig.exe或farm configuration wizard建立Service Application時纔會調用它(因此對於自定義SPService,它一般不會有機會被調用)。
  • CreateProxy():建立一個SPServiceApplicationProxy對象。與CreateApplication()相似。
  • GetApplicationTypeDescription():返回對此Service的描述信息。
  • GetApplicationTypes():返回Service Application的類型。
  • GetCreateApplicationLink():若是但願能夠在管理中心的「管理服務應用程序」中新建此Service Application實例,那麼須要實現此方法並返回新建Service Application頁面的URL。

Create Custom Service Instance Classserver

Service Instance用來描述運行在每一個SPServer上的Service實例。它繼承SPIisWebServiceInstance。對象

public class KaneboyServiceInstance : SPIisWebServiceInstance

Service Instance類的構造函數:

  • 默認構造函數
  • 參數以下的構造函數:
    • 一個SPServer對象,表示運行此Service實例的Server
    • 所對應的SPIisWebService對象

public KaneboyServiceInstance() : base() { }

 

public KaneboyServiceInstance(SPServer server, SPIisWebService service) : base(server, service) { }

Service Instance類須要實現的方法:

  • TypeName屬性:描述此Service Instance的名稱,顯示在管理UI。

Create Custom Service Application Class

Service Application類是對Service Application的實現。它繼承SPIisWebServiceApplication,並一般實現Service Contract接口。

[IisWebServiceApplicationBackupBehavior]

[ServiceBehavior(

        InstanceContextMode = InstanceContextMode.PerSession,

        ConcurrencyMode = ConcurrencyMode.Multiple,

        IncludeExceptionDetailInFaults = true)]

[Guid("933A11F0-7265-4694-97C0-FE04BFB370A5")]

public class KaneboyServiceApplication : SPIisWebServiceApplication, IKaneboyServiceContract

Service Application類的構造函數:

  • 默認構造函數
  • 帶下列參數的構造函數:
    • Service Application名稱
    • 所對應的SPIisWebService對象
    • 所使用的SPIisWebServiceApplicationPool對象

public KaneboyServiceApplication() : base() { }

 

private KaneboyServiceApplication(String name, KaneboyService service, SPIisWebServiceApplicationPool appPool) : base(name, service, appPool) { }

Service Application須要告訴系統,如何鏈接到WCF Service,因此它須要實現:

  • InstallPath屬性:返回.svc所在的目錄。
  • VirtualPath屬性:返回.svc文件的名稱。

若是在Provision這個Service Application的時候,還須要Provision數據庫或其餘資源,能夠重載Provision()和Unprovision()方法。

建立(並Provision)一個Service Application不能直接使用它的構造函數,而是須要使用以下步驟:

  • 建立Service Application至少須要用到以下信息:
    • Service Application名稱
    • 它所對應的SPService對象
    • 它所使用的SPIisWebServiceApplicationPool對象
    • 經過SPService.Applications.GetValue(),肯定這個Service Application是否有其餘實例存在。
    • 使用它的構造函數,新建一個實例對象。
    • 調用SPServiceApplication.Update()保存新建的實例。
    • 調用SPServiceApplication.AddServiceEndpoint()爲Service Application新建WCF Endpoint。

serviceApp.AddServiceEndpoint("http", SPIisWebServiceBindingType.Http);

serviceApp.AddServiceEndpoint("https", SPIisWebServiceBindingType.Https, "secure");

  • 調用SPServiceApplication.Provision()以Provision它。

建立並Provision 自定義Service Application的方法,能夠放到Service Application類中,以static method提供。管理員可使用管理中心UI(位於」ADMIN」中的自定義.aspx,路徑由IServiceAdministration.GetCreateApplicationLink()指定)或自定義powershell cmdlets來完成這個操做,因此在管理中心UI或自定義cmdlets中,須要調用這個static method。

WCF Artifacts

首先,須要一個自定義Host Factory類,繼承自ServiceHostFactory。

public class KaneboyServiceHostFactory : ServiceHostFactory

它重載CreateServiceHost()方法,建立並返回一個ServiceHost對象。

public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)

{

ServiceHost serviceHost = new ServiceHost(typeof(KaneboyServiceApplication), baseAddresses);

serviceHost.Configure(SPServiceAuthenticationMode.Claims);

return serviceHost;

}

在」WebServices」這個mapped folder下面,須要放置自定義Service Application的.svc文件和定義WCF channel的web.config。.svc只須要經過標籤告知Service和Factory類便可。

<%@ServiceHost Language="C#" Debug="true"

               Service="KaneboyServiceApp1.KaneboyServiceApplication, $SharePoint.Project.AssemblyFullName$"

               Factory="KaneboyServiceApp1.KaneboyServiceHostFactory, $SharePoint.Project.AssemblyFullName$" %>

web.config裏面須要定義Service Application將使用的channel。

<configuration>

  <system.serviceModel>

    <services>

      <service name="KaneboyServiceApp1.KaneboyServiceApplication">

        <endpoint

          address=""

          contract="KaneboyServiceApp1.IKaneboyServiceContract"

          binding="customBinding"

          bindingConfiguration="CustomServiceHttpBinding" />

        <endpoint

          address="secure"

          contract="KaneboyServiceApp1.IKaneboyServiceContract"

          binding="customBinding"

          bindingConfiguration="CustomServiceHttpsBinding" />

       </service>

    </services>

    <bindings>

      <customBinding>

        …

      </customBinding>

    </bindings>

  </system.serviceModel>

  <system.webServer>

    <security>

      …

    </security>

  </system.webServer>

</configuration>

Register Service on Farm

將Service註冊到Farm裏面,須要建立Service和Service Instance對象,並將它們Persist到Config DB中(經過調用Update())。註冊能夠經過一個Farm Feature的activate事件來實現。在新建Service和Service Instance對象以前,能夠經過調用SPFarm.Services.GetValue()來確認是否Farm中已經註冊了此服務。在Farm Feature的deactivate事件中,能夠將相關的Service和Service Instance刪除。

Create and Provision Service Application

新建Service Application的實例,可使用管理中心UI(「管理服務應用程序」)或自定義powershell cmdlets來實現。若是是經過管理中心UI,能夠在「ADMIN」中新建一個.aspx,並將其路徑在Service類中經過IServiceAdministration.GetCreateApplicationLink()告知系統。

不管哪一種方法,最關鍵的是,如何將Service Application所使用的SPIisWebServiceApplicationPool對象傳遞給新建Service Application的代碼。若是是使用.aspx,可使用」 ~/_admin/IisWebServiceApplicationPoolSection.ascx」控件,而後經過IisWebServiceApplicationPoolSection.GetOrCreateApplicationPool()獲得用戶選擇的App Pool。若是是使用cmdlets,那麼就經過SPIisWebServiceApplicationPoolPipeBind類來獲得App Pool信息。(Check MSDN to get detail information.)

------------------ 「Server」(App Server)與」Client」(WFE)的分割線 ----------------------

WCF Artifacts

在」WebClients」這個mapped folder下面,將一個」client.config」文件放置到一個自定義目錄中,此文件中包含了告知Service Application Proxy經過哪一個channel鏈接到Service Application的配置信息。

<configuration>

  <system.serviceModel>

    <client>

      <endpoint

        name="http"

        contract="KaneboyServiceApp1.IKaneboyServiceContract"

        binding="customBinding"

        bindingConfiguration="CustomServiceHttpBinding" />

      <endpoint

        name="https"

        contract="KaneboyServiceApp1.IKaneboyServiceContract"

        binding="customBinding"

        bindingConfiguration="CustomServiceHttpsBinding" />

    </client>

    <bindings>

      <customBinding>

            …

      </customBinding>

    </bindings>

  </system.serviceModel>

</configuration>

 

Create Custom Service Proxy Class

Service Proxy類用來描述service consumer。它繼承SPIisWebServiceProxy,並實現IServiceProxyAdministration。

[SupportedServiceApplication("933A11F0-7265-4694-97C0-FE04BFB370A5", "1.0.0.0", typeof(KaneboyServiceApplicationProxy))]

[Guid("44203351-1E42-413E-BAAA-42A4A0788A8D")]

public class KaneboyServiceProxy : SPIisWebServiceProxy, IServiceProxyAdministration

Service Proxy類的構造函數:

  • 默認構造函數
  • 參數爲SPFarm對象的構造函數

IServiceProxyAdministration的方法:

  • CreateProxy():建立一個SPServiceApplicationProxy。
  • GetProxyTypeDescription():返回對此Service Proxy的描述。
  • GetProxyTypes():返回Service Application Proxy的類型。

Create Custom Service Application Proxy Class

Service Application Proxy類定義了鏈接到Service Application的接口,Service Consumer經過它實現對Service的調用。它繼承SPIisWebServiceApplicationProxy類。

[IisWebServiceApplicationProxyBackupBehavior]

[System.Runtime.InteropServices.Guid("6339C282-E7D3-4B0D-94DF-2D09773FDF80")]

public class KaneboyServiceApplicationProxy : SPIisWebServiceApplicationProxy

Service Application Proxy類的構造函數:

  • 默認構造函數
  • 包含如下參數的構造函數:
    • Service Application Proxy的名稱
    • 所對應的Service Proxy對象
    • Service Application的Endpoint URL

public KaneboyServiceApplicationProxy() : base() {}

 

public KaneboyServiceApplicationProxy(String name, KaneboyServiceProxy serviceProxy, Uri serviceEndpointUri) : base(name, serviceProxy, serviceEndpointUri)

{

_loadBalancer = new SPRoundRobinServiceLoadBalancer(serviceEndpointUri);

}

因爲Service Application一般須要Load Balance的能力,因此Service Application Proxy一般會包含一個SPServiceLoadBalancer類型field,它可使用SharePoint內置提供的SPRoundRobinServiceLoadBalancer類來實例化。SPRoundRobinServiceLoadBalancer類須要給出Service Application的URL來進行構造。

Service Application Proxy要實現的方法:

  • 一個根據Service Application的Url,獲取Endpoint Configuration名稱(對應到client.config中」<Endpoint>」節點的」name」屬性)的方法(如「GetEndpointConfigurationName()」),Endpoint Configuration的名稱一般是「http」和「https」。
  • 一個建立並返回ChannelFactory<T>的方法(如「CreateChannelFactory()」),它須要讀取client.config中的信息。

private ChannelFactory<T> CreateChannelFactory<T>(string endpointConfigName)

{

// open client.config

string clientConfigPath = SPUtility.GetGenericSetupPath(@"WebClients\KaneboyServiceApp1");

Configuration clientConfig = OpenClientConfiguration(clientConfigPath);

ConfigurationChannelFactory<T> factory = new ConfigurationChannelFactory<T>(endpointConfigName, clientConfig, null);

 

// configure the channel factory for IDFx claims auth

factory.ConfigureCredentials(SPServiceAuthenticationMode.Claims);

 

return factory;

}

  • 一個獲取Channel(Service Contract接口)的方法,經過調用ChannelFactory. CreateChannelActingAsLoggedOnUser<T>(),來獲取Channel。

private IKaneboyServiceContract GetChannel(Uri address)

{

    // get the endpoint config name

    string endpointConfigName = GetEndpointConfigurationName(address);

 

    ChannelFactory<IKaneboyServiceContract> channelFactory = CreateChannelFactory<IKaneboyServiceContract>(endpointConfigName);

 

    IKaneboyServiceContract channel  = channelFactory.CreateChannelActingAsLoggedOnUser<IKaneboyServiceContract>(new EndpointAddress(address));

    return channel;

}

結合以上的Helper方法,就能夠拿到能夠透過WCF遠程調用Service Application的Channel對象。

建立(並Provision)一個Service Application Proxy的步驟以下:

  • 調用Service Application Proxy構造函數,新建實例。
  • 調用SPServiceApplicationProxy.Update(true)將對象persist到ConfigDB中。
  • 調用SPServiceApplicationProxy.Provision()。

相似Service Application,建立Service Application Proxy的方法能夠放到此類中,以static method的方式提供。

Create and Provision Service Application Proxy

新建並Provision Service Application Proxy,相似Service Application,可使用管理中心UI或自定義powershell cmelets實現。

若是是使用管理中心UI,能夠在建立並Provision了Service Application以後,緊接着建立Service Application Proxy。若是是建立cmdlets,可使用SPServiceApplicationPipeBind來獲得其所對應的Service Application。

Invoke Service

經過Service Application Proxy調用Service Application所提供的功能,步驟以下:

  • 獲取SPServiceApplicationProxy對象,能夠經過SPServiceContext.GetDefaultProxy()來得到。
  • 調用SPServiceApplicationProxy對象所持有的SPServiceLoadBalancer對象的BeginOperation()獲取一個SPServiceLoadBalancerContext對象,而後經過使用SPServiceLoadBalancerContext.EndpointAddress拿到此次請求須要調用的Endpoint Url。使用此Url,並經過調用Service Application Proxy中的Helper方法,拿到IChannel對象,也就是實現了Service Contract的對象。
  • 調用IChannel上的方法
  • 使用IChannel.Close()關閉鏈接。
  • 調用SPServiceLoadBalancer.EndOperation()告知完成了Load Balance操做。
相關文章
相關標籤/搜索