2010-01-08 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Fri, 8 Jan 2010 10:40:46 +0000 (10:40 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Fri, 8 Jan 2010 10:40:46 +0000 (10:40 -0000)
* ContractDescriptionGenerator.cs : fix GetCallbackContract() to
  correctly retrieve ServiceContractAttribute from the service type,
  not the callback type. This ended up to get the bug #567672 sample
  working (but it will break at some stage as it involves some
  non-implemented classes).

* EndpointDispatcher.cs, InputOrReplyRequestProcessor.cs :
  Pass service type to correctly retrieve ServiceContractAttribute
  from the service type, not callback type.

* ServiceProxyGenerator.cs, ServiceRuntimeChannel.cs :
  Pass service type to correctly retrieve ServiceContractAttribute
  from the service type, not callback type.

* CallbackBehaviorAttributeTest.cs : added callback example from
  bug #567672.

svn path=/trunk/mcs/; revision=149226

mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescriptionGenerator.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/EndpointDispatcher.cs
mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/InputOrReplyRequestProcessor.cs
mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog
mcs/class/System.ServiceModel/System.ServiceModel/ServiceProxyGenerator.cs
mcs/class/System.ServiceModel/System.ServiceModel/ServiceRuntimeChannel.cs
mcs/class/System.ServiceModel/Test/System.ServiceModel/CallbackBehaviorAttributeTest.cs
mcs/class/System.ServiceModel/Test/System.ServiceModel/ChangeLog

index 3cd44b966f680584646564bcfc8af8b38249e257..961add56a6ba8c7d1048fa98c5251ba6e41ce352 100644 (file)
@@ -1,3 +1,11 @@
+2010-01-08  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ContractDescriptionGenerator.cs : fix GetCallbackContract() to
+         correctly retrieve ServiceContractAttribute from the service type,
+         not the callback type. This ended up to get the bug #567672 sample
+         working (but it will break at some stage as it involves some
+         non-implemented classes).
+
 2009-12-18  Atsushi Enomoto  <atsushi@ximian.com>
 
        * ServiceContractGenerator.cs :
index edba80ea362733fe8447c1e4c92bd6d1d3c16aae..b4e52621998360d9631d52efd7c1124783628806 100644 (file)
@@ -29,6 +29,7 @@ using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
+using System.Linq;
 using System.Net.Security;
 using System.Reflection;
 using System.Runtime.Serialization;
@@ -91,28 +92,28 @@ namespace System.ServiceModel.Description
                        return null;
                }
 
-               public static ContractDescription GetCallbackContract (Type type)
+               public static ContractDescription GetCallbackContract (Type serviceType, Type callbackType)
                {
-                       return GetContract (type, null, true);
+                       return GetContract (callbackType, null, serviceType);
                }
 
                public static ContractDescription GetContract (
                        Type givenContractType, Type givenServiceType)
                {
-                       return GetContract (givenContractType, givenServiceType, false);
+                       return GetContract (givenContractType, givenServiceType, null);
                }
 
