Create Custom Service Classweb
Service類用來定義這個自定義「Service」,也是各類功能的入口點。它繼承SPIisWebService,並實現IServiceAdministration(以接入到管理系統中)。shell
[Guid("E828358E-E24C-4D78-BE87-C69D458766F4")]數據庫
public class KaneboyService : SPIisWebService, IServiceAdministrationapp
Service類一般實現二個構造函數:ide
public KaneboyService() { }函數
public KaneboyService(SPFarm farm) : base(farm) { }ui
IServiceAdministration的方法:orm
Create Custom Service Instance Classserver
Service Instance用來描述運行在每一個SPServer上的Service實例。它繼承SPIisWebServiceInstance。對象
public class KaneboyServiceInstance : SPIisWebServiceInstance
Service Instance類的構造函數:
public KaneboyServiceInstance() : base() { }
public KaneboyServiceInstance(SPServer server, SPIisWebService service) : base(server, service) { }
Service Instance類須要實現的方法:
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類的構造函數:
public KaneboyServiceApplication() : base() { }
private KaneboyServiceApplication(String name, KaneboyService service, SPIisWebServiceApplicationPool appPool) : base(name, service, appPool) { }
Service Application須要告訴系統,如何鏈接到WCF Service,因此它須要實現:
若是在Provision這個Service Application的時候,還須要Provision數據庫或其餘資源,能夠重載Provision()和Unprovision()方法。
建立(並Provision)一個Service Application不能直接使用它的構造函數,而是須要使用以下步驟:
serviceApp.AddServiceEndpoint("http", SPIisWebServiceBindingType.Http);
serviceApp.AddServiceEndpoint("https", SPIisWebServiceBindingType.Https, "secure");
建立並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類的構造函數:
IServiceProxyAdministration的方法:
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類的構造函數:
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要實現的方法:
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;
}
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,建立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所提供的功能,步驟以下: