您的位置:首页 > 其它

WCF 开发学习笔记

2012-05-24 17:27 597 查看
概述

Windows Communication Foundation (WCF) 是.NET Framework 的扩展,用来创建互连的系统。WCF 提供了创建安全的、可靠的、事务服务的统一框架,WCF 整合和扩展了现有分布式系统的开发技术,如Microsoft .Net Remoting、Web Services、Web Services Enhancements (WSE)等等,来开发统一的可靠系统。WCF 框架可以实现SOA架构的松散耦合的应用程序,WCF 简化了构建SOA架构应用的工作,同时通过统一Enterprise Services、Messaging、.Net Remoting、Web Services、WSE 等技术,降低开发复杂度。WCF服务可以通过属性Attribute进行配置,提高灵活性和效率,支持大量的Web Services标准,如XML、XSD、SOAP、Xpath、WSDL等标准和规范,如WS-Addressing、WS-Policy、WS- Security、WS-Trust、WS-Secure、WS-Reliable Messaging、WS-Atomic Transaction、WS-Coordination等等。

Windows communication Foundation (WCF) 框架模型





 

WCF组成结构





 

Service Class:一个标记了[ServiceContract]属性的类,在其中可能包含多个方法。除了标记了一些WCF 特有的Attribute 外,这个类与一般的类没有什么区别。
Host(宿主):可以是应用程序,进程如Windows Service 等,它是WCF Service 运行环境。
Endpoints:可以是一个,也可以是一组,它是WCF 实现通信的核心要素。

在后面的实例应用中,我还会提到上面这三个概念。

(1)绑定:指定该端点如何与外界通信,也就是为端点指定通信协议。

传输协议:端点和客户端通过传输协议通信。比较常用的是HTTP和TCP。
编码协议:在进入通信链路之前,端点和客户通过编码协议对通信进行编码。比较常见的是XML文件二进制码。
安全协议:端点和用户通过安全协议保证通信的安全。比如一些敏感的信息,要求通过加密的传输信道。比较常见的是HTTPS和WS-Security。

 

(2)地址:一个端点地址指定端点的位置,如果通过端点与WCF通信,必须把通信指定到网络地址。

(3)契约:一个端点上契约指定通过该端点的用户能访问到WCF服务的什么操作。

在WCF 中,类ServiceEndpoint 代表了一个端点(Endpoint),在类中包含的EndpointAddress,Binding,ContractDescription 类型分别对应端点的地址,绑定和契约。

 

WCF服务模型

最后简单的说下WCF的服务模型。

WCF是一个层次架构,该架构的顶层称为服务模型,用于WCF服务的建模。

WCF服务模型提供了3种重要手段对自己的WCF服务进行建模:

(1)面向属性编程:WCF服务模型带有一套元数据属性,可以通过属性表示相应的实体,如:属性,接口,类等。

(2)面向配置编程:WCF服务模型带有方便的配置语言,可以通过它在配置文件中进行建模。

(3)常规命令编程:WCF服务模型带有一组方便的托管类,可以使用这些托管类对服务进行建模。

 

 

示例

定义Server 接口:

using System.Collections.Generic;
using System.ServiceModel;
using Model;

