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. IIS7.5支持html页面包含(include)html页面

    前提条件: ServerSideIncludeModule的安装: 在安装iis的时候选择上该服务(“在服务端包含文件”,选项)即可,如下: 1:处理映射程序 添加模块映射 请求路径 *.html 模 ...

  2. linux 中如何修改时间 date

    修改linux的时间可以使用date指令  修改日期: 时间设定成2009年5月10日的命令如下: #date -s 05/10/2009  修改时间: 将系统时间设定成上午10点18分0秒的命令如下 ...

  3. Ubuntu下制作ISO文件

    利用Ubuntu自带的命令mkisofs就可以制作iso文件,具体方法如下: 1.   如果你是直接从cd压制iso文件的,执行 sudo umount /dev/cdromdd if=/dev/cd ...

  4. 「2014-2-6」TokuMX and MongoDB related materials collection

    简介参考 TokuMX 和 MongoDB 各自的官方站点.       ##  Tokutek 最重要的特点和 marketing word 是所谓 fractal tree indexing te ...

  5. 从0开始学Swift笔记整理(二)

    这是跟在上一篇博文后续内容: --函数中参数的传递引用 类是引用类型,其他的数据类型如整型.浮点型.布尔型.字符.字符串.元组.集合.枚举和结构体全部是值类型. 有的时候就是要将一个值类型参数以引用方 ...

  6. slick-pg v0.1.5 发布

    这个版本的更新主要是: 增加了对 json 的支持 (PostgreSQL 9.3 正式版已经发布了,所以我适时加入了对 pg json 的支持.功能其实前两个星期就已经开发测试好了,但公司跟联邦政府 ...

  7. EmberJs之使用Ember-Data

    写在前面 最近比较忙,换了新工作还要学习很多全新的技术栈,并给自己找了很多借口来不去坚持写博客.常常具有讽刺意味的是,更多剩下的时间并没有利用而更多的是白白浪费,也许这就是青春吧,挥霍吧,这不是我想要 ...

  8. 《JavaScript语言精粹》学习笔记

    一.in的用法 for...in 枚举一个对象的所有可枚举属性 检测DOM/BOM属性 if ("onclick" in elem) { // 元素支持onclick } if ( ...

  9. 手机H5 web调试利器——WEINRE (WEb INspector REmote)

    手机H5 web调试利器--WEINRE (WEb INspector REmote) 调试移动端页面,优先选择使用chrome浏览器调试,如果是hybrid形式的页面,可以使用chrome提供的ch ...

  10. ajaxFileUpload上传文件后提示下载的问题

    在某些版本浏览器下ajaxFileUpload上传文件会提示下载, 1:为什么? 可以观察到,即便返回 JsonResult 在返回的头中也没有任何消息体,直接理解为文本了. 2:解决方案 前端: f ...