+2009-01-14 Astushi Enomoto <atsushi@ximian.com>
+
+ * System.ServiceModel_test.dll.sources :
+ added ClientBase_InteractiveChannelInitializerTest.cs.
+
2009-01-07 Astushi Enomoto <atsushi@ximian.com>
* net_2_1_raw_System.ServiceModel.dll.sources : add OperationContext
+2009-01-14 Atsushi Enomoto <atsushi@ximian.com>
+
+ * ClientBase.cs, ClientRuntimeChannel.cs : added support for
+ interactive channel initializers.
+
2009-01-12 Geoff Norton <gnorton@novell.com>
* ClientBase.cs: Added a few delegates missing from ChannelBase
get { return InnerChannel.State; }
}
- [MonoTODO]
public void Abort ()
{
InnerChannel.Abort ();
}
- [MonoTODO]
public void Close ()
{
InnerChannel.Close ();
}
- [MonoTODO]
public void DisplayInitializationUI ()
{
+ InnerChannel.DisplayInitializationUI ();
}
- [MonoTODO]
void IDisposable.Dispose ()
{
Close ();
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Security;
+using System.Threading;
namespace System.ServiceModel
{
this.runtime = runtime;
this.factory = factory;
_processDelegate = new ProcessDelegate (Process);
+
+ // default values
+ AllowInitializationUI = true;
}
public ClientRuntime Runtime {
#region IClientChannel
- [MonoTODO]
- public bool AllowInitializationUI {
- get { throw new NotImplementedException (); }
- set { throw new NotImplementedException (); }
- }
+ bool did_interactive_initialization;
+
+ public bool AllowInitializationUI { get; set; }
- [MonoTODO]
public bool DidInteractiveInitialization {
- get { throw new NotImplementedException (); }
+ get { return did_interactive_initialization; }
}
public Uri Via {
get { return runtime.Via; }
}
- [MonoTODO]
+ class DelegatingWaitHandle : WaitHandle
+ {
+ public DelegatingWaitHandle (IAsyncResult [] results)
+ {
+ this.results = results;
+ }
+
+ IAsyncResult [] results;
+
+ protected override void Dispose (bool disposing)
+ {
+ if (disposing)
+ foreach (var r in results)
+ r.AsyncWaitHandle.Close ();
+ }
+
+ public override bool WaitOne ()
+ {
+ foreach (var r in results)
+ r.AsyncWaitHandle.WaitOne ();
+ return true;
+ }
+
+ public override bool WaitOne (int millisecondsTimeout)
+ {
+ return WaitOne (millisecondsTimeout, false);
+ }
+
+ WaitHandle [] ResultWaitHandles {
+ get {
+ var arr = new WaitHandle [results.Length];
+ for (int i = 0; i < arr.Length; i++)
+ arr [i] = results [i].AsyncWaitHandle;
+ return arr;
+ }
+ }
+
+ public override bool WaitOne (int millisecondsTimeout, bool exitContext)
+ {
+ return WaitHandle.WaitAll (ResultWaitHandles, millisecondsTimeout, exitContext);
+ }
+
+ public override bool WaitOne (TimeSpan timeout, bool exitContext)
+ {
+ return WaitHandle.WaitAll (ResultWaitHandles, timeout, exitContext);
+ }
+ }
+
+ class DisplayUIAsyncResult : IAsyncResult
+ {
+ public DisplayUIAsyncResult (IAsyncResult [] results)
+ {
+ this.results = results;
+ }
+
+ IAsyncResult [] results;
+
+ internal IAsyncResult [] Results {
+ get { return results; }
+ }
+
+ public object AsyncState {
+ get { return null; }
+ }
+
+ WaitHandle wait_handle;
+
+ public WaitHandle AsyncWaitHandle {
+ get {
+ if (wait_handle == null)
+ wait_handle = new DelegatingWaitHandle (results);
+ return wait_handle;
+ }
+ }
+
+ public bool CompletedSynchronously {
+ get {
+ foreach (var r in results)
+ if (!r.CompletedSynchronously)
+ return false;
+ return true;
+ }
+ }
+ public bool IsCompleted {
+ get {
+ foreach (var r in results)
+ if (!r.IsCompleted)
+ return false;
+ return true;
+ }
+ }
+ }
+
public IAsyncResult BeginDisplayInitializationUI (
AsyncCallback callback, object state)
{
- throw new NotImplementedException ();
+ OnInitializationUI ();
+ IAsyncResult [] arr = new IAsyncResult [runtime.InteractiveChannelInitializers.Count];
+ int i = 0;
+ foreach (var init in runtime.InteractiveChannelInitializers)
+ arr [i++] = init.BeginDisplayInitializationUI (this, callback, state);
+ return new DisplayUIAsyncResult (arr);
}
- [MonoTODO]
public void EndDisplayInitializationUI (
IAsyncResult result)
{
- throw new NotImplementedException ();
+ DisplayUIAsyncResult r = (DisplayUIAsyncResult) result;
+ int i = 0;
+ foreach (var init in runtime.InteractiveChannelInitializers)
+ init.EndDisplayInitializationUI (r.Results [i++]);
+
+ did_interactive_initialization = true;
}
- [MonoTODO]
public void DisplayInitializationUI ()
{
- throw new NotImplementedException ();
+ OnInitializationUI ();
+ foreach (var init in runtime.InteractiveChannelInitializers)
+ init.EndDisplayInitializationUI (init.BeginDisplayInitializationUI (this, null, null));
+
+ did_interactive_initialization = true;
+ }
+
+ void OnInitializationUI ()
+ {
+ if (!AllowInitializationUI && runtime.InteractiveChannelInitializers.Count > 0)
+ throw new InvalidOperationException ("AllowInitializationUI is set to false but the client runtime contains one or more InteractiveChannelInitializers.");
}
public void Dispose ()
protected override void OnOpen (TimeSpan timeout)
{
+ if (runtime.InteractiveChannelInitializers.Count > 0 && !DidInteractiveInitialization)
+ throw new InvalidOperationException ("The client runtime is assigned interactive channel initializers, and in such case DisplayInitializationUI must be called before the channel is opened.");
}
// IChannel
public object Process (MethodBase method, string operationName, object [] parameters)
{
+ if (AllowInitializationUI)
+ DisplayInitializationUI ();
OperationDescription od = SelectOperation (method, operationName, parameters);
if (!od.IsOneWay)
return Request (od, parameters);
System.ServiceModel/ChannelFactoryTest.cs
System.ServiceModel/ChannelFactory_1Test.cs
System.ServiceModel/ClientBaseTest.cs
+System.ServiceModel/ClientBase_InteractiveChannelInitializerTest.cs
System.ServiceModel/ClientCredentialsSecurityTokenManagerTest.cs
System.ServiceModel/CommonUseCases.cs
System.ServiceModel/EndpointAddress10Test.cs
+2009-01-14 Atsushi Enomoto <atsushi@ximian.com>
+
+ * ClientBase_InteractiveChannelInitializerTest.cs : new test, for
+ IInteractiveChannelInitializers support in ClientBase<T>.
+
2008-05-22 Roei Erez <roeie@mainsoft.com>
* fix ContractDescription.GetContract implementation
* Refactor Request processing
--- /dev/null
+//
+// ClientBase_InteractiveChannelInitializerTest.cs
+//
+// Author:
+// Atsushi Enomoto <atsushi@ximian.com>
+//
+// Copyright (C) 2006 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.ObjectModel;
+using System.IO;
+using System.Net.Sockets;
+using System.Reflection;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+using System.ServiceModel.Description;
+using System.ServiceModel.Dispatcher;
+using System.Xml;
+using NUnit.Framework;
+
+namespace MonoTests.System.ServiceModel
+{
+ [TestFixture]
+ // FIXME: it does not contain testcase for successful initialization yet
+ // (MyChannelInitializer implementation hangs on .NET)
+ public class ClientBase_InteractiveChannelInitializerTest
+ {
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void NotAllowedInitializationUI ()
+ {
+ var f = new FooProxy (new BasicHttpBinding (), new EndpointAddress ("http://localhost:37564"));
+ f.Endpoint.Contract.Behaviors.Add (new MyContractBehavior ());
+ f.InnerChannel.AllowInitializationUI = false;
+ f.DisplayInitializationUI ();
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidOperationException))]
+ public void OpenBeforeDisplayInitializationUI ()
+ {
+ var f = new FooProxy (new BasicHttpBinding (), new EndpointAddress ("http://localhost:37564"));
+ f.Endpoint.Contract.Behaviors.Add (new MyContractBehavior ());
+ f.Open ();
+ }
+
+ public class MyContractBehavior2 : MyContractBehavior
+ {
+ }
+
+ public class MyContractBehavior : IContractBehavior
+ {
+ public void AddBindingParameters (ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
+ {
+ }
+
+ public void ApplyClientBehavior (ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
+ {
+ clientRuntime.InteractiveChannelInitializers.Add (new MyChannelInitializer ());
+ }
+
+ public void ApplyDispatchBehavior (ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
+ {
+ }
+
+ public void Validate (ContractDescription contractDescription, ServiceEndpoint endpoint)
+ {
+ }
+ }
+
+ public class MyChannelInitializer : IInteractiveChannelInitializer
+ {
+ delegate void DoWork ();
+ DoWork d;
+ static int instance;
+ int number;
+
+ public MyChannelInitializer ()
+ {
+ number = instance++;
+ }
+
+ public IAsyncResult BeginDisplayInitializationUI (IClientChannel channel, AsyncCallback callback, object state)
+ {
+ Console.WriteLine ("Begin");
+ d = new DoWork (DisplayInitializationUI);
+ return d.BeginInvoke (null, null);
+ }
+
+ public void EndDisplayInitializationUI (IAsyncResult result)
+ {
+ Console.WriteLine ("End");
+ d.EndInvoke (result);
+ }
+
+ public void DisplayInitializationUI ()
+ {
+ Console.WriteLine ("Core: " + number);
+ }
+ }
+
+ public class FooProxy : ClientBase<IFoo>, IFoo
+ {
+ public FooProxy (Binding binding, EndpointAddress address)
+ : base (binding, address)
+ {
+ }
+
+ public string Echo (string msg)
+ {
+ return Channel.Echo (msg);
+ }
+ }
+
+ [ServiceContract]
+ public interface IFoo
+ {
+ [OperationContract]
+ string Echo (string input);
+ }
+
+ public class FooService : IFoo
+ {
+ public string Echo (string input)
+ {
+ return input;
+ }
+ }
+ }
+}