ServiceChannelFactory.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System.Collections.Generic;
  7. using System.Diagnostics;
  8. using System.Runtime;
  9. using System.Runtime.Remoting;
  10. using System.Security;
  11. using System.ServiceModel;
  12. using System.ServiceModel.Description;
  13. using System.ServiceModel.Diagnostics;
  14. using System.ServiceModel.Dispatcher;
  15. abstract class ServiceChannelFactory : ChannelFactoryBase
  16. {
  17. string bindingName;
  18. List<IChannel> channelsList;
  19. ClientRuntime clientRuntime;
  20. RequestReplyCorrelator requestReplyCorrelator = new RequestReplyCorrelator();
  21. IDefaultCommunicationTimeouts timeouts;
  22. MessageVersion messageVersion;
  23. public ServiceChannelFactory(ClientRuntime clientRuntime, Binding binding)
  24. : base()
  25. {
  26. if (clientRuntime == null)
  27. {
  28. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("clientRuntime");
  29. }
  30. this.bindingName = binding.Name;
  31. this.channelsList = new List<IChannel>();
  32. this.clientRuntime = clientRuntime;
  33. this.timeouts = new DefaultCommunicationTimeouts(binding);
  34. this.messageVersion = binding.MessageVersion;
  35. }
  36. public ClientRuntime ClientRuntime
  37. {
  38. get
  39. {
  40. this.ThrowIfDisposed();
  41. return this.clientRuntime;
  42. }
  43. }
  44. internal RequestReplyCorrelator RequestReplyCorrelator
  45. {
  46. get
  47. {
  48. ThrowIfDisposed();
  49. return this.requestReplyCorrelator;
  50. }
  51. }
  52. protected override TimeSpan DefaultCloseTimeout
  53. {
  54. get { return this.timeouts.CloseTimeout; }
  55. }
  56. protected override TimeSpan DefaultReceiveTimeout
  57. {
  58. get { return this.timeouts.ReceiveTimeout; }
  59. }
  60. protected override TimeSpan DefaultOpenTimeout
  61. {
  62. get { return this.timeouts.OpenTimeout; }
  63. }
  64. protected override TimeSpan DefaultSendTimeout
  65. {
  66. get { return this.timeouts.SendTimeout; }
  67. }
  68. public MessageVersion MessageVersion
  69. {
  70. get { return this.messageVersion; }
  71. }
  72. // special overload for security only
  73. public static ServiceChannelFactory BuildChannelFactory(ChannelBuilder channelBuilder, ClientRuntime clientRuntime)
  74. {
  75. if (channelBuilder.CanBuildChannelFactory<IDuplexChannel>())
  76. {
  77. return new ServiceChannelFactoryOverDuplex(channelBuilder.BuildChannelFactory<IDuplexChannel>(), clientRuntime,
  78. channelBuilder.Binding);
  79. }
  80. else if (channelBuilder.CanBuildChannelFactory<IDuplexSessionChannel>())
  81. {
  82. return new ServiceChannelFactoryOverDuplexSession(channelBuilder.BuildChannelFactory<IDuplexSessionChannel>(), clientRuntime, channelBuilder.Binding, false);
  83. }
  84. else
  85. {
  86. return new ServiceChannelFactoryOverRequestSession(channelBuilder.BuildChannelFactory<IRequestSessionChannel>(), clientRuntime, channelBuilder.Binding, false);
  87. }
  88. }
  89. public static ServiceChannelFactory BuildChannelFactory(ServiceEndpoint serviceEndpoint)
  90. {
  91. return BuildChannelFactory(serviceEndpoint, false);
  92. }
  93. public static ServiceChannelFactory BuildChannelFactory(ServiceEndpoint serviceEndpoint, bool useActiveAutoClose)
  94. {
  95. if (serviceEndpoint == null)
  96. {
  97. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceEndpoint");
  98. }
  99. serviceEndpoint.EnsureInvariants();
  100. serviceEndpoint.ValidateForClient();
  101. ChannelRequirements requirements;
  102. ContractDescription contractDescription = serviceEndpoint.Contract;
  103. ChannelRequirements.ComputeContractRequirements(contractDescription, out requirements);
  104. BindingParameterCollection parameters;
  105. ClientRuntime clientRuntime = DispatcherBuilder.BuildProxyBehavior(serviceEndpoint, out parameters);
  106. Binding binding = serviceEndpoint.Binding;
  107. Type[] requiredChannels = ChannelRequirements.ComputeRequiredChannels(ref requirements);
  108. CustomBinding customBinding = new CustomBinding(binding);
  109. BindingContext context = new BindingContext(customBinding, parameters);
  110. InternalDuplexBindingElement internalDuplexBindingElement = null;
  111. InternalDuplexBindingElement.AddDuplexFactorySupport(context, ref internalDuplexBindingElement);
  112. customBinding = new CustomBinding(context.RemainingBindingElements);
  113. customBinding.CopyTimeouts(serviceEndpoint.Binding);
  114. foreach (Type type in requiredChannels)
  115. {
  116. if (type == typeof(IOutputChannel) && customBinding.CanBuildChannelFactory<IOutputChannel>(parameters))
  117. {
  118. return new ServiceChannelFactoryOverOutput(customBinding.BuildChannelFactory<IOutputChannel>(parameters), clientRuntime, binding);
  119. }
  120. if (type == typeof(IRequestChannel) && customBinding.CanBuildChannelFactory<IRequestChannel>(parameters))
  121. {
  122. return new ServiceChannelFactoryOverRequest(customBinding.BuildChannelFactory<IRequestChannel>(parameters), clientRuntime, binding);
  123. }
  124. if (type == typeof(IDuplexChannel) && customBinding.CanBuildChannelFactory<IDuplexChannel>(parameters))
  125. {
  126. if (requirements.usesReply &&
  127. binding.CreateBindingElements().Find<TransportBindingElement>().ManualAddressing)
  128. {
  129. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
  130. SR.GetString(SR.CantCreateChannelWithManualAddressing)));
  131. }
  132. return new ServiceChannelFactoryOverDuplex(customBinding.BuildChannelFactory<IDuplexChannel>(parameters), clientRuntime, binding);
  133. }
  134. if (type == typeof(IOutputSessionChannel) && customBinding.CanBuildChannelFactory<IOutputSessionChannel>(parameters))
  135. {
  136. return new ServiceChannelFactoryOverOutputSession(customBinding.BuildChannelFactory<IOutputSessionChannel>(parameters), clientRuntime, binding, false);
  137. }
  138. if (type == typeof(IRequestSessionChannel) && customBinding.CanBuildChannelFactory<IRequestSessionChannel>(parameters))
  139. {
  140. return new ServiceChannelFactoryOverRequestSession(customBinding.BuildChannelFactory<IRequestSessionChannel>(parameters), clientRuntime, binding, false);
  141. }
  142. if (type == typeof(IDuplexSessionChannel) && customBinding.CanBuildChannelFactory<IDuplexSessionChannel>(parameters))
  143. {
  144. if (requirements.usesReply &&
  145. binding.CreateBindingElements().Find<TransportBindingElement>().ManualAddressing)
  146. {
  147. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
  148. SR.GetString(SR.CantCreateChannelWithManualAddressing)));
  149. }
  150. return new ServiceChannelFactoryOverDuplexSession(customBinding.BuildChannelFactory<IDuplexSessionChannel>(parameters), clientRuntime, binding, useActiveAutoClose);
  151. }
  152. }
  153. foreach (Type type in requiredChannels)
  154. {
  155. // For SessionMode.Allowed or SessionMode.NotAllowed we will accept session-ful variants as well
  156. if (type == typeof(IOutputChannel) && customBinding.CanBuildChannelFactory<IOutputSessionChannel>(parameters))
  157. {
  158. return new ServiceChannelFactoryOverOutputSession(customBinding.BuildChannelFactory<IOutputSessionChannel>(parameters), clientRuntime, binding, true);
  159. }
  160. if (type == typeof(IRequestChannel) && customBinding.CanBuildChannelFactory<IRequestSessionChannel>(parameters))
  161. {
  162. return new ServiceChannelFactoryOverRequestSession(customBinding.BuildChannelFactory<IRequestSessionChannel>(parameters), clientRuntime, binding, true);
  163. }
  164. // and for SessionMode.Required, it is possible that the InstanceContextProvider is handling the session management, so
  165. // accept datagram variants if that is the case
  166. if (type == typeof(IRequestSessionChannel) && customBinding.CanBuildChannelFactory<IRequestChannel>(parameters)
  167. && customBinding.GetProperty<IContextSessionProvider>(parameters) != null)
  168. {
  169. return new ServiceChannelFactoryOverRequest(customBinding.BuildChannelFactory<IRequestChannel>(parameters), clientRuntime, binding);
  170. }
  171. }
  172. // we put a lot of work into creating a good error message, as this is a common case
  173. Dictionary<Type, byte> supportedChannels = new Dictionary<Type, byte>();
  174. if (customBinding.CanBuildChannelFactory<IOutputChannel>(parameters))
  175. {
  176. supportedChannels.Add(typeof(IOutputChannel), 0);
  177. }
  178. if (customBinding.CanBuildChannelFactory<IRequestChannel>(parameters))
  179. {
  180. supportedChannels.Add(typeof(IRequestChannel), 0);
  181. }
  182. if (customBinding.CanBuildChannelFactory<IDuplexChannel>(parameters))
  183. {
  184. supportedChannels.Add(typeof(IDuplexChannel), 0);
  185. }
  186. if (customBinding.CanBuildChannelFactory<IOutputSessionChannel>(parameters))
  187. {
  188. supportedChannels.Add(typeof(IOutputSessionChannel), 0);
  189. }
  190. if (customBinding.CanBuildChannelFactory<IRequestSessionChannel>(parameters))
  191. {
  192. supportedChannels.Add(typeof(IRequestSessionChannel), 0);
  193. }
  194. if (customBinding.CanBuildChannelFactory<IDuplexSessionChannel>(parameters))
  195. {
  196. supportedChannels.Add(typeof(IDuplexSessionChannel), 0);
  197. }
  198. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ChannelRequirements.CantCreateChannelException(
  199. supportedChannels.Keys, requiredChannels, binding.Name));
  200. }
  201. protected override void OnAbort()
  202. {
  203. IChannel channel = null;
  204. lock (ThisLock)
  205. {
  206. channel = (channelsList.Count > 0) ? channelsList[channelsList.Count - 1] : null;
  207. }
  208. while (channel != null)
  209. {
  210. channel.Abort();
  211. lock (ThisLock)
  212. {
  213. channelsList.Remove(channel);
  214. channel = (channelsList.Count > 0) ? channelsList[channelsList.Count - 1] : null;
  215. }
  216. }
  217. }
  218. protected override void OnClose(TimeSpan timeout)
  219. {
  220. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  221. while (true)
  222. {
  223. int count;
  224. IChannel channel;
  225. lock (ThisLock)
  226. {
  227. count = channelsList.Count;
  228. if (count == 0)
  229. return;
  230. channel = channelsList[0];
  231. }
  232. channel.Close(timeoutHelper.RemainingTime());
  233. }
  234. }
  235. protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  236. {
  237. List<ICommunicationObject> objectList;
  238. lock (ThisLock)
  239. {
  240. objectList = new List<ICommunicationObject>();
  241. for (int index = 0; index < channelsList.Count; index++)
  242. objectList.Add(channelsList[index]);
  243. }
  244. return new CloseCollectionAsyncResult(timeout, callback, state, objectList);
  245. }
  246. protected override void OnEndClose(IAsyncResult result)
  247. {
  248. CloseCollectionAsyncResult.End(result);
  249. }
  250. protected override void OnOpened()
  251. {
  252. base.OnOpened();
  253. this.clientRuntime.LockDownProperties();
  254. }
  255. public void ChannelCreated(IChannel channel)
  256. {
  257. if (DiagnosticUtility.ShouldTraceVerbose)
  258. {
  259. TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.ChannelCreated,
  260. SR.GetString(SR.TraceCodeChannelCreated, TraceUtility.CreateSourceString(channel)), this);
  261. }
  262. lock (ThisLock)
  263. {
  264. ThrowIfDisposed();
  265. channelsList.Add(channel);
  266. }
  267. }
  268. public void ChannelDisposed(IChannel channel)
  269. {
  270. if (DiagnosticUtility.ShouldTraceVerbose)
  271. {
  272. TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.ChannelDisposed,
  273. SR.GetString(SR.TraceCodeChannelDisposed, TraceUtility.CreateSourceString(channel)),
  274. this);
  275. }
  276. lock (ThisLock)
  277. {
  278. channelsList.Remove(channel);
  279. }
  280. }
  281. public virtual ServiceChannel CreateServiceChannel(EndpointAddress address, Uri via)
  282. {
  283. IChannelBinder binder = this.CreateInnerChannelBinder(address, via);
  284. ServiceChannel serviceChannel = new ServiceChannel(this, binder);
  285. if (binder is DuplexChannelBinder)
  286. {
  287. DuplexChannelBinder duplexChannelBinder = binder as DuplexChannelBinder;
  288. duplexChannelBinder.ChannelHandler = new ChannelHandler(this.messageVersion, binder, serviceChannel);
  289. duplexChannelBinder.DefaultCloseTimeout = this.DefaultCloseTimeout;
  290. duplexChannelBinder.DefaultSendTimeout = this.DefaultSendTimeout;
  291. duplexChannelBinder.IdentityVerifier = this.clientRuntime.IdentityVerifier;
  292. }
  293. return serviceChannel;
  294. }
  295. public TChannel CreateChannel<TChannel>(EndpointAddress address)
  296. {
  297. return this.CreateChannel<TChannel>(address, null);
  298. }
  299. public TChannel CreateChannel<TChannel>(EndpointAddress address, Uri via)
  300. {
  301. if (!this.CanCreateChannel<TChannel>())
  302. {
  303. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
  304. SR.GetString(SR.CouldnTCreateChannelForChannelType2, this.bindingName, typeof(TChannel).Name)));
  305. }
  306. return (TChannel)this.CreateChannel(typeof(TChannel), address, via);
  307. }
  308. public abstract bool CanCreateChannel<TChannel>();
  309. public object CreateChannel(Type channelType, EndpointAddress address)
  310. {
  311. return this.CreateChannel(channelType, address, null);
  312. }
  313. public object CreateChannel(Type channelType, EndpointAddress address, Uri via)
  314. {
  315. if (via == null)
  316. {
  317. via = this.ClientRuntime.Via;
  318. if (via == null)
  319. {
  320. via = address.Uri;
  321. }
  322. }
  323. ServiceChannel serviceChannel = this.CreateServiceChannel(address, via);
  324. serviceChannel.Proxy = CreateProxy(channelType, channelType, MessageDirection.Input, serviceChannel);
  325. serviceChannel.ClientRuntime.GetRuntime().InitializeChannel((IClientChannel)serviceChannel.Proxy);
  326. OperationContext current = OperationContext.Current;
  327. if ((current != null) && (current.InstanceContext != null))
  328. {
  329. current.InstanceContext.WmiChannels.Add((IChannel)serviceChannel.Proxy);
  330. serviceChannel.WmiInstanceContext = current.InstanceContext;
  331. }
  332. return serviceChannel.Proxy;
  333. }
  334. [Fx.Tag.SecurityNote(Critical = "Constructs a ServiceChannelProxy, which is Critical.",
  335. Safe = "Returns the TP, but does not return the RealProxy -- caller can't get from TP to RP without an elevation.")]
  336. [SecuritySafeCritical]
  337. internal static object CreateProxy(Type interfaceType, Type proxiedType, MessageDirection direction, ServiceChannel serviceChannel)
  338. {
  339. if (!proxiedType.IsInterface)
  340. {
  341. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxChannelFactoryTypeMustBeInterface")));
  342. }
  343. ServiceChannelProxy proxy = new ServiceChannelProxy(interfaceType, proxiedType, direction, serviceChannel);
  344. return proxy.GetTransparentProxy();
  345. }
  346. [Fx.Tag.SecurityNote(Critical = "Calls LinkDemand method RemotingServices.GetRealProxy and access critical class ServiceChannelProxy.",
  347. Safe = "Gets the ServiceChannel (which is not critical) and discards the RealProxy.")]
  348. [SecuritySafeCritical]
  349. internal static ServiceChannel GetServiceChannel(object transparentProxy)
  350. {
  351. IChannelBaseProxy cb = transparentProxy as IChannelBaseProxy;
  352. if (cb != null)
  353. return cb.GetServiceChannel();
  354. ServiceChannelProxy proxy = RemotingServices.GetRealProxy(transparentProxy) as ServiceChannelProxy;
  355. if (proxy != null)
  356. return proxy.GetServiceChannel();
  357. else
  358. return null;
  359. }
  360. protected abstract IChannelBinder CreateInnerChannelBinder(EndpointAddress address, Uri via);
  361. abstract class TypedServiceChannelFactory<TChannel> : ServiceChannelFactory
  362. where TChannel : class, IChannel
  363. {
  364. IChannelFactory<TChannel> innerChannelFactory;
  365. protected TypedServiceChannelFactory(IChannelFactory<TChannel> innerChannelFactory,
  366. ClientRuntime clientRuntime, Binding binding)
  367. : base(clientRuntime, binding)
  368. {
  369. this.innerChannelFactory = innerChannelFactory;
  370. }
  371. protected IChannelFactory<TChannel> InnerChannelFactory
  372. {
  373. get { return this.innerChannelFactory; }
  374. }
  375. protected override void OnAbort()
  376. {
  377. base.OnAbort();
  378. this.innerChannelFactory.Abort();
  379. }
  380. protected override void OnOpen(TimeSpan timeout)
  381. {
  382. this.innerChannelFactory.Open(timeout);
  383. }
  384. protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
  385. {
  386. return this.innerChannelFactory.BeginOpen(timeout, callback, state);
  387. }
  388. protected override void OnEndOpen(IAsyncResult result)
  389. {
  390. this.innerChannelFactory.EndOpen(result);
  391. }
  392. protected override void OnClose(TimeSpan timeout)
  393. {
  394. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  395. base.OnClose(timeoutHelper.RemainingTime());
  396. this.innerChannelFactory.Close(timeoutHelper.RemainingTime());
  397. }
  398. protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  399. {
  400. return new ChainedAsyncResult(timeout, callback, state, base.OnBeginClose, base.OnEndClose,
  401. this.innerChannelFactory.BeginClose, this.innerChannelFactory.EndClose);
  402. }
  403. protected override void OnEndClose(IAsyncResult result)
  404. {
  405. ChainedAsyncResult.End(result);
  406. }
  407. public override T GetProperty<T>()
  408. {
  409. if (typeof(T) == typeof(TypedServiceChannelFactory<TChannel>))
  410. {
  411. return (T)(object)this;
  412. }
  413. T baseProperty = base.GetProperty<T>();
  414. if (baseProperty != null)
  415. {
  416. return baseProperty;
  417. }
  418. return this.innerChannelFactory.GetProperty<T>();
  419. }
  420. }
  421. class ServiceChannelFactoryOverOutput : TypedServiceChannelFactory<IOutputChannel>
  422. {
  423. public ServiceChannelFactoryOverOutput(IChannelFactory<IOutputChannel> innerChannelFactory, ClientRuntime clientRuntime, Binding binding)
  424. : base(innerChannelFactory, clientRuntime, binding)
  425. {
  426. }
  427. protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via)
  428. {
  429. return new OutputChannelBinder(this.InnerChannelFactory.CreateChannel(to, via));
  430. }
  431. public override bool CanCreateChannel<TChannel>()
  432. {
  433. return (typeof(TChannel) == typeof(IOutputChannel)
  434. || typeof(TChannel) == typeof(IRequestChannel));
  435. }
  436. }
  437. class ServiceChannelFactoryOverDuplex : TypedServiceChannelFactory<IDuplexChannel>
  438. {
  439. public ServiceChannelFactoryOverDuplex(IChannelFactory<IDuplexChannel> innerChannelFactory, ClientRuntime clientRuntime, Binding binding)
  440. : base(innerChannelFactory, clientRuntime, binding)
  441. {
  442. }
  443. protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via)
  444. {
  445. return new DuplexChannelBinder(this.InnerChannelFactory.CreateChannel(to, via), this.RequestReplyCorrelator);
  446. }
  447. public override bool CanCreateChannel<TChannel>()
  448. {
  449. return (typeof(TChannel) == typeof(IOutputChannel)
  450. || typeof(TChannel) == typeof(IRequestChannel)
  451. || typeof(TChannel) == typeof(IDuplexChannel));
  452. }
  453. }
  454. class ServiceChannelFactoryOverRequest : TypedServiceChannelFactory<IRequestChannel>
  455. {
  456. public ServiceChannelFactoryOverRequest(IChannelFactory<IRequestChannel> innerChannelFactory, ClientRuntime clientRuntime, Binding binding)
  457. : base(innerChannelFactory, clientRuntime, binding)
  458. {
  459. }
  460. protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via)
  461. {
  462. return new RequestChannelBinder(this.InnerChannelFactory.CreateChannel(to, via));
  463. }
  464. public override bool CanCreateChannel<TChannel>()
  465. {
  466. return (typeof(TChannel) == typeof(IOutputChannel)
  467. || typeof(TChannel) == typeof(IRequestChannel));
  468. }
  469. }
  470. class ServiceChannelFactoryOverOutputSession : TypedServiceChannelFactory<IOutputSessionChannel>
  471. {
  472. bool datagramAdapter;
  473. public ServiceChannelFactoryOverOutputSession(IChannelFactory<IOutputSessionChannel> innerChannelFactory, ClientRuntime clientRuntime, Binding binding, bool datagramAdapter)
  474. : base(innerChannelFactory, clientRuntime, binding)
  475. {
  476. this.datagramAdapter = datagramAdapter;
  477. }
  478. protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via)
  479. {
  480. IOutputChannel channel;
  481. if (this.datagramAdapter)
  482. {
  483. channel = DatagramAdapter.GetOutputChannel(
  484. delegate() { return this.InnerChannelFactory.CreateChannel(to, via); },
  485. timeouts);
  486. }
  487. else
  488. {
  489. channel = this.InnerChannelFactory.CreateChannel(to, via);
  490. }
  491. return new OutputChannelBinder(channel);
  492. }
  493. public override bool CanCreateChannel<TChannel>()
  494. {
  495. return (typeof(TChannel) == typeof(IOutputChannel)
  496. || typeof(TChannel) == typeof(IOutputSessionChannel)
  497. || typeof(TChannel) == typeof(IRequestChannel)
  498. || typeof(TChannel) == typeof(IRequestSessionChannel));
  499. }
  500. }
  501. class ServiceChannelFactoryOverDuplexSession : TypedServiceChannelFactory<IDuplexSessionChannel>
  502. {
  503. bool useActiveAutoClose;
  504. public ServiceChannelFactoryOverDuplexSession(IChannelFactory<IDuplexSessionChannel> innerChannelFactory, ClientRuntime clientRuntime, Binding binding, bool useActiveAutoClose)
  505. : base(innerChannelFactory, clientRuntime, binding)
  506. {
  507. this.useActiveAutoClose = useActiveAutoClose;
  508. }
  509. protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via)
  510. {
  511. return new DuplexChannelBinder(this.InnerChannelFactory.CreateChannel(to, via), this.RequestReplyCorrelator, useActiveAutoClose);
  512. }
  513. public override bool CanCreateChannel<TChannel>()
  514. {
  515. return (typeof(TChannel) == typeof(IOutputChannel)
  516. || typeof(TChannel) == typeof(IRequestChannel)
  517. || typeof(TChannel) == typeof(IDuplexChannel)
  518. || typeof(TChannel) == typeof(IOutputSessionChannel)
  519. || typeof(TChannel) == typeof(IRequestSessionChannel)
  520. || typeof(TChannel) == typeof(IDuplexSessionChannel));
  521. }
  522. }
  523. class ServiceChannelFactoryOverRequestSession : TypedServiceChannelFactory<IRequestSessionChannel>
  524. {
  525. bool datagramAdapter = false;
  526. public ServiceChannelFactoryOverRequestSession(IChannelFactory<IRequestSessionChannel> innerChannelFactory, ClientRuntime clientRuntime, Binding binding, bool datagramAdapter)
  527. : base(innerChannelFactory, clientRuntime, binding)
  528. {
  529. this.datagramAdapter = datagramAdapter;
  530. }
  531. protected override IChannelBinder CreateInnerChannelBinder(EndpointAddress to, Uri via)
  532. {
  533. IRequestChannel channel;
  534. if (this.datagramAdapter)
  535. {
  536. channel = DatagramAdapter.GetRequestChannel(
  537. delegate() { return this.InnerChannelFactory.CreateChannel(to, via); },
  538. this.timeouts);
  539. }
  540. else
  541. {
  542. channel = this.InnerChannelFactory.CreateChannel(to, via);
  543. }
  544. return new RequestChannelBinder(channel);
  545. }
  546. public override bool CanCreateChannel<TChannel>()
  547. {
  548. return (typeof(TChannel) == typeof(IOutputChannel)
  549. || typeof(TChannel) == typeof(IOutputSessionChannel)
  550. || typeof(TChannel) == typeof(IRequestChannel)
  551. || typeof(TChannel) == typeof(IRequestSessionChannel));
  552. }
  553. }
  554. class DefaultCommunicationTimeouts : IDefaultCommunicationTimeouts
  555. {
  556. TimeSpan closeTimeout;
  557. TimeSpan openTimeout;
  558. TimeSpan receiveTimeout;
  559. TimeSpan sendTimeout;
  560. public DefaultCommunicationTimeouts(IDefaultCommunicationTimeouts timeouts)
  561. {
  562. this.closeTimeout = timeouts.CloseTimeout;
  563. this.openTimeout = timeouts.OpenTimeout;
  564. this.receiveTimeout = timeouts.ReceiveTimeout;
  565. this.sendTimeout = timeouts.SendTimeout;
  566. }
  567. public TimeSpan CloseTimeout
  568. {
  569. get { return this.closeTimeout; }
  570. }
  571. public TimeSpan OpenTimeout
  572. {
  573. get { return this.openTimeout; }
  574. }
  575. public TimeSpan ReceiveTimeout
  576. {
  577. get { return this.receiveTimeout; }
  578. }
  579. public TimeSpan SendTimeout
  580. {
  581. get { return this.sendTimeout; }
  582. }
  583. }
  584. }
  585. }