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. Linux内核实现中断和中断处理(二)

    第一部分移步传送门召唤!!:http://www.cnblogs.com/lenomirei/p/5562086.html 上回说了Linux内核实现中断会把中断分为两部分进行处理,上回讲了上部分,这 ...

  2. P1403约数研究

    洛谷1403 约数研究 题目描述 科学家们在Samuel星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机"Samuel2"的长时间运算成为了可能.由于在去年一年的辛苦工作 ...

  3. Java集合的运算之减法A-B

    import com.sun.media.sound.SoftSynthesizer; import java.util.*;   public class a123 { public static ...

  4. 利用破解dll来获取到一个软件的注册码

    ---恢复内容开始--- 首先做这个事是纯属于个人研究而已,请勿以侵犯他人劳动成果. 今天看到了一个关于IL语句的文章,于是就学学,然后实践实践下.废话不多说了. 1.安装好某一个需要注册才可以的使用 ...

  5. PHP疑惑

    <?php $a = array(); $a[0] = 1; $a[1] = 2; $b = (object)$a; var_dump($b); 怎么从对象$b 中取值??? <?php ...

  6. Myeclipse加载maven

    1.自带,需要将之前下好的文本加入到myeclipse中即可.windows---->preference---->Myeclipse---->MavenMyeclipse 3.将本 ...

  7. 在Openfire中使用自己的数据表之修改配置文件

    目前我使用的Openfire版本是3.10.3,以下使用说明也是在这个版本上做的修改. Openfire提供了两种方式使用用户数据表.一种是安装完成之后默认实现的org.jivesoftware.op ...

  8. mvc-servlet---ServletConfig与ServletContext对象详解(转载)

    ServletConfig与ServletContext对象详解 一.ServletConfig对象    在Servlet的配置文件中,可以使用一个或多个<init-param>标签为s ...

  9. C2第三次作业解题报告

    看过题解后如果觉得还算有用,请帮忙加点我所在团队博客访问量 http://www.cnblogs.com/newbe/ http://www.cnblogs.com/newbe/p/4069834.h ...

  10. NumberSort选择法、冒泡法排序

    public class NumberSort {/***读进9个数:*构建成一个int型数组:*顺序排好:**/public static void main(String args[]) {int ...