您的位置:知识库 » .NET技术

[原创]谈谈WCF中的Data Contract (1):Data Contract Overview

作者: Artech  来源: 博客园  发布时间: 2008-08-14 10:03  阅读: 4197 次  推荐: 1   原文链接   [收藏]  
摘要:在我们看来,Service Orientation提供了一种对业务、功能进行分解的方式。
[1] [原创]谈谈WCF中的Data Contract (1):Data Contract Overview
[2] [原创]谈谈WCF中的Data Contract (1):Data Contract Overview
[3] [原创]谈谈WCF中的Data Contract (1):Data Contract Overview
Contract in WCF 

  上面我们实际上是在一个厂商中立的前提下探讨Contract,这里的Contract和具体的平台和技术无关。接下来我们要谈的是基于技术的话题:讨论一下WCF下的Contract。简单地说,WCF中的Contract主要的功能就是如何将一个基于.NETCLR TypeInterface或者Class,转化成一个我们上面提到的Neutral Contract。比如,如果我们在一个Interface和它的成员上分别运用Service Contract AttributeOperation Contract,当我们Host实现了该InterfaceService的时候,WCF就能将在一个.NET-specificCLR Type暴露成一个Neutral Service Contract。同理对于一个,我们通过在一个Class和它的成员上分别添加DataContractAttributeDataMemberAttribute,就可以就该CLR Type转变成Neutral Data Contract

比如我们一个运用了DataContractAttributeDataMemberAttributeOrder class

namespace Artech.DataContractVersioning.Service
{
    [DataContract(Namespace
="http://artech.datacontractversioning")]
    
public class Order 
    
{
        [DataMember(Order 
= 0)]
        
public Guid OrderID
        
{get;set;}

        [DataMember(Order 
= 1)]
        
public DateTime OrderDate
        
getset; }

        [DataMember(Order 
= 2)]
        
public Guid SupplierID
        
getset; }
    }

}

就可以转变成另一种厂商中立的、以XSD表示的Neutral Data Contract

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" targetNamespace="http://artech.datacontractversioning"
    xmlns:xs
="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://artech.datacontractversioning"
    xmlns:ser
="http://schemas.microsoft.com/2003/10/Serialization/">
<xs:import schemaLocation="http://artech/Artech.DataContractVersioning/OrderManagerService.svc?xsd=xsd1"
    namespace
="http://schemas.microsoft.com/2003/10/Serialization/" />
<xs:complexType name="Order">
    
<xs:sequence>
        
<xs:element minOccurs="0" name="OrderID" type="ser:guid" />
        
<xs:element minOccurs="0" name="OrderDate" type="xs:dateTime" />
        
<xs:element minOccurs="0" name="SupplierID" type="ser:guid" />
    
</xs:sequence>
</xs:complexType><xs:element name="Order" nillable="true" type="tns:Order"/></xs:schema>

 

  当Client需要调用该Order typeService的时候,在本地需要一个Data Type能够匹配上面的以XSD体现的Data Contract。一般地,我们可以在VS中通过Add Service Reference的方式或者通过一些Tools,比如XSDUtilSvcUtil来生成这样的Class。比如我们通过Add Service Reference方式,就可以生成下面一个对应的Order class:

 

[System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute(
"System.Runtime.Serialization""3.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name
="Order", Namespace="http://
artech.datacontractversioning
")]
    [System.SerializableAttribute()]
    
public partial class Order : object, System.Runtime.Serialization.IExtensibleDataObject,
System.ComponentModel.INotifyPropertyChanged 
{
        
        [System.NonSerializedAttribute()]
        
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
        
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        
private System.Guid OrderIDField;
        
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        
private System.DateTime OrderDateField;
        
        [System.Runtime.Serialization.OptionalFieldAttribute()]
        
private System.Guid SupplierIDField;
        
        [global::System.ComponentModel.BrowsableAttribute(
false)]
        
public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
            
get {
                
return this.extensionDataField;
            }

            
set {
                
this.extensionDataField = value;
            }

        }

        
        [System.Runtime.Serialization.DataMemberAttribute()]
        
public System.Guid OrderID {
            
get {
                
return this.OrderIDField;
            }

            
set {
                
if ((this.OrderIDField.Equals(value) != true)) {
                    
this.OrderIDField = value;
                    
this.RaisePropertyChanged("OrderID");
                }

            }

        }

        
        [System.Runtime.Serialization.DataMemberAttribute(Order
=1)]
        
public System.DateTime OrderDate {
            
get {
                
return this.OrderDateField;
            }

            
set {
                
if ((this.OrderDateField.Equals(value) != true)) {
                    
this.OrderDateField = value;
                    
this.RaisePropertyChanged("OrderDate");
                }

            }

        }

        
        [System.Runtime.Serialization.DataMemberAttribute(Order
=2)]
        
public System.Guid SupplierID {
            
get {
                
return this.SupplierIDField;
            }

            
set {
                
if ((this.SupplierIDField.Equals(value) != true)) {
                    
this.SupplierIDField = value;
                    
this.RaisePropertyChanged("SupplierID");
                }

            }

        }

        
        
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        
        
protected void RaisePropertyChanged(string propertyName) {
            System.ComponentModel.PropertyChangedEventHandler propertyChanged 
= this.
PropertyChanged;
            
if ((propertyChanged != null)) {
                propertyChanged(
thisnew System.ComponentModel.PropertyChangedEventArgs
(propertyName));
            }

        }

    }

 

  通过上面这样一个在Client自动生成的Order class,你就可以创建Order对象来调用相应的Service了。这种自动生成代码的方式确实很省事,而且当Service端的Data Contract改变的时候,你只需要Update Service Reference就可以重新生成并覆盖现有的代码。但是,就我个人来说,我不要喜欢使用这样的方式,如果对Service暴露出来的数据结构很熟悉的话,我宁愿自己编写这样的class。特别地,对于WCF-WCFClientService都是WCF),如果可能的话,让定义ContractAssemblyServicecontract共享,我想是最直接的方式。

上面我们说所说的都是根据Service暴露出来的、以厂商中立方式体现的(比如XSDClient端生成或者自行创建与之相对的Data type。但是对于下面这样的场景,重建Data Type却不是一个好的选择:Client现在已经有一个Order class,而且很多的业务逻辑均依赖于这个class,现在需要调用一个现有的Order Processing ServiceOrder作某种处理,但是Service Order Type,说得更准确地,Service暴露出来的Order Data ContractClient现有的Order class不太一致,很显然在这种情况下,Client端部可能使用本地Order对象来调用该Service,因为Client提供的数据不符合该Data Contract,如果想上面讲到了重新生成或者创建一个新的Order class,就意味着其他依赖于现有Order class的业务逻辑均会受其影响。所以,在这里,我们需要WCF Data Contract提供给我们的另一种功能——适配功能:通过现有的CLR Type上添加或者改变DataContractAttribute 或者DataMemberAttribute的参数来使现有的CLR Type符合一个既定的Data Contract。究其本质,无论将CLR Type暴露成一个Neutral Contract也好,将CLR Type与既定的Neutral Contract进行适配也罢,这两种功能都是等效的。

  接下来,我们就根据一个例子来讨论WCF Data Contract如何将一个现有的CLR Type与一个既定的Neutral Data Contract匹配。

1
1
标签:WCF

.NET技术热门文章

    .NET技术最新文章

      最新新闻

        热门新闻