[ServiceContract]
public interface IDICOMService
{
/// <summary>
/// Get patient identifier list by query condition
/// </summary>
/// <param name="patientQueryCondition"></param>
/// <returns></returns>
[OperationContract]
List<PatientIdentifier> Query(PatientQueryCondition patientQueryCondition);

/// <summary>
/// Retrieve cache relate file path list
/// </summary>
/// <param name="patientID">patientID</param>
/// <param name="studyInstanceUID">studyInstanceUID</param>
/// <param name="seriesInstanceUID">seriesInstanceUID</param>
/// <param name="sopInstanceUID">sopInstanceUID</param>
/// <returns>cache relate file path list</returns>
[OperationContract]
List<string> Retrieve(string patientID, string studyInstanceUID, string seriesInstanceUID, string sopInstanceUID);

/// <summary>
/// Retrieve file stream by cache related file path
/// </summary>
/// <param name="relatedFilePath">related file path</param>
/// <returns>file stream bytes</returns>
[OperationContract]
byte[] RetrieveFileStream(string relatedFilePath);

/// <summary>
/// Retrieve file name and file byte stream list
/// </summary>
/// <param name="patientID">patientID</param>
/// <param name="studyInstanceUID">studyInstanceUID</param>
/// <param name="seriesInstanceUID">seriesInstanceUID</param>
/// <param name="sopInstanceUID">sopInstanceUID</param>
/// <returns>file name and file byte stream list </returns>
[OperationContract]
Dictionary<string, byte[]> RetrieveFileNameAndStream(string patientID, string studyInstanceUID,
string seriesInstanceUID, string sopInstanceUID);

/// <summary>
/// Retrieve file stream by sort and paging
/// </summary>
/// <param name="patientID">patientID</param>
/// <param name="studyInstanceUID">studyInstanceUID</param>
/// <param name="seriesInstanceUID">seriesInstanceUID</param>
/// <param name="sopInstanceUID">sopInstanceUID</param>
/// <param name="page">page</param>
/// <param name="count">count</param>
/// <param name="sort">sort</param>
/// <param name="sequence">sequence</param>
/// <returns>file name and file byte stream list </returns>
[OperationContract]
Dictionary<string, byte[]> RetrieveFileStreamBySortAndPaging(string patientID, string studyInstanceUID,
string seriesInstanceUID,
string sopInstanceUID, int page, int count,
string sort, string sequence);

/// <summary>
/// Retrieve DicomFileResult entity list By Condition
/// </summary>
/// <param name="patientID">patientID</param>
/// <param name="studyInstanceUID">studyInstanceUID</param>
/// <param name="seriesInstanceUID">seriesInstanceUID</param>
/// <param name="sopInstanceUID">sopInstanceUID</param>
/// <returns>DicomFileResult entity list</returns>
[OperationContract]
List<DicomFileResult> RetrieveDicomFileResultListByCondition(string patientID, string studyInstanceUID,
string seriesInstanceUID, string sopInstanceUID);

/// <summary>
/// Retrieve DicomFileResult entity List   by sort and paging
/// </summary>
/// <param name="patientID">patientID</param>
/// <param name="studyInstanceUID">studyInstanceUID</param>
/// <param name="seriesInstanceUID">seriesInstanceUID</param>
/// <param name="sopInstanceUID">sopInstanceUID</param>
/// <param name="page">page</param>
/// <param name="count">count</param>
/// <param name="sort">sort</param>
/// <param name="sequence">sequence</param>
/// <returns>file name and file byte stream list </returns>
[OperationContract]
List<DicomFileResult> RetrieveDicomFileResultListBySortAndPaging(string patientID, string studyInstanceUID,
string seriesInstanceUID, string sopInstanceUID,
int page, int count, string sort,
string sequence);

/// <summary>
/// Retrieve Report file byte stream by encount type and activity state
/// </summary>
/// <param name="encountType">encount type</param>
/// <param name="activityState">activity state</param>
/// <returns>file byte stream</returns>
[OperationContract]
byte[] RetrieveReportFileByCondition(string encountType, string activityState);

/// <summary>
/// Add Report File By encount type and activity state and byte stream
/// </summary>
/// <param name="encountType">encount Type</param>
/// <param name="activityState">activity State</param>
/// <param name="byteStream">report file byte stream</param>
/// <returns>the result is true or false</returns>
[OperationContract]
bool AddReportFile(string encountType, string activityState, byte[] byteStream);

/// <summary>
/// Remove Report file by encount type and activity state
/// </summary>
/// <param name="encountType">encount Type</param>
/// <param name="activityState">activity State</param>
/// <returns>the result is true or false</returns>
[OperationContract]
bool RemoveReportFileByCondition(string encountType, string activityState);
}


 

 

接下来实现接口

using System.Collections.Generic;
using DAL;
using IDAL;
using Model;
using System.ServiceModel;
/// <summary>
/// Dicom Service class
/// </summary>
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class DICOMService : IDICOMService
{
#region Private Methods

#endregion

#region IDICOMService Members

/// <summary>
/// Query DICOM server by PatientQueryCondition entity
/// </summary>
/// <param name="patientQueryCondition">PatientQueryCondition entity </param>
/// <returns>Patient Identifier list</returns>
public List<PatientIdentifier> Query(PatientQueryCondition patientQueryCondition)
{
return DICOMServiceHandle.Instance.Query(patientQueryCondition);
}

/// <summary>
/// Retrieve cache relate file path list
/// </summary>
/// <param name="patientID">patientID</param>
/// <param name="studyInstanceUID">studyInstanceUID</param>
/// <param name="seriesInstanceUID">seriesInstanceUID</param>
/// <param name="sopInstanceUID">sopInstanceUID</param>
/// <returns>cache relate file path list</returns>
public List<string> Retrieve(string patientID, string studyInstanceUID, string seriesInstanceUID, string sopInstanceUID)
{
return DICOMServiceHandle.Instance.Retrieve(patientID, studyInstanceUID, seriesInstanceUID, sopInstanceUID);
}

/// <summary>
/// Retrieve file stream by cache related file path
/// </summary>
/// <param name="relatedfilePath"> cache related file path</param>
/// <returns>file stream bytes</returns>
public byte[] RetrieveFileStream(string relatedfilePath)
{
return DICOMServiceHandle.Instance.RetrieveFileStream(relatedfilePath);
}

/// <summary>
/// Retrieve file name and file byte stream List
/// </summary>
/// <param name="patientID">patientID</param>
/// <param name="studyInstanceUID">studyInstanceUID</param>
/// <param name="seriesInstanceUID">seriesInstanceUID</param>
/// <param name="sopInstanceUID">sopInstanceUID</param>
/// <returns>file name and file byte stream List</returns>
public Dictionary<string,byte[]> RetrieveFileNameAndStream(string patientID, string studyInstanceUID, string seriesInstanceUID, string sopInstanceUID)
{
return DICOMServiceHandle.Instance.RetrieveFileStream(patientID, studyInstanceUID, seriesInstanceUID,
sopInstanceUID);
}

/// <summary>
/// Retrieve DicomFileResult entity list By Condition
/// </summary>
/// <param name="patientID">patientID</param>
/// <param name="studyInstanceUID">studyInstanceUID</param>
/// <param name="seriesInstanceUID">seriesInstanceUID</param>
/// <param name="sopInstanceUID">sopInstanceUID</param>
/// <returns>DicomFileResult entity list</returns>
public List<DicomFileResult> RetrieveDicomFileResultListByCondition(string patientID, string studyInstanceUID, string seriesInstanceUID, string sopInstanceUID)
{
return DICOMServiceHandle.Instance.RetrieveDcmFileResultListByCondition(patientID, studyInstanceUID,
seriesInstanceUID, sopInstanceUID);
}

/// <summary>
/// Retrieve DicomFileResult entity List By condition
/// </summary>
/// <param name="patientID">patientID</param>
/// <param name="studyInstanceUID">studyInstanceUID</param>
/// <param name="seriesInstanceUID">seriesInstanceUID</param>
/// <param name="sopInstanceUID">sopInstanceUID</param>
/// <param name="page">page</param>
/// <param name="count">count</param>
/// <param name="sort">sort</param>
/// <param name="sequence">sequence</param>
/// <returns>DicomFileResult entity list</returns>
public List<DicomFileResult> RetrieveDicomFileResultListBySortAndPaging(string patientID, string studyInstanceUID, string seriesInstanceUID, string sopInstanceUID, int page, int count, string sort, string sequence)
{
return DICOMServiceHandle.Instance.RetrieveDcmFileResultListBySortAndPaging(patientID, studyInstanceUID,
seriesInstanceUID, sopInstanceUID,
page, count, sort, sequence);
}

/// <summary>
/// Retrieve report file stream by encount type and activity state
/// </summary>
/// <param name="encountType">encount type</param>
/// <param name="activityState">activity state</param>
/// <returns>report file byte stream</returns>
public byte[] RetrieveReportFileByCondition(string encountType, string activityState)
{
return DICOMServiceHandle.Instance.RetrieveReportFileByCondition(encountType, activityState);
}

/// <summary>
/// Add report file by encount type and activity state and byte stream
/// </summary>
/// <param name="encountType">encount type</param>
/// <param name="activityState">activity state</param>
/// <param name="byteStream">byte stream</param>
/// <returns>the result is true or false</returns>
public bool AddReportFile(string encountType, string activityState, byte[] byteStream)
{
return DICOMServiceHandle.Instance.AddReportFile(encountType, activityState, byteStream);
}

/// <summary>
/// Remove report file by encount type and activity state
/// </summary>
/// <param name="encountType">encount type</param>
/// <param name="activityState">activity state</param>
/// <returns>the result is true or false</returns>
public bool RemoveReportFileByCondition(string encountType, string activityState)
{
return DICOMServiceHandle.Instance.RemoveReportFile(encountType, activityState);
}

/// <summary>
/// Retrieve file stream by sort and paging
/// </summary>
/// <param name="patientID">patientID</param>
/// <param name="studyInstanceUID">studyInstanceUID</param>
/// <param name="seriesInstanceUID">seriesInstanceUID</param>
/// <param name="sopInstanceUID">sopInstanceUID</param>
/// <param name="page">page</param>
/// <param name="count">count</param>
/// <param name="sort">sort</param>
/// <param name="sequence">sequence</param>
/// <returns>file name and file byte stream list</returns>
public Dictionary<string, byte[]> RetrieveFileStreamBySortAndPaging(string patientID, string studyInstanceUID, string seriesInstanceUID, string sopInstanceUID, int page, int count, string sort, string sequence)
{
return DICOMServiceHandle.Instance.RetrieveFileStreamBySortAndPaging(patientID, studyInstanceUID,
seriesInstanceUID, sopInstanceUID, page,
count, sort, sequence);
}

#endregion
}


 

 

 

