您的位置:首页 > 其它

WCF从理论到实践(17):OO大背离(带视频+ppt+源码)

2008-04-27 10:26 344 查看

如果您懒得看下面的文字,您按下面的提示下载视频教程,里面还有ppt和源代码

请您到:http://downloads.cnblogs.com/jillzhang/wcf17.rar 下载视频+课件+源码,多谢dudu提供了这么好的交流空间。上篇文章中,大家提了好多好的建议,本次视频文件大小已经大大减小,而且将pptx转换成了ppt,多谢兄弟们的支持和帮助。以后想从事培训,有此方面门路的兄弟如果能推荐一下,更是不胜感激。

概述

上文说到了WCF和传统面向对象编程中不太一致的地方之一:操作重载(Operation Overload),本文讲述WCF 另外一个不太符合OO之处:服务契约和数据契约的继承关系。在面向对象的大原则中有下面两个原则

1) 依赖倒置原则

2) Liskov替换原则

依赖倒置原则强调的是实现依赖于抽象,抽象不依赖于实现 ,而Liskov原则强调的是子类必须可以替换其基类,这在anytao大作<<你必须知道的.Net>>中都有详细的阐述。本文无意阐述这两个原则的细节,想了解OO原则的知识,可以阅读王兄的大作。本文只探讨WCF架构下对这两个原则的辩证统一关系。

WCF架构的特征

在弄清楚WCF在上两个OO原则矛盾统一的关系之前,我想有必要先了解WCF的架构,清楚了WCF架构之后,才能更清楚地明白为何WCF中对上述原则的辩证关系!我们先来看下WCF 通讯的工作原理

[ServiceContract]

public interface IMp3

IRecorder.cs

[ServiceContract]

public interface IRecorder

ITelephone.cs

[ServiceContract]

public interface ITelephone:IMp3,IRecorder

接下来,我们实现服务的实现部分,我们在服务实现中,只需要实现一个Telephoe便可以完成契约中全部的功能列表了

Telephone.cs

using log = System.Console;

public class Telephone:Contracts.ITelephone

此时我们先来看一下服务端服务契约的层级关系图:

Uri baseAddress = new Uri("net.tcp://127.0.0.1:1236");

ServiceHost host = new ServiceHost(typeof(Services.Telephone), baseAddress);

host.AddServiceEndpoint(typeof(Contracts.IMp3), new NetTcpBinding(),"mp3");

host.AddServiceEndpoint(typeof(Contracts.IRecorder), new NetTcpBinding(), "recorder");

host.AddServiceEndpoint(typeof(Contracts.ITelephone), new NetTcpBinding(), "tel");

ServiceMetadataBehavior metaBehavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();

if (metaBehavior == null)

BindingElement bindingElement = new TcpTransportBindingElement();

CustomBinding metaBind = new CustomBinding(bindingElement);

host.AddServiceEndpoint(typeof(IMetadataExchange), metaBind, "MEX");

host.Open();

Console.WriteLine("service is running

Console.Read();

host.Close();

用Svcutil.exe生成代理文件Proxy.cs,打开它,我们会发现如下的代码:

//------------------------------------------------------------------------------

// <auto-generated>

// 此代码由工具生成。

// 运行库版本:2.0.50727.1433

//

// 对此文件的更改可能会导致不正确的行为,并且如果

// 重新生成代码,这些更改将会丢失。

// </auto-generated>

//------------------------------------------------------------------------------

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

[System.ServiceModel.ServiceContractAttribute(ConfigurationName="IMp3")]

public interface IMp3

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

public interface IMp3Channel : IMp3, System.ServiceModel.IClientChannel

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

public partial class Mp3Client : System.ServiceModel.ClientBase<IMp3>, IMp3

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

[System.ServiceModel.ServiceContractAttribute(ConfigurationName="IRecorder")]

public interface IRecorder

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

public interface IRecorderChannel : IRecorder, System.ServiceModel.IClientChannel

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

public partial class RecorderClient : System.ServiceModel.ClientBase<IRecorder>, IRecorder

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

[System.ServiceModel.ServiceContractAttribute(ConfigurationName="ITelephone")]

public interface ITelephone

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

public interface ITelephoneChannel : ITelephone, System.ServiceModel.IClientChannel

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

public partial class TelephoneClient : System.ServiceModel.ClientBase<ITelephone>, ITelephone

从上面的代码中可以看出客户端代理的服务契约的层级关系如下:

[DataContract]

public class Order

和使用该协定的服务契约IOrderManager.cs

[ServiceContract]

public interface IOrderManager

using log = System.Console;

public class OrderManager:IOrderManager

此时,进行托管和生成代理类,代理类代码如下:

//------------------------------------------------------------------------------

// <auto-generated>

// 此代码由工具生成。

// 运行库版本:2.0.50727.1433

//

// 对此文件的更改可能会导致不正确的行为,并且如果

// 重新生成代码,这些更改将会丢失。

// </auto-generated>

//------------------------------------------------------------------------------

namespace Contracts

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

[System.ServiceModel.ServiceContractAttribute(ConfigurationName="IOrderManager")]

public interface IOrderManager

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

public interface IOrderManagerChannel : IOrderManager, System.ServiceModel.IClientChannel

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]

public partial class OrderManagerClient : System.ServiceModel.ClientBase<IOrderManager>, IOrderManager

此时在客户端增加一个OrderDetail类,使其继承Order,代码为:

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]

[System.Runtime.Serialization.DataContractAttribute(Name = "OrderDetail", Namespace = "http://schemas.datacontract.org/2004/07/Contracts")]

public partial class OrderDetail : Order, System.Runtime.Serialization.IExtensibleDataObject

IOrderManager orderService = new OrderManagerClient(new NetTcpBinding(), new EndpointAddress("net.tcp://127.0.0.1:1237/order"));

Contracts.Order order = new Contracts.Order();

orderService.Process(order);

Contracts.OrderDetail orderDetail = new Contracts.OrderDetail();

orderService.Process(orderDetail);

执行的时候,便会在代码orderService.Process(orderDetail);发生如下的异常:



由此可见,Liskov原则在WCF程序的服务端与客户端之间是不适用的,原因在上图的异常说明中已经描述的很清楚了。当然如果非要保持这种继承关系,WCF也提供了相应的机制。但只是一种变相的策略,却不是从根本上要校正此类问题。

小结

在面向对象中的依赖倒置和Liskov原则都是有边界限制的,针对WCF来讲,服务端所设定的契约关系层次和数据的继承关系不能强制的适用于客户端,这充分体现了面向服务的松散耦合的特征,虽然有悖于OO的设计原则,但也恰恰体现了面向服务的优点,且这种做法更适应变化。



视频,课件以及源码下载

请您到:http://downloads.cnblogs.com/jillzhang/wcf17.rar 下载视频+课件+源码,多谢dudu提供了这么好的交流空间。上篇文章中,大家提了好多好的建议,本次视频文件大小已经大大减小,而且将pptx转换成了ppt,多谢兄弟们的支持和帮助。以后想从事培训,有此方面门路的兄弟如果能推荐一下,更是不胜感激。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: