程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> WCF探索之旅(四)——程序中WCF服務整合

WCF探索之旅(四)——程序中WCF服務整合

編輯:C++入門知識

WCF探索之旅(四)——程序中WCF服務整合


我們在之前的博客已經完成過實例,大家也看到了如何使用WCF服務:

添加服務引用——>輸入服務地址——>實例化服務——>調用服務方法

 

那麼今天為什麼要再次說“程序中WCF服務整合”這個話題?

用過WebService的人都知道,隨著服務的增多,管理WebService是一個非常繁重的工作。好了,今天我們的目標來了——讓WCF服務變得整齊、有序、易管理!

 

首先,我們建立一個工廠類,這個工廠用來實例化我們的服務。這樣做的好處是,所有的服務都是由工廠實例化的。

然後我們要建立一個公共的接口,這個接口繼承所有的服務接口。這樣做的好處是,所有的服務接口都可以用這個接口來代替。

 

好了,有了這兩點,我們就可以利用多態+工廠來統一管理我們的服務了。

 

說了這麼多理論,還是以我們程序猿的語言說更明了一些!

 

1、建立接口類IServices

 

	namespace Modules.Interface
	{
	    [ServiceContract]
	    public interface IServices :
	        IUserSevice
	    {
	
	    }
	}

 

2、建立服務工廠ServiceFactory

	namespace Modules.Factory
	{
	    public  class ServiceFactory
	    {
			private static readonly SortedList _serviceBusiness = new SortedList();
			//獲取接口
			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(endpointName);
			}
		
			//獲取用戶服務
			public static IUserSevice GetUserService(string endpointName)
			{
				return GetServiceBusiness(endpointName);
			}
		}
	}

3、建立代理工廠ServiceProxyFactory

	namespace Modules.Factory.ServiceProxy
	{
	    public static class ServiceProxyFactory {
	        public static T Create(string endpointName) {
	            if (string.IsNullOrEmpty(endpointName)) {
	                throw new ArgumentNullException(endpointName);
	            }
	            return (T)(new ServiceRealProxy(endpointName).GetTransparentProxy());
	        }
	    }
	}

4、建立代理類RealProxy

	namespace Modules.Factory.ServiceProxy
	{
		public class ServiceRealProxy : 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(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 = methodCall.MethodBase.Invoke(channel, copiedArgs);
					methodReturn = new ReturnMessage(returnValue, copiedArgs, copiedArgs.Length, methodCall.LogicalCallContext, methodCall);
					((ICommunicationObject)channel).Close();
				}
				catch (TargetInvocationException tiEx) 
				{
					string title;
					if (tiEx.InnerException is NotSupportedException) 
					{
						title =string.Concat( WCFExpetion, NotSupportedException, WCF服務契約異常);
						throw new Exception(
							string.Format({0}:
{1}, title, tiEx.InnerException.Message), tiEx.InnerException);
					}
					else if (tiEx.InnerException is FaultException) 
					{
						title = string.Concat(WCFExpetion, FaultException, 方法內部出現沒有處理的異常);
						throw new Exception(string.Format({0}:
{1}, title, tiEx.InnerException.Message),
						tiEx.InnerException);
					}
					else if (tiEx.InnerException is CommunicationException) 
					{
						title = string.Concat(WCFExpetion, CommunicationException, 網絡異常,請檢查地址是否正確);
						throw new Exception(
						string.Format({0}:
{1}, title, tiEx.InnerException.Message), tiEx.InnerException);
					}
					else if (tiEx.InnerException is TimeoutException) 
					{
						title = string.Concat(WCFExpetion, TimeoutException, 連接超時,請檢查網絡是否正常);
						throw new Exception(
						string.Format({0}:
{1}, title, tiEx.InnerException.Message), tiEx.InnerException);
					}
				}
				catch (Exception ex) 
				{
					throw new Exception(string.Format(WCF出現未知異常:
{0}, ex.Message), ex);
				}
				finally {
					((ICommunicationObject)channel).Abort();
				}
				return methodReturn;
			}
		}

}
5、建立通道工廠ChannelFactoryCreator

 

	namespace ICT.RCS.Modules.Factory.ServiceProxy
	{
	    internal static class ChannelFactoryCreator {
	        private static readonly Hashtable channelFactories = new Hashtable();
	        public static ChannelFactory Create(string endpointName) {
	            if (string.IsNullOrEmpty(endpointName)) {
	                throw new ArgumentNullException(endpointName);
	            }
	
	            ChannelFactory channelFactory = null;
	            if (channelFactories.ContainsKey(endpointName)) {
	                channelFactory = channelFactories[endpointName] as ChannelFactory;
	            }
	            if (channelFactory == null) {
	                channelFactory = new ChannelFactory(endpointName);
	                lock (channelFactories.SyncRoot) {
	                    channelFactories[endpointName] = channelFactory;
	                }
	            }
	            return channelFactory;
	        }
	    }
	}

 

6、引入工廠dll

要想使用WCF,我們以前是必須添加服務引用,而添加服務引用VS就會自動生成一個APP.CONFIG的配置文件,這個文件中配置了服務的地址以及訪問協議等內容。

現在,我們需要將上面的這些內容打包成dll並添加到引用。

7、配置app.config

		 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved