WCF 开发学习笔记

概述

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) 框架模型

3

 

WCF组成结构

6

 

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

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

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

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

8 

(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>

 

 

 

运行的结果如下图:

image

 

 

欢迎各位参与讨论,如果觉得对你有帮助,请点击image    推荐下,万分谢谢.

作者:spring yang

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

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

转载于:https://www.cnblogs.com/springyangwc/archive/2012/05/24/2516827.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值