Add contract existence check when calling AddServiceEndpoint(ServiceEndpoint).
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel / ServiceHostBaseTest.cs
1 //
2 // ServiceHostBaseTest.cs
3 //
4 // Author:
5 //      Igor Zelmanovich <igorz@mainsoft.com>
6 //
7 // Copyright (C) 2008 Mainsoft, Inc.  http://www.mainsoft.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Collections.Generic;
31 using System.Text;
32 using NUnit.Framework;
33 using System.ServiceModel;
34 using System.ServiceModel.Description;
35 using System.ServiceModel.Dispatcher;
36 using SMMessage = System.ServiceModel.Channels.Message;
37 using System.ServiceModel.Channels;
38
39 namespace MonoTests.System.ServiceModel
40 {
41         [TestFixture]
42         public class ServiceHostBaseTest
43         {
44                 class Poker : ServiceHostBase
45                 {
46                         public event EventHandler OnApplyConfiguration;
47
48                         protected override ServiceDescription CreateDescription (out IDictionary<string, ContractDescription> implementedContracts) {
49                                 implementedContracts = new Dictionary<string, ContractDescription> ();
50                                 ServiceDescription description = new ServiceDescription ();
51                                 description.ServiceType = typeof (MyService);
52                                 description.Behaviors.Add (new ServiceBehaviorAttribute ());
53                                 return description;
54                         }
55
56                         protected override void ApplyConfiguration () {
57                                 if (OnApplyConfiguration != null)
58                                         OnApplyConfiguration (this, EventArgs.Empty);
59                                 base.ApplyConfiguration ();
60                         }
61
62                         public void CallInitializeDescription () {
63                                 InitializeDescription (new UriSchemeKeyedCollection ());
64                         }
65
66                         protected override void InitializeRuntime () {
67                                 base.InitializeRuntime ();
68                         }
69
70                         public void CallInitializeRuntime () {
71                                 InitializeRuntime ();
72                         }
73
74                         public void DoAddBaseAddress (Uri uri)
75                         {
76                                 AddBaseAddress (uri);
77                         }
78                 }
79
80                 [Test]
81                 public void Ctor () {
82                         Poker host = new Poker ();
83
84                         Assert.AreEqual (null, host.Description, "Description");
85                         Assert.AreEqual (null, host.Authorization, "Authorization");
86                 }
87
88                 [Test]
89                 public void DefaultConfiguration () {
90                         Poker host = new Poker ();
91                         host.OnApplyConfiguration += delegate (object sender, EventArgs e) {
92                                 Assert.AreEqual (1, host.Description.Behaviors.Count, "Description.Behaviors.Count #1");
93                         };
94                         host.CallInitializeDescription ();
95
96                         Assert.AreEqual (true, host.Description.Behaviors.Count > 1, "Description.Behaviors.Count #2");
97
98                         Assert.IsNotNull (host.Description.Behaviors.Find<ServiceDebugBehavior> (), "ServiceDebugBehavior");
99                         Assert.IsNotNull (host.Description.Behaviors.Find<ServiceAuthorizationBehavior> (), "ServiceDebugBehavior");
100                         Assert.IsNotNull (host.Authorization, "Authorization #1");
101
102                         Assert.AreEqual (host.Description.Behaviors.Find<ServiceAuthorizationBehavior> (), host.Authorization, "Authorization #2");
103                 }
104
105                 [Test]
106                 [ExpectedException (typeof (InvalidOperationException))]
107                 public void ApplyConfigurationNoDescription () {
108                         CustomServiceHost customHost = new CustomServiceHost ();
109                         customHost.ApplyConfiguration ();
110                 }
111
112                 class CustomServiceHost : ServiceHostBase
113                 {
114
115                         public CustomServiceHost () {
116
117                         }
118
119                         public new void ApplyConfiguration () {
120                                 base.ApplyConfiguration ();
121                         }
122
123                         protected override ServiceDescription CreateDescription (out IDictionary<string, ContractDescription> implementedContracts) {
124                                 throw new NotImplementedException ();
125                         }
126                 }
127
128                 [Test]
129                 public void InitializeRuntime () {
130                         Poker host = new Poker ();
131                         host.CallInitializeDescription ();
132                         EndpointAddress address = new EndpointAddress ("http://localhost:8090/");
133                         ContractDescription contract = ContractDescription.GetContract (typeof (IMyContract));
134                         ServiceEndpoint endpoint = new ServiceEndpoint (contract, new BasicHttpBinding (), address);
135                         endpoint.ListenUri = address.Uri;
136                         host.Description.Endpoints.Add (endpoint);
137
138                         Assert.AreEqual (0, host.ChannelDispatchers.Count, "ChannelDispatchers.Count #1");
139
140                         host.CallInitializeRuntime ();
141
142                         Assert.AreEqual (1, host.ChannelDispatchers.Count, "ChannelDispatchers.Count #1");
143                         Assert.AreEqual (CommunicationState.Created, host.ChannelDispatchers [0].State, "ChannelDispatchers.Count #1");
144                 }
145
146                 [ServiceContract]
147                 interface IMyContract
148                 {
149                         [OperationContract]
150                         string GetData ();
151                 }
152
153                 class MyService : IMyContract
154                 {
155                         public string GetData () {
156                                 return "Hello World";
157                         }
158                 }
159
160                 [Test]
161                 public void ChannelDispatchers_NoDebug () {
162                         ServiceHost h = new ServiceHost (typeof (AllActions), new Uri ("http://localhost:8080"));
163                         h.AddServiceEndpoint (typeof (AllActions).FullName, new BasicHttpBinding (), "address");
164
165                         ServiceDebugBehavior b = h.Description.Behaviors.Find<ServiceDebugBehavior> ();
166                         b.HttpHelpPageEnabled = false;                                          
167
168                         h.Open ();
169                         try {
170                         Assert.AreEqual (h.ChannelDispatchers.Count, 1);
171                         ChannelDispatcher channelDispatcher =  h.ChannelDispatchers[0] as ChannelDispatcher;
172                         Assert.IsNotNull (channelDispatcher, "#1");
173                         Assert.IsTrue (channelDispatcher.Endpoints.Count == 1, "#2");
174                         EndpointAddressMessageFilter filter = channelDispatcher.Endpoints [0].AddressFilter as EndpointAddressMessageFilter;
175                         Assert.IsNotNull (filter, "#3");
176                         Assert.IsTrue (filter.Address.Equals (new EndpointAddress ("http://localhost:8080/address")), "#4");
177                         Assert.IsFalse (filter.IncludeHostNameInComparison, "#5");
178                         Assert.IsTrue (channelDispatcher.Endpoints [0].ContractFilter is MatchAllMessageFilter, "#6");
179                         } finally {
180                         h.Close ();
181                         }
182                 }
183
184                 [Test]
185                 public void ChannelDispatchers_WithDebug () {
186                         ServiceHost h = new ServiceHost (typeof (AllActions), new Uri ("http://localhost:8080"));
187                         h.AddServiceEndpoint (typeof (AllActions).FullName, new BasicHttpBinding (), "address");
188                         ServiceMetadataBehavior b = new ServiceMetadataBehavior ();
189                         b.HttpGetEnabled = true;
190                         b.HttpGetUrl = new Uri( "http://localhost:8080" );
191                         h.Description.Behaviors.Add (b);
192                         h.Open ();
193
194                         Assert.AreEqual (h.ChannelDispatchers.Count, 2, "#1");
195                         ChannelDispatcher channelDispatcher = h.ChannelDispatchers[1] as ChannelDispatcher;
196                         Assert.IsNotNull (channelDispatcher, "#2");
197                         Assert.IsTrue (channelDispatcher.Endpoints.Count == 1, "#3");
198                         EndpointAddressMessageFilter filter = channelDispatcher.Endpoints [0].AddressFilter as EndpointAddressMessageFilter;
199                         Assert.IsNotNull (filter, "#4");
200                         Assert.IsTrue (filter.Address.Equals (new EndpointAddress ("http://localhost:8080")), "#5");
201                         Assert.IsFalse (filter.IncludeHostNameInComparison, "#6");
202                         Assert.IsTrue (channelDispatcher.Endpoints [0].ContractFilter is MatchAllMessageFilter, "#7");
203                         h.Close ();
204                 }
205
206                 [Test]
207                 public void SpecificActionTest ()
208                 {
209                         //EndpointDispatcher d = new EndpointDispatcher(
210                         ServiceHost h = new ServiceHost (typeof (SpecificAction), new Uri ("http://localhost:8080"));
211                         h.AddServiceEndpoint (typeof (Action1Interface), new BasicHttpBinding (), "address");
212                                                 
213                         h.Open ();
214                         ChannelDispatcher d = h.ChannelDispatchers [0] as ChannelDispatcher;
215                         EndpointDispatcher ed = d.Endpoints [0] as EndpointDispatcher;
216                         ActionMessageFilter actionFilter = ed.ContractFilter as ActionMessageFilter;
217                         Assert.IsNotNull (actionFilter, "#1");
218                         Assert.IsTrue (actionFilter.Actions.Count == 1, "#2");
219                         h.Close();
220                 }
221
222                 [Test]
223                 public void InitializeRuntimeBehaviors1 () {
224                         HostState st = new HostState ();
225                         ServiceHost h = new ServiceHost (typeof (SpecificAction2), new Uri ("http://localhost:8080"));
226                         h.AddServiceEndpoint (typeof (SpecificAction2), new BasicHttpBinding (), "temp");                       
227
228                         h.Description.Behaviors.Add (new MyServiceBehavior (st, h));
229
230                         h.Description.Endpoints [0].Behaviors.Add (new MyEndpointBehavior (st, h));
231                         h.Description.Endpoints [0].Contract.Behaviors.Add (new MyContractBehavior (st, h));
232                         h.Description.Endpoints [0].Contract.Operations [0].Behaviors.Add (new MyOperationBehavior (st, h));
233                         
234                         h.Open ();
235                         h.Close ();
236                         
237                         string expected = "Start, IServiceBehavior.Validate, IContractBehavior.Validate, IEndpointBehavior.Validate, IOperationBehavior.ApplyDispatchBehavior, IServiceBehavior.AddBindingParameters, IContractBehavior.AddBindingParameters, IEndpointBehavior.AddBindingParameters, IOperationBehavior.AddBindingParameters, IServiceBehavior.ApplyDispatchBehavior, IContractBehavior.ApplyDispatchBehavior, IEndpointBehavior.ApplyDispatchBehavior, IOperationBehavior.ApplyDispatchBehavior";
238                         Assert.AreEqual (expected, st.CurrentStage);
239                 }
240
241                 [Test]
242                 public void InitializeRuntimeBehaviors2 () {
243                         HostState st = new HostState ();
244                         ServiceHost h = new ServiceHost (typeof (SpecificAction), new Uri ("http://localhost:8080"));
245                         h.AddServiceEndpoint (typeof (Action1Interface), new BasicHttpBinding (), "temp");
246                         h.AddServiceEndpoint (typeof (Action2Interface), new BasicHttpBinding (), "temp2");
247
248                         h.Description.Behaviors.Add (new MyServiceBehavior (st, h));                    
249                         
250                         h.Description.Endpoints [0].Behaviors.Add (new MyEndpointBehavior (st, h));
251                         h.Description.Endpoints [0].Contract.Behaviors.Add (new MyContractBehavior (st, h));
252                         h.Description.Endpoints [0].Contract.Operations [0].Behaviors.Add (new MyOperationBehavior (st, h));
253
254                         h.Description.Endpoints [1].Behaviors.Add (new MyEndpointBehavior (st, h));
255                         h.Description.Endpoints [1].Contract.Behaviors.Add (new MyContractBehavior (st, h));
256                         h.Description.Endpoints [1].Contract.Operations [0].Behaviors.Add (new MyOperationBehavior (st, h));
257                         h.Open ();
258                         h.Close ();
259
260                         string expected = "Start, IServiceBehavior.Validate, IContractBehavior.Validate, IEndpointBehavior.Validate, IOperationBehavior.ApplyDispatchBehavior, IContractBehavior.Validate, IEndpointBehavior.Validate, IOperationBehavior.ApplyDispatchBehavior, IServiceBehavior.AddBindingParameters, IContractBehavior.AddBindingParameters, IEndpointBehavior.AddBindingParameters, IOperationBehavior.AddBindingParameters, IServiceBehavior.AddBindingParameters, IContractBehavior.AddBindingParameters, IEndpointBehavior.AddBindingParameters, IOperationBehavior.AddBindingParameters, IServiceBehavior.ApplyDispatchBehavior, IContractBehavior.ApplyDispatchBehavior, IEndpointBehavior.ApplyDispatchBehavior, IOperationBehavior.ApplyDispatchBehavior, IContractBehavior.ApplyDispatchBehavior, IEndpointBehavior.ApplyDispatchBehavior, IOperationBehavior.ApplyDispatchBehavior";
261                         Assert.AreEqual (expected, st.CurrentStage);
262                 }
263
264                 [Test]
265                 public void AddBaseAddress ()
266                 {
267                         var host = new Poker ();
268                         Assert.AreEqual (0, host.BaseAddresses.Count, "#1");
269                         host.DoAddBaseAddress (new Uri ("http://localhost:37564"));
270                         Assert.AreEqual (1, host.BaseAddresses.Count, "#1");
271                         host.DoAddBaseAddress (new Uri ("net.tcp://localhost:893"));
272                         Assert.AreEqual (2, host.BaseAddresses.Count, "#1");
273                 }
274
275                 [Test]
276                 [ExpectedException (typeof (ArgumentException))]
277                 public void AddBaseAddress2 ()
278                 {
279                         var host = new Poker ();
280                         Assert.AreEqual (0, host.BaseAddresses.Count, "#1");
281                         host.DoAddBaseAddress (new Uri ("http://localhost:37564"));
282                         // http base address is already added.
283                         host.DoAddBaseAddress (new Uri ("http://localhost:893"));
284                 }
285
286                 [Test]
287                 public void AddServiceEndpointUri ()
288                 {
289                         var host = new ServiceHost (typeof (AllActions),
290                                 new Uri ("http://localhost:37564"));
291                         var se = host.AddServiceEndpoint (typeof (AllActions),
292                                 new BasicHttpBinding (), "foobar");
293                         Assert.AreEqual ("http://localhost:37564/foobar", se.Address.Uri.AbsoluteUri, "#1");
294                         Assert.AreEqual ("http://localhost:37564/foobar", se.ListenUri.AbsoluteUri, "#2");
295                 }
296
297                 [Test]
298                 public void AddServiceEndpointUri2 ()
299                 {
300                         var host = new ServiceHost (typeof (AllActions),
301                                 new Uri ("http://localhost:37564"));
302                         var se = host.AddServiceEndpoint (typeof (AllActions),
303                                 new BasicHttpBinding (), String.Empty);
304                         Assert.AreEqual ("http://localhost:37564/", se.Address.Uri.AbsoluteUri, "#1");
305                         Assert.AreEqual ("http://localhost:37564/", se.ListenUri.AbsoluteUri, "#2");
306                 }
307
308                 [Test]
309                 [ExpectedException (typeof (InvalidOperationException))]
310                 public void AddServiceEndpointOnlyMex ()
311                 {
312                         var host = new ServiceHost (typeof (AllActions),
313                                 new Uri ("http://localhost:37564"));
314                         host.Description.Behaviors.Add (new ServiceMetadataBehavior ());
315                         host.AddServiceEndpoint ("IMetadataExchange",
316                                 new BasicHttpBinding (), "/wsdl");
317                         host.Open ();
318                         try {
319                                 // to make sure that throwing IOE from here does not count.
320                                 host.Close ();
321                         } catch {
322                         }
323                         Assert.Fail ("should not open");
324                 }
325
326                 [Test]
327                 public void RunDestinationUnreachableTest ()
328                 {
329                         RunDestinationUnreachableTest ("BasicHttp", new BasicHttpBinding ());
330                 }
331
332                 [Test]
333                 public void RunDestinationUnreachableTest2 ()
334                 {
335                         RunDestinationUnreachableTest ("CustomSoap12", new CustomBinding (new HttpTransportBindingElement ()));
336                 }
337
338                 void RunDestinationUnreachableTest (string label, Binding binding)
339                 {
340                         string address = "http://localhost:37564/";
341                         var host = OpenHost (address, binding);
342                         
343                         try {
344                                 var client = new DestinationUnreachableClient (binding, address);
345                                 client.NotImplementedOperation ();
346                                 Assert.Fail (label + " ActionNotSupportedException is expected");
347                         } catch (ActionNotSupportedException) {
348                                 // catching it instead of ExpectedException to distinguish errors at service side.
349                         } finally {
350                                 host.Close ();
351                         }
352                 }
353                 
354                 ServiceHost OpenHost (string address, Binding binding)
355                 {
356                         var baseAddresses = new Uri[] { new Uri(address) };
357
358                         var host = new ServiceHost (typeof (DummyService), baseAddresses);
359                         host.AddServiceEndpoint (typeof (IDummyService), binding, new Uri ("", UriKind.Relative));
360                         host.Open ();
361                         return host;
362                 }
363
364 #if NET_4_0
365                 [Test]
366                 [ExpectedException (typeof (InvalidOperationException))]
367                 public void AddServiceEndpoint_Directly_ContractMismatch ()
368                 {
369                         var host = new ServiceHost (typeof (DummyService));
370                         var address = new EndpointAddress ("http://localhost:8080");
371                         var binding = new BasicHttpBinding ();
372                         var contract = ContractDescription.GetContract (typeof (INotImplementedService));
373                         host.AddServiceEndpoint (new ServiceEndpoint (contract, binding, address));
374                 }
375 #endif
376
377                 #region helpers
378
379                 public enum Stage
380                 {
381                 }
382
383                 public class HostState
384                 {
385                         public string CurrentStage = "Start";
386                 }
387
388                 public class MyServiceBehavior : IServiceBehavior
389                 {
390                         #region IServiceBehavior Members
391
392                         HostState _state;
393                         ServiceHost _host;
394                         public MyServiceBehavior (HostState state, ServiceHost h) {
395                                 _state = state;
396                                 _host = h;
397                         }
398
399                         public void AddBindingParameters (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, global::System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) {                         
400                                 _state.CurrentStage += ", IServiceBehavior.AddBindingParameters";                               
401                                 bindingParameters.Add (this);
402                         }
403
404                         public void ApplyDispatchBehavior (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {                            
405                                 _state.CurrentStage += ", IServiceBehavior.ApplyDispatchBehavior";                              
406                         }
407
408                         public void Validate (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
409                                 _state.CurrentStage += ", IServiceBehavior.Validate";
410                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);
411                         }
412
413                         #endregion
414                 }
415
416                 public class MyEndpointBehavior : IEndpointBehavior
417                 {
418                         #region IEndpointBehavior Members
419                         HostState _state;
420                         ServiceHost _host;
421                         public MyEndpointBehavior (HostState state, ServiceHost h) {
422                                 _state = state;
423                                 _host = h;
424                         }
425
426                         public void AddBindingParameters (ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) {
427                                 Console.WriteLine ("IEndpointBehavior - AddBindingParameters " + _host.ChannelDispatchers.Count);
428                                 _state.CurrentStage += ", IEndpointBehavior.AddBindingParameters";                              
429                                 bindingParameters.Add (this);
430                         }
431
432                         public void ApplyClientBehavior (ServiceEndpoint endpoint, ClientRuntime clientRuntime) {
433                                 Console.WriteLine ("IEndpointBehavior - ApplyClientBehavior " + _host.ChannelDispatchers.Count);
434                         }
435
436                         public void ApplyDispatchBehavior (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) {
437                                 Console.WriteLine ("IEndpointBehavior - ApplyDispatchBehavior " + _host.ChannelDispatchers.Count);
438                                 _state.CurrentStage += ", IEndpointBehavior.ApplyDispatchBehavior";                             
439                         }
440
441                         public void Validate (ServiceEndpoint endpoint) {
442                                 Console.WriteLine ("IEndpointBehavior - Validate " + _host.ChannelDispatchers.Count);
443                                 _state.CurrentStage += ", IEndpointBehavior.Validate";
444                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);                            
445                         }
446
447                         #endregion
448                 }
449
450                 public class MyContractBehavior : IContractBehavior
451                 {
452                         #region IContractBehavior Members
453                         HostState _state;
454                         ServiceHost _host;
455                         public MyContractBehavior (HostState state, ServiceHost h) {
456                                 _state = state;
457                                 _host = h;
458                         }
459
460                         public void AddBindingParameters (ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) {
461                                 Console.WriteLine ("Contract - AddBindingParameters " + _host.ChannelDispatchers.Count);
462                                 _state.CurrentStage += ", IContractBehavior.AddBindingParameters";                              
463                                 bindingParameters.Add (this);
464                         }
465
466                         public void ApplyClientBehavior (ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) {
467                                 Console.WriteLine ("Contract - ApplyClientBehavior " + _host.ChannelDispatchers.Count);
468                         }
469
470                         public void ApplyDispatchBehavior (ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) {
471                                 Console.WriteLine ("Contract - ApplyDispatchBehavior " + _host.ChannelDispatchers.Count);
472                                 _state.CurrentStage += ", IContractBehavior.ApplyDispatchBehavior";                             
473                         }
474
475                         public void Validate (ContractDescription contractDescription, ServiceEndpoint endpoint) {
476                                 Console.WriteLine ("Contract - Validate " + _host.ChannelDispatchers.Count);
477                                 _state.CurrentStage += ", IContractBehavior.Validate";          
478                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);                            
479                         }
480
481                         #endregion
482                 }
483
484                 public class MyOperationBehavior : IOperationBehavior
485                 {
486                         #region IOperationBehavior Members
487                         HostState _state;
488                         ServiceHost _host;
489                         public MyOperationBehavior (HostState state, ServiceHost h) {
490                                 _state = state;
491                                 _host = h;
492                         }
493
494                         public void AddBindingParameters (OperationDescription operationDescription, BindingParameterCollection bindingParameters) {
495                                 Console.WriteLine ("IOperationBehavior - AddBindingParameters " + _host.ChannelDispatchers.Count);
496                                 _state.CurrentStage += ", IOperationBehavior.AddBindingParameters";                                     
497                                 bindingParameters.Add (this);
498                         }
499
500                         public void ApplyClientBehavior (OperationDescription operationDescription, ClientOperation clientOperation) {
501                                 Console.WriteLine ("IOperationBehavior - ApplyClientBehavior " + _host.ChannelDispatchers.Count);
502                         }
503
504                         public void ApplyDispatchBehavior (OperationDescription operationDescription, DispatchOperation dispatchOperation) {
505                                 Console.WriteLine ("IOperationBehavior - ApplyDispatchBehavior " + _host.ChannelDispatchers.Count);
506                                 _state.CurrentStage += ", IOperationBehavior.ApplyDispatchBehavior";                            
507                         }
508
509                         public void Validate (OperationDescription operationDescription) {
510                                 Console.WriteLine ("IOperationBehavior - Validate " + _host.ChannelDispatchers.Count);
511                                 _state.CurrentStage += ", IOperationBehavior.ApplyDispatchBehavior";
512                                 Assert.AreEqual (_host.ChannelDispatchers.Count, 0);
513                         }
514
515                         #endregion
516                 }
517
518                 [ServiceContract]
519                 class AllActions
520                 {
521                         [OperationContract (Action = "*", ReplyAction = "*")]
522                         public SMMessage Get (SMMessage req) {
523                                 return null;
524                         }
525                 }
526
527                 [ServiceContract]
528                 interface Action1Interface
529                 {
530                         [OperationContract (Action = "Specific1", ReplyAction = "*")]
531                         SMMessage GetMessage1 (SMMessage req);
532                 }
533
534                 [ServiceContract]
535                 interface Action2Interface
536                 {
537                         [OperationContract (Action = "Specific2", ReplyAction = "*")]
538                         SMMessage GetMessage2 (SMMessage req);
539                 }
540                 
541                 class SpecificAction : Action1Interface, Action2Interface
542                 {                       
543                         public SMMessage GetMessage1 (SMMessage req) {
544                                 return null;
545                         }
546
547                         public SMMessage GetMessage2 (SMMessage req) {
548                                 return null;
549                         }
550                 }
551
552                 [ServiceContract]
553                 class SpecificAction2
554                 {
555                         [OperationContract (Action = "Specific", ReplyAction = "*")]
556                         public SMMessage GetMessage1 (SMMessage req) {
557                                 return null;
558                         }
559                 }
560
561                 class MyChannelDispatcher : ChannelDispatcher
562                 {
563                         public bool Attached = false;
564
565                         public MyChannelDispatcher (IChannelListener l) : base (l) { }
566                         protected override void Attach (ServiceHostBase host) {
567                                 base.Attach (host);
568                                 Attached = true;
569                         }
570                 }
571
572                 class MyChannelListener : IChannelListener
573                 {
574                         #region IChannelListener Members
575
576                         public IAsyncResult BeginWaitForChannel (TimeSpan timeout, AsyncCallback callback, object state) {
577                                 throw new NotImplementedException ();
578                         }
579
580                         public bool EndWaitForChannel (IAsyncResult result) {
581                                 throw new NotImplementedException ();
582                         }
583
584                         public T GetProperty<T> () where T : class {
585                                 throw new NotImplementedException ();
586                         }
587
588                         public Uri Uri {
589                                 get { throw new NotImplementedException (); }
590                         }
591
592                         public bool WaitForChannel (TimeSpan timeout) {
593                                 throw new NotImplementedException ();
594                         }
595
596                         #endregion
597
598                         #region ICommunicationObject Members
599
600                         public void Abort () {
601                                 throw new NotImplementedException ();
602                         }
603
604                         public IAsyncResult BeginClose (TimeSpan timeout, AsyncCallback callback, object state) {
605                                 throw new NotImplementedException ();
606                         }
607
608                         public IAsyncResult BeginClose (AsyncCallback callback, object state) {
609                                 throw new NotImplementedException ();
610                         }
611
612                         public IAsyncResult BeginOpen (TimeSpan timeout, AsyncCallback callback, object state) {
613                                 throw new NotImplementedException ();
614                         }
615
616                         public IAsyncResult BeginOpen (AsyncCallback callback, object state) {
617                                 throw new NotImplementedException ();
618                         }
619
620                         public void Close (TimeSpan timeout) {
621                                 throw new NotImplementedException ();
622                         }
623
624                         public void Close () {
625                                 throw new NotImplementedException ();
626                         }
627
628                         public event EventHandler Closed;
629
630                         public event EventHandler Closing;
631
632                         public void EndClose (IAsyncResult result) {
633                                 throw new NotImplementedException ();
634                         }
635
636                         public void EndOpen (IAsyncResult result) {
637                                 throw new NotImplementedException ();
638                         }
639
640                         public event EventHandler Faulted;
641
642                         public void Open (TimeSpan timeout) {
643                                 throw new NotImplementedException ();
644                         }
645
646                         public void Open () {
647                                 throw new NotImplementedException ();
648                         }
649
650                         public event EventHandler Opened;
651
652                         public event EventHandler Opening;
653
654                         public CommunicationState State {
655                                 get { throw new NotImplementedException (); }
656                         }
657
658                         #endregion
659                 }
660
661                 [ServiceContract]
662                 public interface IDummyService
663                 {
664                         [OperationContract]
665                         void DummyOperation ();
666                 }
667                 public class DummyService : IDummyService
668                 {
669                         public void DummyOperation ()
670                         {
671                                 // Do nothing
672                         }
673                 }
674                 [ServiceContract]
675                 public interface INotImplementedService
676                 {
677                         [OperationContract]
678                         void NotImplementedOperation ();
679                 }
680                 public class DestinationUnreachableClient : ClientBase<INotImplementedService>, INotImplementedService
681                 {
682                         public void NotImplementedOperation ()
683                         {
684                                 Channel.NotImplementedOperation ();
685                         }
686                 
687                         public DestinationUnreachableClient (Binding binding, string address) 
688                                 : base (binding, new EndpointAddress (address))
689                         {
690                         }
691                 }
692
693                 #endregion
694         }
695 }