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. Git使用文档

    建立项目 新建项目 进入gitlab.dev(192.168.14.28) 选择LDAP,用自己的域账号登录 点击右上角的 加号(+)新建项目 填写项目名称 选择组为 Online_Web “Visi ...

  2. Bank homework 10 2016 4 25

    #include<iostream>#include<string>using namespace std;class Bank { public: Bank(string _ ...

  3. Jade之标签

    一种简洁的便于书写html的模板语言. 支持所有的html(5)标签和正常的javascript表达式 标签 相比于html,jade的标签只需一个标签名即可,不需要关闭标签,也不需要尖括号. 对于需 ...

  4. IMP数据到指定的表空间

    IMP数据到指定的表空间 当我们通过imp导入dmp文件时,默认的情况下,数据会导入到exp出的dmp文件所对应的表空间里面. 比如:通过orcl_dev用户,exp数据,用orcl_test用户im ...

  5. 横竖屏切换时Activity的生命周期

    设置横竖屏切换时Activity生命周期的属性设置,在清单文件中的Activity节点中设置.根据具体需求设置: 1.不设置Activity的android:configChanges时,切屏会重新调 ...

  6. 在cocos2d里面如何使用Texture Packer和像素格式来优化spritesheet

    免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...

  7. day4----json的简单实用

    json官方说明参见:http://json.org/ Python操作json的标准api库参考:http://docs.python.org/library/json.html 重要函数 编码:把 ...

  8. Neo4j 2.0 M4 发布

    Neo4j 发布了 2.0 的第四个里程碑版本,该版本要求 Java 7 的支持.详细的改进记录请看发行通知. Neo是一个网络——面向网络的数据库——也就是说,它是一个嵌入式的.基于磁盘的.具备完全 ...

  9. Dynamic CRM 2013学习笔记(十六)用JS控制Tab可见,可用

    一个Form里经常会有好几个Tab,有时要根据一些条件设置哪些Tab可用,可见.下面就介绍下如何用JS对Tab进行控制. 1. 控制可见   function setTabVisableByName( ...

  10. Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示

    CRM的项目,审批流是一个必须品.为了更方便灵活地使用.配置审批流,我们自定义了一整套审批流.首先来看下它的效果: 1. 审批模板 这是一个最简单的审批流,首先指定审批实体,及相关字段,再配置流程节点 ...