其中

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]


 

 

是保证WCF实例是单例的.

 

然后再如下在运行窗口把这个给启动了.

class Program
{
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("***** Console Based Host*****");
var timer = new QueryDicomServerTimer();
using (ServiceHost serviceHost = new ServiceHost(typeof(DICOMService)))
{
serviceHost.Open();
Console.WriteLine("The server is ready.");
DisplayServerInfo(serviceHost);
timer.Start();
Console.WriteLine("Press the Enter key to terminate the service");
Console.ReadLine();
}
timer.End();
}

static void DisplayServerInfo(ServiceHost serviceHost)
{
Console.WriteLine();
Console.WriteLine("****** Host Info ******");
foreach (var endpoint in serviceHost.Description.Endpoints)
{
Console.WriteLine("The address is {0}", endpoint.Address);
Console.WriteLine("The binding is {0}", endpoint.Binding.Name);
Console.WriteLine("The contract is {0}", endpoint.Contract.Name);
Console.WriteLine();
}
Console.WriteLine("***********************");
}
}


 

 

 

 

web.config配置如下:

<system.serviceModel>
<bindings/>
<client/>
<services>
<service name="DICOMServiceLib.BLL.DICOMService" behaviorConfiguration="DICOMServiceMEXBehavior">
<endpoint address="" binding="basicHttpBinding" contract="DICOMServiceLib.IDAL.IDICOMService"/>
<!-- Enable the MEX endpoint -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<!-- Need to add this so MEX knows the address of our service -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:9090/DICOMService"/>
</baseAddresses>
</host>
</service>
</services>
<!-- A behavior definition for MEX -->
<behaviors>
<serviceBehaviors>
<behavior name="DICOMServiceMEXBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>


 

 

 

运行的结果如下图:





 

 

欢迎各位参与讨论,如果觉得对你有帮助,请点击

    推荐下,万分谢谢.

作者:spring yang

出处:http://www.cnblogs.com/springyangwc/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: