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 接口:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      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);
      }

      接下来实现接口

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      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
        }

      其中

      1
      [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

      是保证WCF实例是单例的.

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

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      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配置如下:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      <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/Leo_wl/p/2517146.html