WCF,很好,却又麻烦,很多时候不想用WCF的原因就是:用这个真麻烦...

麻烦的地方,比如:

  • 一堆一堆的服务配置,散落在一个一个的folder下,更新系统时容易出错
  • 客户端除了要知道WCF Contract外,还要知道服务Provider所在位置

所以想了个办法来简化这些,主要思路是:

  • 加入Internal Communication Service,简称ICS。用来插入自定义的中间层
  • 编写一个Service Locator Service,用来将WCF服务提供者信息抽取统一保存,如:url, endpoint类型,做到wcf服务提供者位置无关性

完成后,WCF客户端(包括WCF服务内部调用了其他WCF服务的服务...)调用代码会变成如下方式:

//不支持事务的调用方式
IUser userSrv = ICSFactory.Create<IUser>();
var result = userSrv.GetUserName("", "", "");
ICSFactory.Close(userSrv); //支持事务的调用方式
string result = string.Empty;
using (TransactionScope ts = new TransactionScope())
{
IUser userSrv = ICSFactory.Create<IUser>();
IAdmin adminSrv = ICSFactory.Create<IAdmin>(); result = userSrv.GetUserName("", "", "");
result = adminSrv.CheckPermission().ToString(); ts.Complete(); ICSFactory.Close(userSrv);
ICSFactory.Close(adminSrv);
}

WCF客户端的配置信息去哪了呢? A:在appSetting中,有个key,用来表示服务配置信息文件所在路径,如:\\fs\root\a2d.service.config,配置文件如下:

<?xml version="1.0" encoding="utf-8" ?>
<A2D>
<ServiceLocator>
<Service ContractNamespace="DEsbInterface" Contract="IUser">
<Url EndpointType="Tcp">net.tcp://192.168.1.100:9999/usersrv</Url>
</Service>
<Service ContractNamespace="DEsbInterface" Contract="IAdmin">
<Url EndpointType="Tcp">net.tcp://192.168.1.100:9998/adminsrv</Url>
</Service>
</ServiceLocator>
</A2D>

如果调用WCF服务的客户端只有一个程序,就没多大用了,但是如果有很多客户端程序,那就有用了,如下场景:

4台server都作为客户端进行WCF服务的调用

ICS原理:

在本例中,ICS其实就是ICSFactory,用来建立WCF服务代理,通过代码方式加入binding、address、transaction信息,底层调用的是ChannelFactory来建立通信,代码如下:

public class ICSFactory
{
/// <summary>
/// 创建WCF服务代理对象
/// </summary>
/// <typeparam name="T">WCF的Contract类型</typeparam>
/// <returns></returns>
public static T Create<T>()
{
string contractNamespace = typeof(T).Namespace;
string contract = typeof(T).Name; //根据WCF Contract信息找到相应的位置信息
Location location = ServiceLocator.Locate(contractNamespace, contract); //生成绑定信息
NetTcpBinding binding = new NetTcpBinding();
binding.ReceiveTimeout = new TimeSpan(, , );
binding.Security.Mode = SecurityMode.None;
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None; //事务设置
binding.TransactionFlow = true;
binding.TransactionProtocol = TransactionProtocol.OleTransactions; //地址信息
EndpointAddress address = new EndpointAddress(location.Url); //建立信道
T broker=ChannelFactory<T>.CreateChannel(binding, address); //返回代理对象
return broker;
} /// <summary>
/// Dispose代理对象
/// </summary>
/// <param name="broker"></param>
public static void Close(object broker)
{
if (broker == null)
return; IDisposable disposable = broker as IDisposable;
if (disposable == null)
return; disposable.Dispose();
}
}

Service Locator Service原理:

也就是ServiceLocator.Locate函数。

程序启动时会根据配置读取config文件的xml到内存对象中:Service、Url。具体代码略。

Locate函数的代码如下:

        /// <summary>
/// 根据Contract的命名空间及Contract名找到服务的真实地址信息
/// </summary>
/// <param name="contractNamespace"></param>
/// <param name="contract"></param>
/// <returns></returns>
public static Location Locate(string contractNamespace, string contract)
{
Service srv=null; string key = string.Format("{0}.{1}", contractNamespace, contract);
if (!serviceCache.ContainsKey(key))
{
srv = FindService(contractNamespace, contract, srv);
serviceCache[key] = srv;
}
else
{
srv=serviceCache[key];
}
if(srv.Urls==null||srv.Urls.Count==)
throw new Exception(string.Format("Service' url not found [{0}.{1}]", contractNamespace, contract)); Url url=srv.Urls.First(); Location location = new Location();
location.EndpointType = url.EndpointType;
location.Url = url.ReferenceUrl;return location;
} private static Service FindService(string contractNamespace, string contract, Service srv)
{
List<Service> matchedServices = LocatorServiceConfiguration.Services.Where(t =>
t.Contract.CompareTo(contract) ==
&&
t.ContractNamespace.CompareTo(contractNamespace) ==
).ToList(); if (matchedServices == null || matchedServices.Count == )
throw new Exception(string.Format("Service not found [{0}.{1}]", contractNamespace, contract)); srv = matchedServices.First();
return srv;
}

内部通信服务Factory(WCF)的更多相关文章

  1. autofac 注入普通服务和WCF服务

    using Autofac;using Autofac.Builder;using Autofac.Core; //实现Autofac扩展 public static AutofacRegisterW ...

  2. 从开发的角度比较 ASP.NET Web 服务与 WCF

    Windows Communication Foundation (WCF) 具有一个 ASP.NET 兼容模式选项,用户使用此选项可以对 WCF 应用程序进行编程和配置,使其像 ASP.NET We ...

  3. WCF开发实战系列四:使用Windows服务发布WCF服务

    WCF开发实战系列四:使用Windows服务发布WCF服务 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 上一篇文章中我们通过编写的控制台程序或WinForm程序来为本 ...

  4. Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务、WCF消息头添加安全验证Token

    原文:Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务.WCF消息头添加安全验证Token 为什么选择wcf?   因为好像wcf和wpf就是哥俩,,, 为什么选择异步 ...

  5. C#.NET 操作Windows服务承载WCF

    Windows服务的制作.安装可以参考这篇: C#.NET 操作Windows服务(安装.卸载) - runliuv - 博客园 (cnblogs.com) 本篇会在这个解决方案基础上,继续修改. 一 ...

  6. IOS调用WCF服务,WCF服务器进行上传图片

    1.IOS端采用post方式请求服务器端的url地址 如:http://192.168.0.12:50000/serverce1.svc/upload IOS端的代码采用base64位编码的方式传值给 ...

  7. WCF服务与WCF数据服务的区别

    问: Hi, I am newbie to wcf programming and a little bit confused between WCF Service and WCF Data  Se ...

  8. 重温WCF之构建一个简单的WCF(一)(2)通过Windows Service寄宿服务和WCF中实现操作重载

    参考地址:http://www.cnblogs.com/zhili/p/4039111.html 一.如何在Windows Services中寄宿WCF服务 第一步:创建Windows 服务项目,具体 ...

  9. 创建服务factory和service方法的区别

    factory方法返回的是对象,json或数组,也可以返回字符串类型的数据,但service方法只能返回数据或对象 创建服务有3种方法 $provide.provider('服务名',function ...

随机推荐

  1. 王爽-汇编语言-综合研究一-搭建简易C环境

    (一) 学习过程: 整个过程分为两个部分: 第一:将TC2.0的环境使用虚拟软盘复制到DOS虚拟机中: 打开WinImage,fileànew,由于TC2.0的环境解压后为2.02M,所以我们在Sta ...

  2. three.js 之旅 (五)--跟场景scene相关的函数

    1.scene.add(obj);   在场景中添加物体 2.scene.remove(obj);   在场景中移除物体 3.scene.children();  获取场景中所有子对象的列表 4.sc ...

  3. Educational Codeforces Round 10

    A:Gabriel and Caterpillar 题意:蜗牛爬树问题:值得一提的是在第n天如果恰好在天黑时爬到END,则恰好整除,不用再+1: day = (End - Begin - day0)/ ...

  4. php安装gearman扩展实现异步分步式任务

    参考: 1.小喵爱你的博客 2.PHP Manual 依赖 1.gcc44 2.boost >=1.39 3.libevent 4.php5.3+ 5.update ld.so.conf 安装依 ...

  5. lvs主备可以自由切换,vip落在主上的时候,端口无法telnet,业务连接不了

    lvs主备可以自由切换,vip落在主上的时候,端口无法telnet,业务连接不了 解决:将主上的keepalived重启,故障解除 原因:不可知 lvs常见故障原因: real server上的脚步没 ...

  6. Divide Two Integers leetcode

    题目:Divide Two Integers Divide two integers without using multiplication, division and mod operator. ...

  7. step by step 之餐饮管理系统二

    昨天写了餐饮管理系统的相关需求,得到了园友的一些好的建议,感到很高兴,确实写的也不全面,现在补充一下需要的业务,这次主要做的主要是前台收银系统,所以业务主要集中在前台点菜收银这块,而后面数据管理这块则 ...

  8. office2003-2007 绿色版 出错 文件丢失(未解决)

    - 这个版本是我大学时候(2012)年一直用到现在的版本:目录结构如下: 原来一直在32位系统中使用,没有出错过; - 刚装的两台电脑系统分别为 Win7Pro 和 Win10Pro ,都是64位的: ...

  9. 使用PPT绘制96孔板

    什么?96孔板就是Ctrl+C然后再Ctrl+V? 那你用PPT给我画一个384孔板吧……(学生物的应该都知道这货吧?示意图不少用吧?) 还不够麻烦?那就试试基因芯片吧…… 疯掉了有木有? 那么,看看 ...

  10. du -sg 和df -g 所看的文件系统大小不一致

    最近碰到一个问题: df -g 查看内存,发现空间已经满了,但是到对应目录查看,发现只用了一半的空间,感觉还有一半不见了. 经咨询其他人,给了两个解释: 1.fsck :使用Fsck命令修复损坏的分区 ...