WCF系列一完全不使用配置文件构建和使用WCF服务
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
只使用代码而不用配置文件的情况不适合IIS为宿主的情况,IIS宿主必须使用配置文件配置WCF的ServiceHost。
1、服务端
1.1.准备Contract和实现Contract的服务
很简单的一个Contract(Interface)和实现这个Contract(实现这个接口的类)的服务。
这是VS2005中使用add new item,选WCF Service后自动生成的一个模板例子服务代码。
1.2.建立ServiceHost
一般使用public ServiceHost(Type serviceType, params Uri[] baseAddresses)构造方法建立ServicesHost。
参数:
Type serviceType -- 为实现了某些Contract的类的类型,为这个服务主机要host的服务。
params Uri[] baseAddresses -- 为任意数量的baseAddress。
一个ServiceHost内只能驻留一个Service类,但是这个Service类可以实现多个Contract,每个Contract都能通过一个或多个(不同的bind)Endpoint向客户端暴露。
1.3.给ServiceHost添加Endpoint
Endpoint是直接暴露给客户端就行通讯的接口,经典的一个Endpoint可以用ABC来描述,即address –这个Endpoint对外的访问地址,binding –这个Endpoint是通过什么样的通讯手段暴露给客户端的,Contract -- 这个Endpoint对外暴露的是哪个Contract。
通过两个方法给ServiceHost添加Endpoint
ServiceHost.AddServiceEndpoint AddServiceEndpoint方法有8种重载,ServiceHost提供了四种:
ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, string address);
ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, Uri address);
ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, string address, Uri listenUri);
ServiceEndpoint AddServiceEndpoint(Type implementedContract, Binding binding, Uri address, Uri listenUri);
ServiceHost的父类ServiceHostBase也提供了四种:
ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, string address);
ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, Uri address);
ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, string address, Uri listenUri);
ServiceEndpoint AddServiceEndpoint(string implementedContract, Binding binding, Uri address, Uri listenUri);
其中参数implementedContract为Contract的完全名称,即名称空间.类名。
item)
ServiceHost.Description是一个ServiceDescription 类型的对象。
ServiceDescription 是一个Service在内存中的一个完整的描述,包括服务的所有Endpoint,和每个Endpoint的各自的address、binding、contract和behaviors。
使用此方法先要根据Endpoint的ABC构造一个ServiceEndpoint 对象。
ServiceEndpoint(ContractDescription contract, Binding binding, EndpointAddress address)
其中ContractDescription这样通过ContractDescription的静态方法GetContract构造:
ContractDescription.GetContract(Type contractType);
1.4.视需要给ServiceHost添加behavior
ServiceHost.Behaviors是一个IServiceBehavior类型的对象集合。
IserviceBehavior 提供了一个在整个服务范围内修改或则插入定制扩展的机制。
如果需要把服务通过WSDL对外暴露对服务的Metadata描述,就需要加一个ServiceMetadataBehavior类型的Behavior:
要发布Metadata,ServiceHost必须有一个http的baseAddress,所以在构造ServiceHost实例时,就需要在构造方法中加入这个http的baseAddress,这个http的baseAddress就是对外发布的Metadata地址。
1.5.打开ServiceHost,开始提供服务
ServiceHost构建好了,添加了需要的Endpoint、behavior后,使用ServiceHost.Open()方法开发ServiceHost实例,开始对外提供服务。
2、客户端
2.1.引用service
客户端要访问服务端的服务,首先要知道服务端的服务提供了什么方法,就是要知道服务的Contract。
如何取得服务端的Contract有几种方法
直接把服务端的Contract的副本拷贝到客户端这个方法是最原始的一种方法,这样保证了服务端跟客户端使用同一份Contract。
但是,这个方法不值得提倡,因为双方的Contract是同一个来源,但是毕竟是两个独立的物理存在,它们之间只能人为的来保证其一致性。
使用Svcutil.exe工具获得服务端Contract并生
成本地服务代理类
大家知道,web service是通过WSDL对外提供服务的描述,以便客户端能够通过wsdl 知道这个web service所包含的方法、方法的签名等等信息,客户端通过wsdl就能知道怎么去调用这个web service。
到了WCF时代,微软依然采用WSDL来提供对WCF服务的描述。
前面服务端给ServiceHost添加了一个ServiceMetadataBehavior类型的Behavior,目的就是让服务端对外提供WSDL形式的服务Metadata描述。
微软提供了Svcutil.exe工具用来通过WSDL生成客户端Contract和代理功能:
httpbaseAddress 就是服务端设置的http的baseAddress。
当然前提是服务端在ServiceHost.Behaviors添加一个ServiceMetadataBehavior类型的Behavior,并设置HttpGetEnabled属性为true,允许对外暴露服务端Metadata描述
运行Svcutil.exe后,生成两个文件,一个是WCF配置文件,一个是包含了服务端Contract和对应于服务端service的本地代理类的cs文件。
生成的cs文件有下面的规律:
●引用服务端的服务所涉及的Contract
(Interface类型)基本都原样引用到客户端
(可能会自动给Contract添加一些
Attribute)。
●服务端的Endpoint到了客户端,每个具有不
同Contract的Endpoint都会在客户端生成一
个代理类。
Contract相同,binding不同的
Endpoint使用同一个客户端代理类。
在客户端项目中添加Service reference 在vs2005中安装了WCF的extention后,在项目的References上点击右键,会多出来一个“Add Service Reference”的选项,这就是用来引用WCF服务的,引用地址就是服务端设置的http的baseAddress。
在这里引用WCF服务,跟使用Svcutil.exe命令一样,会在项目中生成同样的两个文件。
2.2.生成客户端service代理实例
引用服务后,客户端生成了配置文件和包含了Contract和本地代理类的cs文件,这里我们完全不使用配置文件,所以把生成的配置文件从项目中排除。
使用ChannelFactory Generic 使用ChannelFactory Generic类的CreateChannel静态方法CreateChannel,返回一个客户端代理。
static TChannel CreateChannel(Binding binding, EndpointAddress endpointAddress);
这个方法包含了一个Endpoint的ABC三个主要元素:
Address –new EndpointAddress("")是地址。
Bingding –new BasicHttpBinding() 是绑定。
Contract -- localhost. IService是引用服务后在在客户端生成的来自服务端的Contract(interface类型)。
直接使用引用服务后形成的本地代理类上面使用ChannelFactory的CreateChannel静态方法建立代理只使用到了引用WCF服务后在客户端生成的Contract,同时前面也说过,引用WCF服务后,还会在同时给每个Contract不同的Endpoint生成一个继承自
客户端可以直接使用多个重载的代理类构造方法实例化这些代理类。
如果不使用配置文件,使用这个构造方法:
SecondServiceClient(Binding binding, EndpointAddress remoteAddress)
其中SecondServiceClient为本地的一个代理类。
实例化一个代理类的代码是这样的:
同样,实例化的proxy也包含了一个Endpoint的ABC三个主要元素:
Address –new EndpointAddress("")是地址。
Bingding –new BasicHttpBinding() 是绑定。
Contract –localhost.ServiceClient本身就是继承自某一个Contract的
2.3.使用代理实例的方法
有了WCF的本地代理类实例,就可以使用服务提供的方法了。