-               static ContractDescription GetContract (Type givenContractType, Type givenServiceType, bool assumeServiceContract)
+               static ContractDescription GetContract (Type givenContractType, Type givenServiceType, Type serviceTypeForCallback)
                {
                        // FIXME: serviceType should be used for specifying attributes like OperationBehavior.
 
                        Type exactContractType = null;
                        ServiceContractAttribute sca = null;
                        Dictionary<Type, ServiceContractAttribute> contracts = 
-                               GetServiceContractAttributes (givenServiceType ?? givenContractType);
+                               GetServiceContractAttributes (serviceTypeForCallback ?? givenServiceType ?? givenContractType);
                        if (contracts.ContainsKey(givenContractType)) {
                                exactContractType = givenContractType;
-                               sca = contracts[givenContractType];
+                               sca = contracts [givenContractType];
                        } else {
                                foreach (Type t in contracts.Keys)
                                        if (t.IsAssignableFrom(givenContractType)) {
@@ -127,10 +128,10 @@ namespace System.ServiceModel.Description
                        if (exactContractType == null)
                                exactContractType = givenContractType;
                        if (sca == null) {
-                               if (assumeServiceContract)
-                                       sca = new ServiceContractAttribute ();
+                               if (serviceTypeForCallback != null)
+                                       sca = contracts.Values.First ();
                                else
-                                       throw new InvalidOperationException (String.Format ("Attempted to get contract type from '{0}' which neither is a service contract nor does it inherit service contract.", givenContractType));
+                                       throw new InvalidOperationException (String.Format ("Attempted to get contract type from '{0}' which neither is a service contract nor does it inherit service contract.", serviceTypeForCallback ?? givenContractType));
                        }
                        string name = sca.Name ?? exactContractType.Name;
                        string ns = sca.Namespace ?? "http://tempuri.org/";
index 568c7bf9fc4bfc743ceea82bca86acc5dc949ab8..08f78317b777a85e4fb303d87511b301a8cb443a 100644 (file)
@@ -1,3 +1,9 @@
+2010-01-08  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * EndpointDispatcher.cs, InputOrReplyRequestProcessor.cs :
+         Pass service type to correctly retrieve ServiceContractAttribute
+         from the service type, not callback type.
+
 2010-01-07  Atsushi Enomoto  <atsushi@ximian.com>
 
        * ChannelDispatcher.cs : make sure to unlock channel acceptor wait
index 8770fa2360c802d99e5c6e82fcbfdb5fdb6caee6..5c29cb4eaba65105af564d3a2cdddb5d33780188 100644 (file)
@@ -123,7 +123,7 @@ namespace System.ServiceModel.Dispatcher
                        //Build the dispatch operations
                        DispatchRuntime db = this.DispatchRuntime;
                        if (!isCallback && se.Contract.CallbackContractType != null) {
-                               var ccd = ContractDescriptionGenerator.GetCallbackContract (se.Contract.CallbackContractType);
+                               var ccd = ContractDescriptionGenerator.GetCallbackContract (db.Type, se.Contract.CallbackContractType);
                                db.CallbackClientRuntime = ccd.CreateClientRuntime ();
                                db.CallbackClientRuntime.CallbackClientType = ccd.ContractType;
                        }
index e2615c6ae41af09f3a575dd7d7ff746ba5e42262..74a4daa0e35ffa0300ccc3af55cc27d7114775ec 100644 (file)
@@ -55,7 +55,7 @@ namespace System.ServiceModel.Dispatcher
                {
                        ServiceRuntimeChannel contextChannel;
                        if (dispatch_runtime.HasCallbackRuntime) {
-                               var type = ServiceProxyGenerator.CreateCallbackProxyType (dispatch_runtime.CallbackClientRuntime.CallbackClientType);
+                               var type = ServiceProxyGenerator.CreateCallbackProxyType (dispatch_runtime.Type, dispatch_runtime.CallbackClientRuntime.CallbackClientType);
                                contextChannel = (ServiceRuntimeChannel) Activator.CreateInstance (type, new object [] {reply_or_input, dispatch_runtime});
                        }
                        else
index 9107d56c8ead5d0054976454e63425035cacbbcb..89495146f67be6923c8de239cd0a35e481f4b4e9 100755 (executable)
@@ -1,3 +1,9 @@
+2010-01-08  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * ServiceProxyGenerator.cs, ServiceRuntimeChannel.cs :
+         Pass service type to correctly retrieve ServiceContractAttribute
+         from the service type, not callback type.
+
 2010-01-08  Atsushi Enomoto  <atsushi@ximian.com>
 
        * ClientRuntimeChannel.cs : to open duplex callback channel, it must
index 1efd151e42b8c941c68bb18d98aa5d44e0a3b7a1..75430bef08cb66877c7114bfbbdd196698e8e133 100644 (file)
@@ -37,9 +37,9 @@ namespace System.ServiceModel
 {
        internal class ServiceProxyGenerator : ProxyGeneratorBase
        {
-               public static Type CreateCallbackProxyType (Type type)
+               public static Type CreateCallbackProxyType (Type serviceType, Type callbackType)
                {
-                       var cd = ContractDescriptionGenerator.GetCallbackContract (type);
+                       var cd = ContractDescriptionGenerator.GetCallbackContract (serviceType, callbackType);
                        string modname = "dummy";
                        Type crtype = typeof (DuplexServiceRuntimeChannel);
 
@@ -47,7 +47,7 @@ namespace System.ServiceModel
                        CodeClass c = new CodeModule (modname).CreateClass (
                                "__callbackproxy_" + cd.Name,
                                crtype,
-                               new Type [] {type});
+                               new Type [] {callbackType});
 
                        //
                        // public __callbackproxy_MyContract (
index 1cf72776b879aa21c227947a271bf04a6736be06..e07f26ed3d393a54e9f873cb3e999beb0ba70d7f 100644 (file)
@@ -41,7 +41,7 @@ namespace System.ServiceModel
                {
                        // setup callback ClientRuntimeChannel.
                        var crt = runtime.CallbackClientRuntime;
-                       var cd = ContractDescriptionGenerator.GetCallbackContract (crt.CallbackClientType);
+                       var cd = ContractDescriptionGenerator.GetCallbackContract (runtime.Type, crt.CallbackClientType);
                        client = new ClientRuntimeChannel (crt, cd, this.DefaultOpenTimeout, this.DefaultCloseTimeout, channel, null,
                                                           runtime.ChannelDispatcher.MessageVersion, this.RemoteAddress, null);
                }
index 46de1fcc76bc85c816cf044bfd9f52e6a984235b..24700233a1db9531d723d2ec05a299b18a834254 100644 (file)
@@ -35,6 +35,7 @@ using System.ServiceModel.Channels;
 using System.ServiceModel.Description;
 using System.ServiceModel.Dispatcher;
 using System.Transactions;
+using System.Threading;
 using NUnit.Framework;
 
 namespace MonoTests.System.ServiceModel
@@ -124,5 +125,77 @@ namespace MonoTests.System.ServiceModel
                        [OperationContract]
                        void Block (string s);
                }
+
+               #region "bug #567672"
+               [Test]
+               public void CallbackExample1 ()
+               {
+                       //Start service and use net.tcp binding
+                       ServiceHost eventServiceHost = new ServiceHost (typeof (GreetingsService));
+                       NetTcpBinding tcpBindingpublish = new NetTcpBinding ();
+                       tcpBindingpublish.Security.Mode = SecurityMode.None;
+                       eventServiceHost.AddServiceEndpoint (typeof (IGreetings), tcpBindingpublish, "net.tcp://localhost:8000/GreetingsService");
+                       eventServiceHost.Open ();
+
+                       //Create client proxy
+                       NetTcpBinding clientBinding = new NetTcpBinding ();
+                       clientBinding.Security.Mode = SecurityMode.None;
+                       EndpointAddress ep = new EndpointAddress ("net.tcp://localhost:8000/GreetingsService");
+                       ClientCallback cb = new ClientCallback ();
+                       IGreetings proxy = DuplexChannelFactory<IGreetings>.CreateChannel (new InstanceContext (cb), clientBinding, ep);
+
+                       //Call service
+                       proxy.SendMessage ();
+
+                       //Wait for callback - sort of hack, but better than using wait handle to possibly block tests.
+                       Thread.Sleep (1000);
+
+                       //Cleanup
+                       eventServiceHost.Close ();
+
+                       Assert.IsTrue (CallbackSent, "#1");
+                       Assert.IsTrue (CallbackReceived, "#1");
+               }
+
+               public static bool CallbackSent, CallbackReceived;
+
+               //Service implementation
+               [ServiceBehavior (ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
+               public class GreetingsService : IGreetings
+               {
+                       public void SendMessage ()
+                       {
+                               //Make a callback
+                               IGreetingsCallback clientCallback = OperationContext.Current.GetCallbackChannel<IGreetingsCallback> ();
+
+                               clientCallback.ShowMessage ("Mono and WCF are GREAT!");
+                               CallbackBehaviorAttributeTest.CallbackSent = true;
+                       }
+               }
+
+               // Client callback interface implementation
+               [CallbackBehavior (ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
+               public class ClientCallback : IGreetingsCallback
+               {
+                       public void ShowMessage (string message)
+                       {
+                               CallbackBehaviorAttributeTest.CallbackReceived = true;
+                       }
+               }
+
+               [ServiceContract (CallbackContract = typeof (IGreetingsCallback))]
+               public interface IGreetings
+               {
+                       [OperationContract (IsOneWay = true)]
+                       void SendMessage ();
+               }
+
+               [ServiceContract]
+               public interface IGreetingsCallback
+               {
+                       [OperationContract (IsOneWay = true)]
+                       void ShowMessage (string message);
+               }
+               #endregion
        }
 }
index 987d2b8705e62df96adccf6b857f05d8c10cc7dc..9e2452e92e1f6fcb73b430e6ae6c90bce8de8f9b 100755 (executable)
@@ -1,3 +1,8 @@
+2010-01-08  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * CallbackBehaviorAttributeTest.cs : added callback example from
+         bug #567672.
+
 2010-01-07  Atsushi Enomoto  <atsushi@ximian.com>
 
        * ServiceHostBaseTest.cs : another mannerless test here.