为了降低本系统各个组件之间的耦合度,本系统将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. HDU 5925 Coconuts

    2016 CCPC 东北四省赛 D. 一道好题. 现场写崩了. 赛后LSh跟我讲了一种离散化的做法, 没听懂. 题意 一个\(R \cdot C\ (R, C\le 10^9)\) 的矩形点阵上有 $ ...

  2. 本地仓库 同步到 bitbucket 远程git库

    http://blog.csdn.net/lue2009/article/details/46553829 配置ssh连接: http://blog.csdn.net/lue2009/article/ ...

  3. zabbix监控系列(2)之zabbix-agent安装

    zabbix-agent的安装不用LAMP的支持,所以直接源码安装,make两下,改下配置文件即可,改完后可以把源码包直接压缩打包就可以给其他agent用了,可谓,一次编译,多台使用. NO1.解包压 ...

  4. 探究JavaScript中的五种事件处理程序

    探究JavaScript中的五种事件处理程序 我们知道JavaScript与HTML之间的交互是通过事件实现的.事件最早是在IE3和Netscape Navigator 2中出现的,当时是作为分担服务 ...

  5. (翻译)如何对python dict 类型按键(keys)或值(values)排序

    如何对dict类型按键(keys)排序(Python 2.4 或更高版本): mydict = {'carl':40, 'alan':2, 'bob':1, 'danny':3} for key in ...

  6. js013-事件

    js013-事件 本章内容 理解事件流 使用时间处理程序 不同的事件类型 JS与HTML之间的交互是通过实践实现的.时间就还文档或浏览器窗口发生的一些特定的交互 瞬间.可以使用侦听器来预定事件,以便时 ...

  7. html img src base64

    网页上有些图片的src或css背景图片的url后面跟了一大串字符,比如:data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAYAAABId ...

  8. 9月5日网页基础知识 通用标签、属性(body属性、路径、格式控制) 通用标签(有序列表、无序列表、常用标签)(补)

    网页基础知识 一.HTML语言 HTML语言翻译汉语为超文本标记语言. 二.网页的分类 1.静态页面:在静态页面中修改网页内容实际上就是修改网页原代码,不能从后台操作,数据来只能来源于原于代码.静态网 ...

  9. Winsock 入门 Echo 示例

    #include <stdio.h> #include <winsock2.h> #pragma comment(lib, "ws2_32") /* Win ...

  10. Codeforces 697A - Pineapple Incident

    题目链接:http://codeforces.com/problemset/problem/697/A 题目大意: 输入三个数 t,s,x; 判断x是否合适 合适的位置位 t , t+s, t+s+1 ...