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所提供的功能,步骤以下: