• 利用WCF技术降低系统之间的耦合度


         为了降低本系统各个组件之间的耦合度,本系统将BLL层采用WCF技术发布为Web Service,以供UI层调用。

      前面我们已经介绍过,为什么UI层不直接调用BLL层,而是要经过UI->Service.Wrapper->Service.Host->Service->BLL这样绕一大圈的方式来调用BLL层呢?

      笔者认为至少有以下几个原因:

      第一,直接调用会导致系统耦合度太高,任何后台的改动都会导致前台需要重新编译、发布,而这样做了之后,只要Contract不改变,则前台不用做任何改动;

      第二,这样做了之后,比较适合SOA的理念,系统的扩展性、交互性和灵活性大大提高;

      第三,直接调用会导致Solution中会有过多的Project,编译非常慢,导致开发人员的时间浪费过多。

      下面让我们来看看WCF是如何在系统中得到应用的。

      首先,我们需要事先实现一个Contract,让相关的各个组件共同遵守。一个Contract,实际上就是一个interface,为了使它能用于WCF,我们需要添加ServiceContract、OperationContract标识。如果该interface用到了一些自定义的Info类,则需要使用ServiceKnownType一一指明。

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     1 using System;
     2 using System.Collections;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 using System.Text;
     6 using System.ServiceModel;
     7 using System.Runtime.Serialization;
     8 using Eallies.OA.Service.Contract.Fault;
     9 using Eallies.OA.Info;
    10 
    11 namespace Eallies.OA.Service.Contract
    12 {
    13     [ServiceContract]
    14     [ServiceKnownType(typeof(EmployeeInfo))]
    15     public interface IEmployeeContract
    16     {
    17         [OperationContract]
    18         [FaultContract(typeof(FaultInfo))]
    19         void SaveEmployee(EmployeeInfo employeeInfo);
    20 
    21         [OperationContract]
    22         IList GetEmployees();
    23     }
    24 }

      另外,FaultContract用于WCF的错误处理,我们可以在配置文件中将includeExceptionDetailInFaults设为true,这样我们就能将错误的详细信息通过Web Service传到UI层。而FaultInfo则是一个简单的类,用于保存需要传递的消息,如错误信息。

    双击代码全选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     1 <?xml version="1.0"?>
     2 <configuration xmlns="[url]http://schemas.microsoft.com/.NetConfiguration/v2.0[/url]">
     3   <system.serviceModel>
     4     <behaviors>
     5       <serviceBehaviors>
     6         <behavior name="metadataSupport">
     7           <serviceDebug includeExceptionDetailInFaults="true" />
     8           <serviceMetadata httpGetEnabled="true" />
     9         </behavior>
    10       </serviceBehaviors>
    11     </behaviors>
    12   </system.serviceModel>
    13 </configuration>

      之后,我们就可以用一个继承于Contract的类将BLL层进行包装。

    双击代码全选
    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
     1 using System;
     2 using System.Collections;
     3 using System.Collections.Generic;
     4 using System.Linq;
     5 using System.Text;
     6 using Eallies.OA.Service.Contract;
     7 using Eallies.OA.Info;
     8 using Eallies.OA.BLL;
     9 
    10 namespace Eallies.OA.Service
    11 {
    12     public class EmployeeService : IEmployeeContract
    13     {
    14         #region IEmployeeContract Members
    15 
    16         public void SaveEmployee(EmployeeInfo employeeInfo)
    17         {
    18             try
    19             {
    20                 EmployeeBLL bll = new EmployeeBLL();
    21                 bll.SaveEmployee(employeeInfo);
    22             }
    23             catch
    24             {
    25                 throw;
    26             }
    27         }
    28 
    29         public IList GetEmployees()
    30         {
    31             try
    32             {
    33                 EmployeeBLL bll = new EmployeeBLL();
    34                 return bll.GetEmployees();
    35             }
    36             catch
    37             {
    38                 throw;
    39             }
    40         }
    41 
    42         #endregion
    43     }
    44 }

    完成之后的这样一个类我们就可以采用WCF技术Host到合适的应用程序中了。本系统将WCF给Host到IIS中了。要做到这点,只需要创建一个ASP.NET Web Service Application,将该项目发布为虚拟目录。

      具体的类则是通过svc文件来完成Host的。其代码则非常简单:

    双击代码全选
    1
    1 <%@ ServiceHost Language="C#" Debug="true" Service="Eallies.OA.Service.EmployeeService" %>

      这样一来,该BLL层的所有函数就发布成Web Service了。不论客户端的形式是怎样的,我们都可以调用这个Web Service来完成客户端的功能。当然,为了使客户端的调用更为简单,我们需要将Web Service进行进一步的包装。这个过程可以使用Microsoft自带的svcutil.exe工具来完成。

    代码全选
    1
    1 svcutil.exe "http://localhost/Eallies.OA.Service.Host/EmployeeHost.svc?wsdl" /o:"..Eallies.OA.Service.WrapperEmployeeWrapper.cs" /r:"..Eallies.OA.InfobinDebugEallies.OA.Info.dll" /r:"..Eallies.OA.Info.EnumbinDebugEallies.OA.Info.Enum.dll" /r:"..Eallies.OA.Service.Contract.FaultbinDebugEallies.OA.Service.Contract.Fault.dll" /n:*,Eallies.OA.Service.Wrapper /noConfig

      值得注意的是,如果我们的Web Service引用了其它的类,则svcutil.exe工具会帮我们将所有的这些类重新生成一次,当然,这不是我们期望的。为此,我们采用参数/r的方式将需要引用的各个dll传入,这样就可以避免svcutil.exe工具自动生成了。另外/r参数可以多次指定,这为多个dll的引用提供了可能。

  • 相关阅读:
    Android 面试题--Activity
    Android 手机卫士--平移动画实现
    Android 手机卫士--导航界面4的业务逻辑
    Android 手机卫士--获取联系人信息并显示与回显
    Android 手机卫士--绑定sim卡序列号
    Android 手机卫士--导航界面3、4和功能列表界面跳转逻辑处理
    Android 手机卫士--导航界面2
    Android 手机卫士--9patch图
    Add Columns to the Web Sessions List
    C# System.Collections.Generic.Dictionary
  • 原文地址:https://www.cnblogs.com/luyujie/p/3198360.html
Copyright © 2020-2023  润新知