+2010-06-18 Atsushi Enomoto <atsushi@ximian.com>
+
+ * ServiceMetadataExtension.cs : use simple ChannelDispatcher.IsMex field.
+
2010-06-17 Atsushi Enomoto <atsushi@ximian.com>
* ServiceMetadataExtension.cs : overwrite MessageVersion to use None.
listener.Properties.Add (new MetadataPublishingInfo () { SupportsMex = isMex, SupportsHelp = !isMex, Instance = instance });
else
throw new InvalidOperationException ("FIXME: attempt to use ServiceMetadataExtension to not-supported channel listener: " + listener.GetType ());
+ channelDispatcher.IsMex = true;
channelDispatcher.Endpoints [0].DispatchRuntime.InstanceContextProvider = new SingletonInstanceContextProvider (new InstanceContext (owner, instance));
dispatchers.Add (uri, channelDispatcher);
+2010-06-17 Atsushi Enomoto <atsushi@ximian.com>
+
+ * ChannelDispatcher.cs : add simple bool field to mark for mex channel.
+
2010-06-17 Atsushi Enomoto <atsushi@ximian.com>
* ChannelDispatcher.cs : MessageVersion check is moved to
{
public abstract class ChannelDispatcherBase : CommunicationObject
{
+ internal bool IsMex { get; set; }
+
public abstract IChannelListener Listener { get; }
public abstract ServiceHostBase Host { get; }
+2010-06-18 Atsushi Enomoto <atsushi@ximian.com>
+
+ * ServiceHostBase.cs : Do not build more than one ChannelDispatcher
+ for a Binding. Then check duplicate listen URIs, excluding mex ones.
+
2010-06-17 Atsushi Enomoto <atsushi@ximian.com>
* ServiceHostBase.cs : retrieve MessageVersion and raise an error
{
DateTime start = DateTime.Now;
InitializeRuntime ();
+ for (int i = 0; i < ChannelDispatchers.Count; i++) {
+ // Skip ServiceMetadataExtension-based one. special case.
+ for (int j = i + 1; j < ChannelDispatchers.Count; j++) {
+ var cd1 = ChannelDispatchers [i];
+ var cd2 = ChannelDispatchers [j];
+ if (cd1.IsMex || cd2.IsMex)
+ continue;
+ if (cd1.Listener.Uri.Equals (cd2.Listener.Uri))
+ throw new InvalidOperationException ("Two or more service endpoints with different Binding instance are bound to the same listen URI.");
+ }
+ }
+
var waits = new List<ManualResetEvent> ();
foreach (var cd in ChannelDispatchers) {
var wait = new ManualResetEvent (false);
this.host = host;
}
- List<ChannelDispatcher> built_dispatchers = new List<ChannelDispatcher> ();
+ Dictionary<Binding,ChannelDispatcher> built_dispatchers = new Dictionary<Binding,ChannelDispatcher> ();
Dictionary<ServiceEndpoint, EndpointDispatcher> ep_to_dispatcher_ep = new Dictionary<ServiceEndpoint, EndpointDispatcher> ();
internal static Action<ChannelDispatcher> ChannelDispatcherSetter;
ServiceHostBase.CurrentServiceHostHack = null;
}
ep = cd.InitializeServiceEndpoint (serviceType, se);
- built_dispatchers.Add (cd);
+ built_dispatchers.Add (se.Binding, cd);
}
ep_to_dispatcher_ep[se] = ep;
return cd;
ChannelDispatcher FindExistingDispatcher (ServiceEndpoint se)
{
- return built_dispatchers.FirstOrDefault ((ChannelDispatcher cd) => (cd.Listener.Uri.Equals (se.ListenUri)) && cd.MessageVersion.Equals (se.Binding.MessageVersion));
+ return built_dispatchers.FirstOrDefault ((KeyValuePair<Binding,ChannelDispatcher> p) => se.Binding == p.Key).Value;
}
internal void ApplyDispatchBehaviors ()
+2010-06-18 Atsushi Enomoto <atsushi@ximian.com>
+
+ * ChannelDispatcherTest.cs : had to disable a test that regressed from
+ validating duplicate listen URI. Possible remedy is described too.
+
2010-04-05 Atsushi Enomoto <atsushi@ximian.com>
* EndpointAddressMessageFilterTest.cs :
}
[Test]
+ [Category ("NotWorking")]
+ // Validating duplicate listen URI causes this regression.
+ // Since it is niche, I rather fixed ServiceHostBase to introduce validation.
+ // It is probably because this code doesn't use ServiceEndpoint to build IChannelListener i.e. built without Binding.
+ // We can add an extra field to ChannelDispatcher to indicate that it is from ServiceEndpoint (i.e. with Binding),
+ // but it makes little sense especially for checking duplicate listen URIs. Duplicate listen URIs should be rejected anyways.
public void EndpointDispatcherAddTest8 ()
{
var uri = CreateAvailableUri ("http://localhost:37564");
try {
h.Open (TimeSpan.FromSeconds (10));
+ Assert.AreEqual (3, h.ChannelDispatchers.Count, "#0"); // TestContract, d, mex
Assert.IsTrue (listener.BeginAcceptChannelTried, "#1"); // while it throws NIE ...
Assert.IsFalse (listener.WaitForChannelTried, "#2");
Assert.IsNotNull (ed.DispatchRuntime, "#3");
+2010-06-18 Atsushi Enomoto <atsushi@ximian.com>
+
+ * ServiceHostTest.cs : improved endpoint tests and enabled them.
+
2010-06-18 Atsushi Enomoto <atsushi@ximian.com>
* ServiceHostTest.cs : fix AddServiceEndpoint tests to make sense.
[Test]
[ExpectedException (typeof (InvalidOperationException))]
- [Category ("NotWorking")]
public void AddServiceEndpoint2 ()
{
ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
[Test]
[ExpectedException (typeof (InvalidOperationException))]
- [Category ("NotWorking")]
public void AddServiceEndpoint2_2 ()
{
ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
[Test]
[ExpectedException (typeof (InvalidOperationException))]
- [Category ("NotWorking")] // If I blindly reject things like this, it will block Service[Debug|Metadata]Behavior functionality.
public void AddServiceEndpoint2_3 ()
{
- ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
- host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (Foo)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo")));
- host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (IMetadataExchange)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo")));
+ ServiceHost host = new ServiceHost (typeof (HogeFuga), new Uri ("http://localhost/echo"));
+ host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (IHoge)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo")));
+ host.Description.Endpoints.Add (new ServiceEndpoint (ContractDescription.GetContract (typeof (IFuga)), new BasicHttpBinding (), new EndpointAddress ("http://localhost/echo")));
// Different contracts unlike previous two cases.
// If two or more endpoints are bound to the same listen
host.Close (); // should not reach here. It is to make sure to close unexpectedly opened host.
}
+ [Test]
+ public void AddServiceEndpoint2_4 ()
+ {
+ ServiceHost host = new ServiceHost (typeof (HogeFuga), new Uri ("http://localhost:37564"));
+ var binding = new BasicHttpBinding ();
+ host.AddServiceEndpoint (typeof (IHoge), binding, new Uri ("http://localhost:37564"));
+ host.AddServiceEndpoint (typeof (IFuga), binding, new Uri ("http://localhost:37564"));
+
+ // Use the same binding, results in one ChannelDispatcher (actually two, for metadata/debug behavior).
+ host.Open ();
+ try {
+ Assert.AreEqual (2, host.ChannelDispatchers.Count, "#1");
+ foreach (ChannelDispatcher cd in host.ChannelDispatchers) {
+ if (cd.BindingName != binding.Name)
+ continue; // mex
+ Assert.AreEqual (2, cd.Endpoints.Count, "#2");
+ }
+ } finally {
+ host.Close ();
+ }
+ }
+
[Test]
[ExpectedException (typeof (InvalidOperationException))]
- [Category ("NotWorking")]
public void AddServiceEndpoint3 ()
{
ServiceHost host = new ServiceHost (typeof (Foo), new Uri ("http://localhost/echo"));
[OperationContract]
string Echo (string source);
}
+
+ [ServiceContract]
+ interface IHoge
+ {
+ [OperationContract]
+ void DoX ();
+ }
+
+ [ServiceContract]
+ interface IFuga
+ {
+ [OperationContract]
+ void DoY ();
+ }
+
+ class HogeFuga : IHoge, IFuga
+ {
+ public void DoX () {}
+ public void DoY () {}
+ }
class Baz : IBaz
{