心海巨澜

天行键,君子以自强不息;地势坤,君子以厚德载物!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

      上一章我们介绍了契约设计中的明确契约(ExplicitContract),这一章我们介绍:已知类型契约(KnownTypesContract)。

      已知类型契约(KnownTypesContract)允许在服务契约中使用多态的行为;在服务操作中暴露基本类型,将已知类型(known types)相关到:基本类型(基类类型)自身、特定操作、整个服务契约;采用属性声明或者配置的方式来实现。

      开发环境:Visual Studio 2010 + Net Framework 4.0 。

      下面通过代码来演示已知类型契约(此项目建立在WCF面向服务应用程序系列之二:契约设计(ExplicitContract)中的解决方案中):

      1、新增一个WCF Service Library程序,修改项目名称为KnownTypesContract,删除自动添加的文件。

      2、新建Item.cs类,代码如下:

代码
[DataContract(Namespace = "http://schemas.xinhaijulan.com/demos/KnownTypesContract")]
[KnownType(
typeof(ItemCreate))]
//[KnownType(typeof(ItemModify))]
public class Item
{
[DataMember(Name
= "IdContract", IsRequired = true, Order = 0)]
public int Id { get; set; }

[DataMember(Name
= "NameContract", IsRequired = true, Order = 1)]
public string Name { get; set; }

[DataMember(Name
= "MessageContract", IsRequired = true, Order = 2)]
public string Message { get; set; }

[DataMember(Name
= "ItemCategoriesContract", IsRequired = true, Order = 3)]
public virtual ItemCategories ItemCategories { get; set; }
}

       3、新建枚举ItemCategories.cs,代码如下:

[DataContract(Namespace = "http://schemas.xinhaijulan.com/demos/KnownTypesContract")]
public enum ItemCategories
{
[EnumMember]
None
= 0,
[EnumMember]
Create
= 1,
[EnumMember]
Modify
= 2,
[EnumMember]
Delete
= 3
}

      4、新建ItemCreate.cs类,代码如下:

代码
[DataContract(Namespace = "http://schemas.xinhaijulan.com/demos/KnownTypesContract")]
public class ItemCreate : Item
{
public ItemCreate()
{
}

[DataMember(Name
= "ItemCategoriesContract", IsRequired = true, Order = 3)]
public override ItemCategories ItemCategories
{
get { return ItemCategories.Create; }
}
}

      5、新建ItemModify.cs类,代码如下:

代码
[DataContract(Namespace = "http://schemas.xinhaijulan.com/demos/KnownTypesContract")]
public class ItemModify : Item
{
public ItemModify()
{
}

[DataMember(Name
= "ItemCategoriesContract", IsRequired = true, Order = 3)]
public override ItemCategories ItemCategories
{
get { return ItemCategories.Modify; }
}
}

      6、新建WCF接口文件IKnownTypesService.cs,代码如下:

[ServiceContract(Name = "KnownTypesContract", Namespace = "http://schemas.xinhaijulan.com/demos/KnownTypesContract")]
public interface IKnownTypesService
{
[OperationContract(Name
= "SaveItemContract")]
[ServiceKnownType(
typeof(ItemCreate))]
void SaveItem(Item item);

[OperationContract(Name
= "GetItemContract")]
[ServiceKnownType(
typeof(ItemCreate))]
Item GetItem();

[OperationContract(Name
= "SaveItemModifyContract")]
//[ServiceKnownType(typeof(ItemModify))]
void SaveItemModify(Item item);

[OperationContract(Name
= "GetItemModifyContract")]
//[ServiceKnownType(typeof(ItemModify))]
Item GetItemModify();
}

      注意:上述方法SaveItem和GetItem被标记了ServiceKnowType属性,而SaveItemModify和GetItemModify没有被标记为ServiceKnowType属性,只有被标记了ServiceKnowType类型的Item的继承类才能在客户端展示和被调用,否则,继承这种多态特点在客户端将不起作用。在此例中,ItemCreate将在客户端显示和被调用,ItemModify由于没有被标记为ServiceKnowType,则不可以在客户端显示和被调用。

      7、创建KnownTypesService.cs类,代码如下:

代码
public class KnownTypesService : IKnownTypesService
{
private Item _item;
public void SaveItem(Item item)
{
this._item = item;
}

public Item GetItem()
{
this._item.Message = "IExplicitService.GetItem() invoked.";
return this._item;
}

public void SaveItemModify(Item item)
{
this._item = item;
}

public Item GetItemModify()
{
this._item.Message = "IExplicitService.GetItemModify() invoked.";
return this._item;
}
}

      8、修改App.config中的服务名称 、端点契约、服务地址,代码如下:

代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="KnownTypesContract.KnownTypesService">
<endpoint address="" binding="wsHttpBinding" contract="KnownTypesContract.IKnownTypesService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/KnownTypesContract/KnownTypesService/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information
-->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

</configuration>

      9、在客户端控制台程序Client中,添加Service Reference,修改名称空间为KnownTypesService,并添加测试TestKnownTypesContract方法,代码如下:

代码
private static void TestKnownTypesContract()
{
Console.WriteLine(
"-----------------Test KnownTypesContract Begin-----------------");
KnownTypesContract.KnownTypesContractClient client
= new KnownTypesContract.KnownTypesContractClient();

KnownTypesContract.Item item
= new KnownTypesContract.ItemCreate();

client.SaveItemContract(item);
item
= client.GetItemContract();

Console.WriteLine(
"Get from server item.ItemCategoriesContract is : {0}", item.ItemCategoriesContract.ToString());

//item = new KnownTypesContract.ItemModify();

//client.SaveItemModifyContract(item);
//item = client.GetItemModifyContract();

//Console.WriteLine("Get from server item.ItemCategoriesContract is : {0}", item.ItemCategoriesContract.ToString());

Console.WriteLine(
"-----------------Test KnownTypesContract End-----------------");
}

      注意:因ItemModify没有补标记为ServiceKnowType,则在客户端找不到此类,若要显示并调用此类,则需要在接口文件中添加ServiceKnowType标记。

      细心的读者也许观察到Item.cs这个类中有一行注释:://[KnownType(typeof(ItemModify))],是的,这也是打开多态的开关。

 

      总结,在已知类型契约中:1、通过基类添加KnowType标记实现多态;2、通过接口文件方法中添加ServiceKnowType标记实现多态。

      至此,WCF契约设计—KnownTypesContract介绍完毕,下一章将介绍WCF契约设计(MessageContract)

      Demo下载将在契约设计介绍全部完成时提供。请到【契约设计(MessageContract)】下载DEMO。

 

作者:心海巨澜
出处:http:
//xinhaijulan.cnblogs.com
版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

posted on 2010-10-07 13:45  心海巨澜  阅读(3305)  评论(1编辑  收藏  举报