WCF系列一完全不使用配置文件构建和使用WCF服务-

发布时间:   来源:文档文库   
字号:
文档收集于互联网,已重新整理排版.word版本可编辑,有帮助欢迎下载支持. 只使用代码而不用配置文件的情况不适合IIS为宿主的情况,IIS宿主必须使用配置文件配置WCFServiceHost
1 服务端
1.1. 准备Contract和实现Contract的服务
很简单的一个ContractInterface)和实现这个Contract(实现这个接口的类)的服务。
这是VS2005中使用add new item,选WCF Service后自动生成的一个模板例子服务代码。
[ServiceContract(] public interface IService {
[OperationContract]
string MyOperation1(string myValue; }
public class Service : IService {
public string MyOperation1(string myValue {
return "Hello: " + myValue; } }
1.2. 建立ServiceHost
一般使用public ServiceHost(Type serviceType, params Uri[] baseAddresses构造方法建立ServicesHost
参数:
1文档来源为:从网络收集整理.word版本可编辑.
文档收集于互联网,已重新整理排版.word版本可编辑,有帮助欢迎下载支持. Type serviceType -- 为实现了某些Contract的类的类型,为这个服务主机要host服务。
params Uri[] baseAddresses -- 为任意数量的baseAddress Uri baseAddress = new Uri(""; //Instantiate new ServiceHost
myServiceHost = new ServiceHost(typeof(Service, baseAddress;
一个ServiceHost内只能驻留一个Service类,但是这个Service类可以实现多个Contract,每个Contract都能通过一个或多个(不同的bindEndpoint向客户端暴露。
进程、应用程序域和ServiceHost
Dotnet出现之前,资源的分配是以进程为单位,进程是应用程序的安全边界,进程之间不能直接访问,一个进程的崩溃也不会直接影响到别的进程。
但是,进程有个缺点,为了维护进城的安全上下文,耗费的资源很大。
后来引入了线程,一个进程中可以包含多个线程,同一进程里的线程共享资源、切换方便,但是线程不具有隔离性,一个线程的崩溃将会影响到其他线程。
Dotnet引入了应用程序域,是介于进程和线程之间的逻辑概念,它既有进程的安全隔离性的优点,又有线程轻巧快捷的特性。应用程序域跟进程一样,一个应用程序域不能直接访问另一个应用程序域的资源,一个应用程序域的崩溃也不会影响其他应用程序域。同时应用程序域占用的资源比进程少的多,应用程序直接的切换也很快捷。
一个进程中可以包含多个应用程序域,一个应用程序域内有可以包含多个线程。 所有的win可执行文件exedll等等)的开头都是一个被称作(Portable Executable结构,dotnet的可执行文件同样也是用了这个PE(结构同以前的兼容,只是增加了些内容),下面是dotnetPE主要包含的信息:
运行这个可执行文件要求的最低CLR版本号 是否使用了强名称 程序的入口地址
1文档来源为:从网络收集整理.word版本可编辑.
文档收集于互联网,已重新整理排版.word版本可编辑,有帮助欢迎下载支持. 可执行文件的元数据(metadata
简单的dotnetexe可执行文件的载入过程:
windows程序载入器(os loader读取exe文件的PE头,获取入口地址,exe入口地址其实是个跳转指令指向mscoree.dll中的_corexemain函数。
_corexemain函数实际上是个入口程序,一般被称作shim(填隙物)。由这个入口程序来决定使用哪个类型的CLR(服务器类型或工作站类型),和什么版本的CLR来运行这exe
确定了使用哪个CLR后,动态载入这个CLR,把控制权交给CLR
CLR拿到控制权后,首先创建一个工作进程,以便在进程内创建应用程序域。 CLR创建工作进程后,首先会创建一个缺省应用程序域,这个缺省应用程序域一般不用来加载用户代码。之后,开始在在新的应用程序域中加载用户代码,并运行。
具体到承载WCFconsole应用,是个dotnetexe程序,运行后被CLR加载到一个应用程序域后,ServiceHost就在这个应用程序内运行,如下图:
在一个Application Domain中可以实例化多个 ServiceHost 实例,但每个应用程序域内只有一个 ServiceHost 实例更便于操作。您可以在一个宿主内使用多个端点公开多个服务接口。
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;
1文档来源为:从网络收集整理.word版本可编辑.
文档收集于互联网,已重新整理排版.word版本可编辑,有帮助欢迎下载支持. 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;
其中参数implementedContractContract的完全名称,即名称空间.类名。 myServiceHost.AddServiceEndpoint(typeof(WCFService.IService, new BasicHttpBinding(, "";

item ServiceHost.Description 是一个 ServiceDescription 类型的对象。
ServiceDescription 是一个Service在内存中的一个完整的描述,包括服务的所有Endpoint,和每个Endpoint的各自的addressbindingcontractbehaviors

使用此方法先要根据EndpointABC构造一个ServiceEndpoint 对象。
ServiceEndpoint(ContractDescription contract, Binding binding, EndpointAddress address
1文档来源为:从网络收集整理.word版本可编辑.
文档收集于互联网,已重新整理排版.word版本可编辑,有帮助欢迎下载支持. 其中ContractDescription这样通过ContractDescription的静态方法GetContract
ContractDescription.GetContract(Type contractType; ServiceEndpoint myServiceEndpoint = new
ServiceEndpoint(ContractDescription.GetContract(typeof(WCFService.IService, new BasicHttpBinding(, new EndpointAddress(baseAddress; ;
1.4. 视需要给ServiceHost添加behavior
ServiceHost. Behaviors是一个 IServiceBehavior类型的对象集合。
IserviceBehavior 提供了一个在整个服务范围内修改或则插入定制扩展的机制。 如果需要把服务通过WSDL对外暴露对服务的Metadata描述,就需要加一个ServiceMetadataBehavior类型的Behavior
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(; behavior.HttpGetEnabled = true; behavior.HttpGetUrl = new Uri(""; ; // myServiceHostServiceHost实例
要发布MetadataServiceHost必须有一个httpbaseAddress,所以在构造ServiceHost实例时,就需要在构造方法中加入这个httpbaseAddress,这个httpbaseAddress就是对外发布的Metadata地址。
1.5. 打开ServiceHost,开始提供服务
ServiceHost构建好了,添加了需要的Endpointbehavior后,使用ServiceHost.Open(方法开发ServiceHost实例,开始对外提供服务。
2 客户端 2.1. 引用service
客户端要访问服务端的服务,首先要知道服务端的服务提供了什么方法,就是要知道服务的Contract。如何取得服务端的Contract有几种方法
1文档来源为:从网络收集整理.word版本可编辑.
文档收集于互联网,已重新整理排版.word版本可编辑,有帮助欢迎下载支持. 直接把服务端的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和代理功能: Svcutil.exe httpbaseAddress
httpbaseAddress 就是服务端设置的httpbaseAddress。当然前提是服务端在ServiceHost. Behaviors加一个ServiceMetadataBehavior类型的Behavior,并设置HttpGetEnabled属性为true,允许对外暴露服务端Metadata描述
运行Svcutil.exe后,生成两个文件,一个是WCF配置文件,一个是包含了服务端Contract和对应于服务端service的本地代理类的cs文件。
生成的cs文件有下面的规律:
引用服务端的服务所涉及的ContractInterface类型)基本都原样引用到客户端(可能会自动给Contract添加一些Attribute)。
服务端的Endpoint到了客户端,每个具有不ContractEndpoint都会在客户端生成一1文档来源为:从网络收集整理.word版本可编辑.
文档收集于互联网,已重新整理排版.word版本可编辑,有帮助欢迎下载支持. 个代理类。Contract相同,binding不同的Endpoint使用同一个客户端代理类。
在客户端项目中添加
Service reference vs2005中安装了WCFextention后,在项目的References上点击右键,会多出来一个“Add Service Reference”的选项,这就是用来引用WCF服务的,引用地址就服务端设置的httpbaseAddress
在这里引用WCF服务,跟使用Svcutil.exe命令一样,会在项目中生成同样的两个文件。
2.2. 生成客户端service代理实例
引用服务后,客户端生成了配置文件和包含了Contract和本地代理类的cs文件,这里我们完全不使用配置文件,所以把生成的配置文件从项目中排除。
使用
ChannelFactory Generic 使用ChannelFactory Generic类的CreateChannel静态方法CreateChannel,返回一个客户端代理。
static TChannel CreateChannel(Binding binding, EndpointAddress endpointAddress;
localhost.IService proxy = ChannelFactoryIService>.CreateChannel(new BasicHttpBinding(, new EndpointAddress("";
这个方法包含了一个EndpointABC三个主要元素: Address new EndpointAddress(""是地址。 Bingding new BasicHttpBinding( 是绑定。
Contract -- localhost. IService是引用服务后在在客户端生成的来自服务端的Contractinterface类型)。
直接使用引用服务后形成的本地代理类
上面使用ChannelFactoryCreateChannel静态方法建立代理只使用到了引用WCF务后在客户端生成的Contract,同时前面也说过,引用WCF服务后,还会在同时给每个Contract不同的Endpoint生成一个继承自
1文档来源为:从网络收集整理.word版本可编辑.
文档收集于互联网,已重新整理排版.word版本可编辑,有帮助欢迎下载支持. 客户端可以直接使用多个重载的代理类构造方法实例化这些代理类。如果不使用配置文件,使用这个构造方法:
SecondServiceClient(Binding binding, EndpointAddress remoteAddress 其中SecondServiceClient为本地的一个代理类。实例化一个代理类的代码是这样的: localhost.ServiceClient proxy = new localhost.ServiceClient(new BasicHttpBinding(, new EndpointAddress("";
同样,实例化的proxy也包含了一个EndpointABC三个主要元素: Address new EndpointAddress(""是地址。 Bingding new BasicHttpBinding( 是绑定。
Contract localhost.ServiceClient本身就是继承自某一个Contract
2.3. 使用代理实例的方法
有了WCF的本地代理类实例,就可以使用服务提供的方法了。 string result = proxy.MyOperation1("myFirstWCF";
1文档来源为:从网络收集整理.word版本可编辑.

本文来源:https://www.2haoxitong.net/k/doc/0153477382d049649b6648d7c1c708a1294a0a68.html

《WCF系列一完全不使用配置文件构建和使用WCF服务-.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式