为了降低本系统各个组件之间的耦合度,本系统将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的引用提供了可能。

利用WCF技术降低系统之间的耦合度的更多相关文章

  1. VC中利用多线程技术实现线程之间的通信

    当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...

  2. WCF技术剖析之七:如何实现WCF与EnterLib PIAB、Unity之间的集成

    原文:WCF技术剖析之七:如何实现WCF与EnterLib PIAB.Unity之间的集成 在这之前,我写过深入介绍MS EnterLib PIAB的文章(参阅<MS Enterprise Li ...

  3. 利用WCF的双工通讯实现一个简单的心跳监控系统 z

    利用WCF的双工通讯实现一个简单的心跳监控系统 http://www.cnblogs.com/zuowj/p/5761011.html 何为心跳监控系统? 故名思义,就是监控某个或某些个程序的运行状态 ...

  4. WCF技术剖析之五:利用ASP.NET兼容模式创建支持会话(Session)的WCF服务

    原文:WCF技术剖析之五:利用ASP.NET兼容模式创建支持会话(Session)的WCF服务 在<基于IIS的WCF服务寄宿(Hosting)实现揭秘>中,我们谈到在采用基于IIS(或者 ...

  5. 深度技术Win7系统利用diskpart命令实现硬盘分区的技巧

    转自:http://www.xitongcheng.com/jiaocheng/win7_article_2491.html 1. 深度技术Win7系统利用diskpart命令实现硬盘分区的技巧分享给 ...

  6. WCF技术剖析之十四:泛型数据契约和集合数据契约(下篇)

    原文:WCF技术剖析之十四:泛型数据契约和集合数据契约(下篇) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]在.NE ...

  7. 《WCF技术剖析》博文系列汇总[持续更新中]

    原文:<WCF技术剖析>博文系列汇总[持续更新中] 近半年以来,一直忙于我的第一本WCF专著<WCF技术剖析(卷1)>的写作,一直无暇管理自己的Blog.在<WCF技术剖 ...

  8. 用 ThreadPoolExecutor/ThreadPoolTaskExecutor 线程池技术提高系统吞吐量(附带线程池参数详解和使用注意事项)

    1.概述 在Java中,我们一般通过集成Thread类和实现Runnnable接口,调用线程的start()方法实现线程的启动.但如果并发的数量很多,而且每个线程都是执行很短的时间便结束了,那样频繁的 ...

  9. WCF技术的不同应用场景及其实现分析

    这一篇文章,是总结一下WCF技术,以及基于这个技术发展出来的几个典型应用场景,并且我将尝试对这些不同的WCF实现的原理进行一些比较分析. 关于WCF这个技术的基本概念,如果你不是很清楚,可以参考一下有 ...

随机推荐

  1. dedecms /plus/feedback_ajax.php、/templets/feedback_main.htm、/templets/feedback_edit.htm XSS && SQL Injection Vul

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 通过该漏洞可以注入恶意代码到评论标题里,网站管理员在后台管理用户评论时触 ...

  2. MACOS 答题器,界面跳转

    国内OSX开发的资料实在少,甚至连一本开发的书都找不到… 更无语的是,苹果自家的开发文档Sample Code不仅还停留在OC版本,还是MRC的… 在这样的情况下,OSX开发还真得靠“想象力”… 网上 ...

  3. css3 media媒体查询器用法总结

    随着响应式设计模型的诞生,Web网站又要发生翻天腹地的改革浪潮,可能有些人会觉得在国内IE6用户居高不下的情况下,这些新的技术还不会广泛的蔓延下去,那你就错了,如今淘宝,凡客,携程等等公司都已经在大胆 ...

  4. STL之lower_bound和upper_bound

    ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)算法返回一个非递减序列[first, la ...

  5. sscanf()函数的使用及其实例

    资料引自: 传送门 sscanf函数原型: Int sscanf( const char * src, const char * format, ...); int scanf( const char ...

  6. Hough Transform

    Hough Transform Introduction: The Hough transform is an algorithm that will take a collection of poi ...

  7. hdu 2036 - 改革春风吹满地(计算几何)

    题意:求解多边形面积 解法: 先了解数学上"叉积"的含义与性质: 三角形ΔABC的面积为: 我们可以依次计算每个三角形的面积,ΔABC,ΔACE,ΔEF - - 所有三角形的面积之 ...

  8. SSH 学习总结-01 SSH整合环境

    一 Struts2+Spring3+Hibernate4+Maven 整合环境 1 开发工具 1)JDK下载地址:http://www.oracle.com/technetwork/java/java ...

  9. BZOJ1180: [CROATIAN2009]OTOCI

    传送门 一遍AC,开心! $Link-Cut-Tree$最后一题 //BZOJ 1180 //by Cydiater //2016.9.18 #include <iostream> #in ...

  10. JavaWeb---总结(十)HttpServletRequest对象(一)

    一.HttpServletRequest介绍 HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象 ...