我一直都比较反感添加服务引用的方式来通过vs生成代理来调用服务的方式。对于WebService Client来说,没有找到比较好的方法,可是对于WCF来说,还是有不少办法可以做的。然而对于WCF 客户端,我也一直也希望能够做到的要求:
1、客户端和服务端尽量做到低耦合,特别对于服务端的修改,客户端能尽量减少修改已至不用修改。
2、对于客户端来说,调用WCF服务的代码要做到简洁、安全、方便和高效。
所以我有了这种想法:
WCF ChannelFactory进行缓存,方便重用,提高性能。
对于服务端的请求,通过Action进行传递,统一调用和处理:
代码如下:
internal static class ChannelFactoryCreator
{
//存储所有的客户端代理
private static Hashtable channelFactories = new Hashtable();
/// <summary>
/// 根据point名称获得相应的客户端代理
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="endpointName"></param>
/// <returns></returns>
public static ChannelFactory<T> Create<T>(string endpointName)
{
if (string.IsNullOrEmpty(endpointName))
{
throw new ArgumentNullException("endpointName");//*,可以自动查询配置信息中Contract相同的。
}
ChannelFactory<T> channelFactory = null;
if (channelFactories.ContainsKey(endpointName))
{
channelFactory = channelFactories[endpointName] as ChannelFactory<T>;
}
if (channelFactory == null)
{
channelFactory = new ChannelFactory<T>(endpointName);
lock (channelFactories.SyncRoot)
{
channelFactories[endpointName] = channelFactory;
}
}
return channelFactory;
}
/// <summary>
/// 通过Action封装操作
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="action"></param>
/// <param name="endPointName"></param>
public static void UseService<T>(Action<T> action,string endPointName)
{
T channel = Create<T>(endPointName).CreateChannel();
try {
((IClientChannel)channel).Open(); action(channel);
((IClientChannel)channel).Close(); }
catch
{
((IClientChannel)channel).Abort();
}
}