+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 :
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;
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)) {
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/";
+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
//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;
}
{
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
+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
{
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);
CodeClass c = new CodeModule (modname).CreateClass (
"__callbackproxy_" + cd.Name,
crtype,
- new Type [] {type});
+ new Type [] {callbackType});
//
// public __callbackproxy_MyContract (
{
// 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);
}
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Transactions;
+using System.Threading;
using NUnit.Framework;
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
}
}
+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.