首页 > 代码库 > WCF探索之旅(四)——程序中WCF服务整合
WCF探索之旅(四)——程序中WCF服务整合
我们在之前的博客已经完成过实例,大家也看到了如何使用WCF服务:
添加服务引用——>输入服务地址——>实例化服务——>调用服务方法
那么今天为什么要再次说“程序中WCF服务整合”这个话题?
用过WebService的人都知道,随着服务的增多,管理WebService是一个非常繁重的工作。好了,今天我们的目标来了——让WCF服务变得整齐、有序、易管理!
首先,我们建立一个工厂类,这个工厂用来实例化我们的服务。这样做的好处是,所有的服务都是由工厂实例化的。
然后我们要建立一个公共的接口,这个接口继承所有的服务接口。这样做的好处是,所有的服务接口都可以用这个接口来代替。
好了,有了这两点,我们就可以利用多态+工厂来统一管理我们的服务了。
说了这么多理论,还是以我们程序猿的语言说更明了一些!
1、建立接口类IServices
namespace <span style="font-family: SimSun; font-size: 10.5pt;">Modules.Interface</span> { [ServiceContract] public interface IServices : IUserSevice { } }
2、建立服务工厂ServiceFactory
namespace Modules.Factory { public class ServiceFactory { private static readonly SortedList<string, IServices> _serviceBusiness = new SortedList<string, IServices>(); //获取接口 public static IServices GetServiceBusiness(string endpointName) { IServices iServices; iServices = CreateWCFInterface(endpointName); if (_serviceBusiness.ContainsKey(endpointName)) { iServices = _serviceBusiness[endpointName]; } else { if (true) { iServices = CreateWCFInterface(endpointName); } _serviceBusiness.Add(endpointName, iServices); } return iServices; } //获取WCF服务方法,使用代理工厂 private static IServices CreateWCFInterface(string endpointName) { return ServiceProxyFactory.Create<IServices>(endpointName); } //获取用户服务 public static IUserSevice GetUserService(string endpointName) { return GetServiceBusiness(endpointName); } } }
3、建立代理工厂ServiceProxyFactory
namespace Modules.Factory.ServiceProxy { public static class ServiceProxyFactory { public static T Create<T>(string endpointName) { if (string.IsNullOrEmpty(endpointName)) { throw new ArgumentNullException("endpointName"); } return (T)(new ServiceRealProxy<T>(endpointName).GetTransparentProxy()); } } }
4、建立代理类RealProxy
namespace Modules.Factory.ServiceProxy { public class ServiceRealProxy<T> : RealProxy { private readonly string _endpointName; public ServiceRealProxy(string endpointName): base(typeof(T)) { if (string.IsNullOrEmpty(endpointName)) { throw new ArgumentNullException("endpointName"); } this._endpointName = endpointName; } //重写Invoke public override IMessage Invoke(IMessage msg) { T channel = ChannelFactoryCreator.Create<T>(this._endpointName).CreateChannel(); IMethodCallMessage methodCall = (IMethodCallMessage)msg; IMethodReturnMessage methodReturn = null; object[] copiedArgs = Array.CreateInstance(typeof(object), methodCall.Args.Length) as object[]; methodCall.Args.CopyTo(copiedArgs, 0); try { object returnValue = http://www.mamicode.com/methodCall.MethodBase.Invoke(channel, copiedArgs);>5、建立通道工厂ChannelFactoryCreatornamespace ICT.RCS.Modules.Factory.ServiceProxy { internal static class ChannelFactoryCreator { private static readonly Hashtable channelFactories = new Hashtable(); public static ChannelFactory<T> Create<T>(string endpointName) { if (string.IsNullOrEmpty(endpointName)) { throw new ArgumentNullException("endpointName"); } 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; } } }6、引入工厂dll
要想使用WCF,我们以前是必须添加服务引用,而添加服务引用VS就会自动生成一个APP.CONFIG的配置文件,这个文件中配置了服务的地址以及访问协议等内容。
现在,我们需要将上面的这些内容打包成dll并添加到引用。
7、配置app.config
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="bin"/> </assemblyBinding> </runtime> <system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="bhc"> <dataContractSerializer maxItemsInObjectGraph="2147483647"/> </behavior> </endpointBehaviors> </behaviors> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_WcfService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="409600" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="None"> <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" /> <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" /> </security> </binding> </wsHttpBinding> </bindings> <client> <endpoint address="http://localhost:8080/UserManagerService.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_WcfService" contract="wcfDemo.IServices" name="Service" /> </client> </system.serviceModel> </configuration>至此,我们的整合已经完成了。我们在需要用服务的地方使用ServiceFactory.GetUserService().AddUser(enUser);即可。不需要引入服务引用,不需要手动实例化,是不是方便了很多,灵活了很多!
如果现在有了新的服务需求,我们只需要
1、开发一个新的接口和实现
2、在IService接口中添加继承
3、更新服务
4、程序中直接调用ServiceFactory就可以“点”出它来
这篇博客中参考了其他人很多东西,也是一次尝试。如果大家在练习或者使用过程中遇到什么问题,咱们可以一起交流!
下一篇博客跟大家一起分享:WCF与WebService的异同