瀏覽代碼

2009-08-11 Atsushi Enomoto <[email protected]>

	* IOperationInvoker.cs : fix interface.
	* DefaultOperationInvoker.cs : refresh implementation of the above.
	* BaseMessagesFormatter.cs, OperationInvokerHandler.cs :
	  dependent changes for above.

	* ServiceHostBase.cs : use new IOperationInvoker implementation.

	* System.ServiceModel.dll.sources: add DefaultOperationInvoker.cs.


svn path=/trunk/mcs/; revision=139695
Atsushi Eno 16 年之前
父節點
當前提交
95ce234785

+ 4 - 0
mcs/class/System.ServiceModel/ChangeLog

@@ -1,3 +1,7 @@
+2009-08-11  Astushi Enomoto  <[email protected]>
+
+	* System.ServiceModel.dll.sources: add DefaultOperationInvoker.cs.
+
 2009-08-07  Astushi Enomoto  <[email protected]>
 
 	* System.ServiceModel.dll.sources: add ServiceProxyGenerator.cs.

+ 4 - 2
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs

@@ -157,8 +157,10 @@ namespace System.ServiceModel.Dispatcher
 			{
 				int index = 0;
 				foreach (ParameterInfo pi in requestMethodParams)
-					if (!pi.IsOut)
-						parameters [pi.Position] = parts [index++];
+					if (!pi.IsOut) {
+						parameters [index] = parts [index];
+						index++;
+					}
 			}
 		}
 

+ 7 - 0
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChangeLog

@@ -1,3 +1,10 @@
+2009-08-11  Atsushi Enomoto  <[email protected]>
+
+	* IOperationInvoker.cs : fix interface.
+	* DefaultOperationInvoker.cs : refresh implementation of the above.
+	* BaseMessagesFormatter.cs, OperationInvokerHandler.cs :
+	  dependent changes for above.
+
 2009-08-07  Atsushi Enomoto  <[email protected]>
 
 	* InputOrReplyRequestProcessor.cs : now it could return an instance

+ 131 - 0
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/DefaultOperationInvoker.cs

@@ -0,0 +1,131 @@
+//
+// DefaultOperationInvoker.cs
+//
+// Author: Atsushi Enomoto ([email protected])
+//
+// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using System.ServiceModel;
+using System.ServiceModel.Description;
+using System.Reflection;
+using System.Threading;
+
+namespace System.ServiceModel.Dispatcher
+{
+	class DefaultOperationInvoker : IOperationInvoker
+	{
+		readonly OperationDescription od;
+		readonly ParameterInfo [] in_params, out_params;
+
+		public DefaultOperationInvoker (OperationDescription od)
+		{
+			this.od = od;
+			var mi = od.SyncMethod ?? od.BeginMethod;
+			var il = new List<ParameterInfo> ();
+			var ol = new List<ParameterInfo> ();
+			var pl = mi.GetParameters ();
+			int count = mi == od.BeginMethod ? pl.Length - 2 : pl.Length;
+			for (int i = 0; i < count; i++) {
+				var pi = pl [i];
+				if (!pi.IsOut)
+					il.Add (pi);
+				if (pi.IsOut)
+					ol.Add (pi);
+			}
+			in_params = il.ToArray ();
+			out_params = ol.ToArray ();
+		}
+
+		public bool IsSynchronous {
+			get { return true; }
+		}
+
+		public object [] AllocateInputs ()
+		{
+			return new object [in_params.Length];
+		}
+
+		public object Invoke (object instance, object [] inputs, out object [] outputs)
+		{
+			var arr = new object [in_params.Length + out_params.Length];
+			for (int i = 0; i < in_params.Length; i++)
+				arr [in_params [i].Position] = inputs [i];
+
+			var ret = od.SyncMethod.Invoke (instance, arr);
+
+			outputs = new object [out_params.Length];
+			for (int i = 0; i < out_params.Length; i++)
+				outputs [i] = arr [out_params [i].Position];
+
+			return ret;
+		}
+
+		public IAsyncResult InvokeBegin (object instance, object [] inputs, AsyncCallback callback, object state)
+		{
+			var arr = new object [in_params.Length + out_params.Length + 2];
+			for (int i = 0; i < in_params.Length; i++)
+				arr [in_params [i].Position] = inputs [i];
+			arr [arr.Length - 2] = callback;
+			arr [arr.Length - 1] = state;
+			return new InvokeAsyncResult (arr, (IAsyncResult) od.BeginMethod.Invoke (instance, arr));
+		}
+
+		public object InvokeEnd (object instance, out object [] outputs, IAsyncResult result)
+		{
+			var r = (InvokeAsyncResult) result;
+			var ret = od.EndMethod.Invoke (instance, new object [] {r.Source});
+			var arr = r.Parameters;
+			outputs = new object [out_params.Length];
+			for (int i = 0; i < out_params.Length; i++)
+				outputs [i] = arr [out_params [i].Position];
+			return ret;
+		}
+
+		class InvokeAsyncResult : IAsyncResult
+		{
+			public InvokeAsyncResult (object [] parameters, IAsyncResult source)
+			{
+				Source = source;
+				Parameters = parameters;
+			}
+
+			public IAsyncResult Source;
+			public object [] Parameters;
+
+			public WaitHandle AsyncWaitHandle {
+				get { return Source.AsyncWaitHandle; }
+			}
+			public bool CompletedSynchronously {
+				get { return Source.CompletedSynchronously; }
+			}
+			public bool IsCompleted {
+				get { return Source.IsCompleted; }
+			}
+			public object AsyncState {
+				get { return Source.AsyncState; }
+			}
+		}
+	}
+}

+ 2 - 2
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/IOperationInvoker.cs

@@ -32,8 +32,8 @@ namespace System.ServiceModel.Dispatcher
 	public interface IOperationInvoker
 	{
 		bool IsSynchronous { get; }
-		object [] AllocateParameters ();
-		object Invoke (object instance, object [] inputs);
+		object [] AllocateInputs ();
+		object Invoke (object instance, object [] inputs, out object [] outputs);
 		IAsyncResult InvokeBegin (object instance, object [] inputs, 
 			AsyncCallback callback, object state);
 		object InvokeEnd (object instance, out object [] outputs, IAsyncResult result);

+ 4 - 4
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/OperationInvokerHandler.cs

@@ -31,12 +31,12 @@ namespace System.ServiceModel.Dispatcher
 			DispatchOperation operation = mrc.Operation;
 			Message req = mrc.IncomingMessage;
 			object instance = mrc.InstanceContext.GetServiceInstance(req);
-			object [] parameters;			
+			object [] parameters, outParams;
 			BuildInvokeParams (mrc, out parameters);
 
 			if (operation.Invoker.IsSynchronous) {
-				object result = operation.Invoker.Invoke (instance, parameters);
-				HandleInvokeResult (mrc, parameters, result);
+				object result = operation.Invoker.Invoke (instance, parameters, out outParams);
+				HandleInvokeResult (mrc, outParams, result);
 			} else {// asynchronous
 				InvokeAsynchronous (mrc, instance, parameters);
 			}			
@@ -112,7 +112,7 @@ namespace System.ServiceModel.Dispatcher
 			EnsureValid (operation);
 
 			if (operation.DeserializeRequest) {
-				parameters = operation.Invoker.AllocateParameters ();
+				parameters = operation.Invoker.AllocateInputs ();
 				operation.Formatter.DeserializeRequest (mrc.IncomingMessage, parameters);
 			} else
 				parameters = new object [] { mrc.IncomingMessage };

+ 1 - 0
mcs/class/System.ServiceModel/System.ServiceModel.dll.sources

@@ -614,6 +614,7 @@ System.ServiceModel.Dispatcher/ClientOperation.cs
 System.ServiceModel.Dispatcher/ClientRuntime.cs
 System.ServiceModel.Dispatcher/DataContractSerializerServiceBehavior.cs
 System.ServiceModel.Dispatcher/DefaultInstanceContextProvider.cs
+System.ServiceModel.Dispatcher/DefaultOperationInvoker.cs
 System.ServiceModel.Dispatcher/DispatchOperation.cs
 System.ServiceModel.Dispatcher/DispatchRuntime.cs
 System.ServiceModel.Dispatcher/EndpointAddressMessageFilter.cs

+ 4 - 0
mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog

@@ -1,3 +1,7 @@
+2009-08-11  Atsushi Enomoto  <[email protected]>
+
+	* ServiceHostBase.cs : use new IOperationInvoker implementation.
+
 2009-08-07  Atsushi Enomoto  <[email protected]>
 
 	* ServiceRuntimeChannel.cs : change .ctor() args.

+ 4 - 5
mcs/class/System.ServiceModel/System.ServiceModel/ServiceHostBase.cs

@@ -479,11 +479,7 @@ namespace System.ServiceModel
 			}
 
 			// Setup Invoker
-			// FIXME: support async method
-			if (od.SyncMethod != null)
-				o.Invoker = new SyncMethodInvoker (od.SyncMethod);
-			else
-				o.Invoker = new AsyncMethodInvoker (od.BeginMethod, od.EndMethod);
+			o.Invoker = new DefaultOperationInvoker (od);
 
 			// Setup Formater
 			o.Formatter = BaseMessagesFormatter.Create (od);
@@ -612,6 +608,7 @@ namespace System.ServiceModel
 			Close ();
 		}
 
+		/*
 		class SyncMethodInvoker : IOperationInvoker
 		{
 			readonly MethodInfo _methodInfo;
@@ -692,5 +689,7 @@ namespace System.ServiceModel
 
 			#endregion
 		}
+		*/
 	}
+
 }