DispatchRuntime.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Dispatcher
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.Diagnostics;
  10. using System.IdentityModel.Policy;
  11. using System.Runtime;
  12. using System.ServiceModel;
  13. using System.ServiceModel.Channels;
  14. using System.ServiceModel.Description;
  15. using System.ServiceModel.Diagnostics;
  16. using System.Threading;
  17. using System.Web.Security;
  18. using System.Runtime.Diagnostics;
  19. public sealed class DispatchRuntime
  20. {
  21. ServiceAuthenticationManager serviceAuthenticationManager;
  22. ServiceAuthorizationManager serviceAuthorizationManager;
  23. ReadOnlyCollection<IAuthorizationPolicy> externalAuthorizationPolicies;
  24. AuditLogLocation securityAuditLogLocation;
  25. ConcurrencyMode concurrencyMode;
  26. bool ensureOrderedDispatch;
  27. bool suppressAuditFailure;
  28. AuditLevel serviceAuthorizationAuditLevel;
  29. AuditLevel messageAuthenticationAuditLevel;
  30. bool automaticInputSessionShutdown;
  31. ChannelDispatcher channelDispatcher;
  32. SynchronizedCollection<IInputSessionShutdown> inputSessionShutdownHandlers;
  33. EndpointDispatcher endpointDispatcher;
  34. IInstanceProvider instanceProvider;
  35. IInstanceContextProvider instanceContextProvider;
  36. InstanceContext singleton;
  37. bool ignoreTransactionMessageProperty;
  38. SynchronizedCollection<IDispatchMessageInspector> messageInspectors;
  39. OperationCollection operations;
  40. IDispatchOperationSelector operationSelector;
  41. ClientRuntime proxyRuntime;
  42. ImmutableDispatchRuntime runtime;
  43. SynchronizedCollection<IInstanceContextInitializer> instanceContextInitializers;
  44. bool isExternalPoliciesSet;
  45. bool isAuthenticationManagerSet;
  46. bool isAuthorizationManagerSet;
  47. SynchronizationContext synchronizationContext;
  48. PrincipalPermissionMode principalPermissionMode;
  49. object roleProvider;
  50. Type type;
  51. DispatchOperation unhandled;
  52. bool transactionAutoCompleteOnSessionClose;
  53. bool impersonateCallerForAllOperations;
  54. bool impersonateOnSerializingReply;
  55. bool releaseServiceInstanceOnTransactionComplete;
  56. SharedRuntimeState shared;
  57. bool preserveMessage;
  58. bool requireClaimsPrincipalOnOperationContext;
  59. internal DispatchRuntime(EndpointDispatcher endpointDispatcher)
  60. : this(new SharedRuntimeState(true))
  61. {
  62. if (endpointDispatcher == null)
  63. {
  64. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointDispatcher");
  65. }
  66. this.endpointDispatcher = endpointDispatcher;
  67. Fx.Assert(shared.IsOnServer, "Server constructor called on client?");
  68. }
  69. internal DispatchRuntime(ClientRuntime proxyRuntime, SharedRuntimeState shared)
  70. : this(shared)
  71. {
  72. if (proxyRuntime == null)
  73. {
  74. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("proxyRuntime");
  75. }
  76. this.proxyRuntime = proxyRuntime;
  77. this.instanceProvider = new CallbackInstanceProvider();
  78. this.channelDispatcher = new ChannelDispatcher(shared);
  79. this.instanceContextProvider = InstanceContextProviderBase.GetProviderForMode(InstanceContextMode.PerSession, this);
  80. Fx.Assert(!shared.IsOnServer, "Client constructor called on server?");
  81. }
  82. DispatchRuntime(SharedRuntimeState shared)
  83. {
  84. this.shared = shared;
  85. this.operations = new OperationCollection(this);
  86. this.inputSessionShutdownHandlers = this.NewBehaviorCollection<IInputSessionShutdown>();
  87. this.messageInspectors = this.NewBehaviorCollection<IDispatchMessageInspector>();
  88. this.instanceContextInitializers = this.NewBehaviorCollection<IInstanceContextInitializer>();
  89. this.synchronizationContext = ThreadBehavior.GetCurrentSynchronizationContext();
  90. this.automaticInputSessionShutdown = true;
  91. this.principalPermissionMode = ServiceAuthorizationBehavior.DefaultPrincipalPermissionMode;
  92. this.securityAuditLogLocation = ServiceSecurityAuditBehavior.defaultAuditLogLocation;
  93. this.suppressAuditFailure = ServiceSecurityAuditBehavior.defaultSuppressAuditFailure;
  94. this.serviceAuthorizationAuditLevel = ServiceSecurityAuditBehavior.defaultServiceAuthorizationAuditLevel;
  95. this.messageAuthenticationAuditLevel = ServiceSecurityAuditBehavior.defaultMessageAuthenticationAuditLevel;
  96. this.unhandled = new DispatchOperation(this, "*", MessageHeaders.WildcardAction, MessageHeaders.WildcardAction);
  97. this.unhandled.InternalFormatter = MessageOperationFormatter.Instance;
  98. this.unhandled.InternalInvoker = new UnhandledActionInvoker(this);
  99. }
  100. public IInstanceContextProvider InstanceContextProvider
  101. {
  102. get
  103. {
  104. return this.instanceContextProvider;
  105. }
  106. set
  107. {
  108. if (value == null)
  109. {
  110. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
  111. }
  112. lock (this.ThisLock)
  113. {
  114. this.InvalidateRuntime();
  115. this.instanceContextProvider = value;
  116. }
  117. }
  118. }
  119. public InstanceContext SingletonInstanceContext
  120. {
  121. get { return this.singleton; }
  122. set
  123. {
  124. if (value == null)
  125. {
  126. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
  127. }
  128. lock (this.ThisLock)
  129. {
  130. this.InvalidateRuntime();
  131. this.singleton = value;
  132. }
  133. }
  134. }
  135. public ConcurrencyMode ConcurrencyMode
  136. {
  137. get
  138. {
  139. return this.concurrencyMode;
  140. }
  141. set
  142. {
  143. lock (this.ThisLock)
  144. {
  145. this.InvalidateRuntime();
  146. this.concurrencyMode = value;
  147. }
  148. }
  149. }
  150. public bool EnsureOrderedDispatch
  151. {
  152. get
  153. {
  154. return this.ensureOrderedDispatch;
  155. }
  156. set
  157. {
  158. lock (this.ThisLock)
  159. {
  160. this.InvalidateRuntime();
  161. this.ensureOrderedDispatch = value;
  162. }
  163. }
  164. }
  165. public AuditLogLocation SecurityAuditLogLocation
  166. {
  167. get
  168. {
  169. return this.securityAuditLogLocation;
  170. }
  171. set
  172. {
  173. if (!AuditLogLocationHelper.IsDefined(value))
  174. {
  175. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
  176. }
  177. lock (this.ThisLock)
  178. {
  179. this.InvalidateRuntime();
  180. this.securityAuditLogLocation = value;
  181. }
  182. }
  183. }
  184. public bool SuppressAuditFailure
  185. {
  186. get
  187. {
  188. return this.suppressAuditFailure;
  189. }
  190. set
  191. {
  192. lock (this.ThisLock)
  193. {
  194. this.InvalidateRuntime();
  195. this.suppressAuditFailure = value;
  196. }
  197. }
  198. }
  199. public AuditLevel ServiceAuthorizationAuditLevel
  200. {
  201. get
  202. {
  203. return this.serviceAuthorizationAuditLevel;
  204. }
  205. set
  206. {
  207. if (!AuditLevelHelper.IsDefined(value))
  208. {
  209. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
  210. }
  211. lock (this.ThisLock)
  212. {
  213. this.InvalidateRuntime();
  214. this.serviceAuthorizationAuditLevel = value;
  215. }
  216. }
  217. }
  218. public AuditLevel MessageAuthenticationAuditLevel
  219. {
  220. get
  221. {
  222. return this.messageAuthenticationAuditLevel;
  223. }
  224. set
  225. {
  226. if (!AuditLevelHelper.IsDefined(value))
  227. {
  228. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
  229. }
  230. lock (this.ThisLock)
  231. {
  232. this.InvalidateRuntime();
  233. this.messageAuthenticationAuditLevel = value;
  234. }
  235. }
  236. }
  237. public ReadOnlyCollection<IAuthorizationPolicy> ExternalAuthorizationPolicies
  238. {
  239. get
  240. {
  241. return this.externalAuthorizationPolicies;
  242. }
  243. set
  244. {
  245. lock (this.ThisLock)
  246. {
  247. this.InvalidateRuntime();
  248. this.externalAuthorizationPolicies = value;
  249. this.isExternalPoliciesSet = true;
  250. }
  251. }
  252. }
  253. public ServiceAuthenticationManager ServiceAuthenticationManager
  254. {
  255. get
  256. {
  257. return this.serviceAuthenticationManager;
  258. }
  259. set
  260. {
  261. lock (this.ThisLock)
  262. {
  263. this.InvalidateRuntime();
  264. this.serviceAuthenticationManager = value;
  265. this.isAuthenticationManagerSet = true;
  266. }
  267. }
  268. }
  269. public ServiceAuthorizationManager ServiceAuthorizationManager
  270. {
  271. get
  272. {
  273. return this.serviceAuthorizationManager;
  274. }
  275. set
  276. {
  277. lock (this.ThisLock)
  278. {
  279. this.InvalidateRuntime();
  280. this.serviceAuthorizationManager = value;
  281. this.isAuthorizationManagerSet = true;
  282. }
  283. }
  284. }
  285. public bool AutomaticInputSessionShutdown
  286. {
  287. get { return this.automaticInputSessionShutdown; }
  288. set
  289. {
  290. lock (this.ThisLock)
  291. {
  292. this.InvalidateRuntime();
  293. this.automaticInputSessionShutdown = value;
  294. }
  295. }
  296. }
  297. public ChannelDispatcher ChannelDispatcher
  298. {
  299. get { return this.channelDispatcher ?? this.endpointDispatcher.ChannelDispatcher; }
  300. }
  301. public ClientRuntime CallbackClientRuntime
  302. {
  303. get
  304. {
  305. if (this.proxyRuntime == null)
  306. {
  307. lock (this.ThisLock)
  308. {
  309. if (this.proxyRuntime == null)
  310. {
  311. this.proxyRuntime = new ClientRuntime(this, this.shared);
  312. }
  313. }
  314. }
  315. return this.proxyRuntime;
  316. }
  317. }
  318. public EndpointDispatcher EndpointDispatcher
  319. {
  320. get { return this.endpointDispatcher; }
  321. }
  322. public bool ImpersonateCallerForAllOperations
  323. {
  324. get
  325. {
  326. return this.impersonateCallerForAllOperations;
  327. }
  328. set
  329. {
  330. lock (this.ThisLock)
  331. {
  332. this.InvalidateRuntime();
  333. this.impersonateCallerForAllOperations = value;
  334. }
  335. }
  336. }
  337. public bool ImpersonateOnSerializingReply
  338. {
  339. get
  340. {
  341. return this.impersonateOnSerializingReply;
  342. }
  343. set
  344. {
  345. lock (this.ThisLock)
  346. {
  347. this.InvalidateRuntime();
  348. this.impersonateOnSerializingReply = value;
  349. }
  350. }
  351. }
  352. internal bool RequireClaimsPrincipalOnOperationContext
  353. {
  354. get
  355. {
  356. return this.requireClaimsPrincipalOnOperationContext;
  357. }
  358. set
  359. {
  360. lock (this.ThisLock)
  361. {
  362. this.InvalidateRuntime();
  363. this.requireClaimsPrincipalOnOperationContext = value;
  364. }
  365. }
  366. }
  367. public SynchronizedCollection<IInputSessionShutdown> InputSessionShutdownHandlers
  368. {
  369. get { return this.inputSessionShutdownHandlers; }
  370. }
  371. public bool IgnoreTransactionMessageProperty
  372. {
  373. get { return this.ignoreTransactionMessageProperty; }
  374. set
  375. {
  376. lock (this.ThisLock)
  377. {
  378. this.InvalidateRuntime();
  379. this.ignoreTransactionMessageProperty = value;
  380. }
  381. }
  382. }
  383. public IInstanceProvider InstanceProvider
  384. {
  385. get { return this.instanceProvider; }
  386. set
  387. {
  388. lock (this.ThisLock)
  389. {
  390. this.InvalidateRuntime();
  391. this.instanceProvider = value;
  392. }
  393. }
  394. }
  395. public SynchronizedCollection<IDispatchMessageInspector> MessageInspectors
  396. {
  397. get { return this.messageInspectors; }
  398. }
  399. public SynchronizedKeyedCollection<string, DispatchOperation> Operations
  400. {
  401. get { return this.operations; }
  402. }
  403. public IDispatchOperationSelector OperationSelector
  404. {
  405. get { return this.operationSelector; }
  406. set
  407. {
  408. lock (this.ThisLock)
  409. {
  410. this.InvalidateRuntime();
  411. this.operationSelector = value;
  412. }
  413. }
  414. }
  415. public bool ReleaseServiceInstanceOnTransactionComplete
  416. {
  417. get { return this.releaseServiceInstanceOnTransactionComplete; }
  418. set
  419. {
  420. lock (this.ThisLock)
  421. {
  422. this.InvalidateRuntime();
  423. this.releaseServiceInstanceOnTransactionComplete = value;
  424. }
  425. }
  426. }
  427. public SynchronizedCollection<IInstanceContextInitializer> InstanceContextInitializers
  428. {
  429. get { return this.instanceContextInitializers; }
  430. }
  431. public SynchronizationContext SynchronizationContext
  432. {
  433. get { return this.synchronizationContext; }
  434. set
  435. {
  436. lock (this.ThisLock)
  437. {
  438. this.InvalidateRuntime();
  439. this.synchronizationContext = value;
  440. }
  441. }
  442. }
  443. public PrincipalPermissionMode PrincipalPermissionMode
  444. {
  445. get
  446. {
  447. return this.principalPermissionMode;
  448. }
  449. set
  450. {
  451. if (!PrincipalPermissionModeHelper.IsDefined(value))
  452. {
  453. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
  454. }
  455. lock (this.ThisLock)
  456. {
  457. this.InvalidateRuntime();
  458. this.principalPermissionMode = value;
  459. }
  460. }
  461. }
  462. public RoleProvider RoleProvider
  463. {
  464. get { return (RoleProvider)this.roleProvider; }
  465. set
  466. {
  467. lock (this.ThisLock)
  468. {
  469. this.InvalidateRuntime();
  470. this.roleProvider = value;
  471. }
  472. }
  473. }
  474. public bool TransactionAutoCompleteOnSessionClose
  475. {
  476. get { return this.transactionAutoCompleteOnSessionClose; }
  477. set
  478. {
  479. lock (this.ThisLock)
  480. {
  481. this.InvalidateRuntime();
  482. this.transactionAutoCompleteOnSessionClose = value;
  483. }
  484. }
  485. }
  486. public Type Type
  487. {
  488. get { return this.type; }
  489. set
  490. {
  491. lock (this.ThisLock)
  492. {
  493. this.InvalidateRuntime();
  494. this.type = value;
  495. }
  496. }
  497. }
  498. public DispatchOperation UnhandledDispatchOperation
  499. {
  500. get { return this.unhandled; }
  501. set
  502. {
  503. if (value == null)
  504. {
  505. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
  506. }
  507. lock (this.ThisLock)
  508. {
  509. this.InvalidateRuntime();
  510. this.unhandled = value;
  511. }
  512. }
  513. }
  514. public bool ValidateMustUnderstand
  515. {
  516. get { return this.shared.ValidateMustUnderstand; }
  517. set
  518. {
  519. lock (this.ThisLock)
  520. {
  521. this.InvalidateRuntime();
  522. this.shared.ValidateMustUnderstand = value;
  523. }
  524. }
  525. }
  526. public bool PreserveMessage
  527. {
  528. get { return this.preserveMessage; }
  529. set
  530. {
  531. lock (this.ThisLock)
  532. {
  533. this.InvalidateRuntime();
  534. this.preserveMessage = value;
  535. }
  536. }
  537. }
  538. internal bool RequiresAuthentication
  539. {
  540. get
  541. {
  542. return this.isAuthenticationManagerSet;
  543. }
  544. }
  545. internal bool RequiresAuthorization
  546. {
  547. get
  548. {
  549. return (this.isAuthorizationManagerSet || this.isExternalPoliciesSet ||
  550. AuditLevel.Success == (this.serviceAuthorizationAuditLevel & AuditLevel.Success));
  551. }
  552. }
  553. internal bool HasMatchAllOperation
  554. {
  555. get
  556. {
  557. lock (this.ThisLock)
  558. {
  559. return !(this.unhandled.Invoker is UnhandledActionInvoker);
  560. }
  561. }
  562. }
  563. internal bool EnableFaults
  564. {
  565. get
  566. {
  567. if (this.IsOnServer)
  568. {
  569. ChannelDispatcher channelDispatcher = this.ChannelDispatcher;
  570. return (channelDispatcher != null) && channelDispatcher.EnableFaults;
  571. }
  572. else
  573. {
  574. return this.shared.EnableFaults;
  575. }
  576. }
  577. }
  578. internal bool IsOnServer
  579. {
  580. get { return this.shared.IsOnServer; }
  581. }
  582. internal bool ManualAddressing
  583. {
  584. get
  585. {
  586. if (this.IsOnServer)
  587. {
  588. ChannelDispatcher channelDispatcher = this.ChannelDispatcher;
  589. return (channelDispatcher != null) && channelDispatcher.ManualAddressing;
  590. }
  591. else
  592. {
  593. return this.shared.ManualAddressing;
  594. }
  595. }
  596. }
  597. internal int MaxCallContextInitializers
  598. {
  599. get
  600. {
  601. lock (this.ThisLock)
  602. {
  603. int max = 0;
  604. for (int i = 0; i < this.operations.Count; i++)
  605. {
  606. max = System.Math.Max(max, this.operations[i].CallContextInitializers.Count);
  607. }
  608. max = System.Math.Max(max, this.unhandled.CallContextInitializers.Count);
  609. return max;
  610. }
  611. }
  612. }
  613. internal int MaxParameterInspectors
  614. {
  615. get
  616. {
  617. lock (this.ThisLock)
  618. {
  619. int max = 0;
  620. for (int i = 0; i < this.operations.Count; i++)
  621. {
  622. max = System.Math.Max(max, this.operations[i].ParameterInspectors.Count);
  623. }
  624. max = System.Math.Max(max, this.unhandled.ParameterInspectors.Count);
  625. return max;
  626. }
  627. }
  628. }
  629. // Internal access to CallbackClientRuntime, but this one doesn't create on demand
  630. internal ClientRuntime ClientRuntime
  631. {
  632. get { return this.proxyRuntime; }
  633. }
  634. internal object ThisLock
  635. {
  636. get { return this.shared; }
  637. }
  638. internal bool IsRoleProviderSet
  639. {
  640. get { return this.roleProvider != null; }
  641. }
  642. internal DispatchOperationRuntime GetOperation(ref Message message)
  643. {
  644. ImmutableDispatchRuntime runtime = this.GetRuntime();
  645. return runtime.GetOperation(ref message);
  646. }
  647. internal ImmutableDispatchRuntime GetRuntime()
  648. {
  649. ImmutableDispatchRuntime runtime = this.runtime;
  650. if (runtime != null)
  651. {
  652. return runtime;
  653. }
  654. else
  655. {
  656. return GetRuntimeCore();
  657. }
  658. }
  659. ImmutableDispatchRuntime GetRuntimeCore()
  660. {
  661. lock (this.ThisLock)
  662. {
  663. if (this.runtime == null)
  664. {
  665. this.runtime = new ImmutableDispatchRuntime(this);
  666. }
  667. return this.runtime;
  668. }
  669. }
  670. internal void InvalidateRuntime()
  671. {
  672. lock (this.ThisLock)
  673. {
  674. this.shared.ThrowIfImmutable();
  675. this.runtime = null;
  676. }
  677. }
  678. internal void LockDownProperties()
  679. {
  680. this.shared.LockDownProperties();
  681. if (this.concurrencyMode != ConcurrencyMode.Single && this.ensureOrderedDispatch)
  682. {
  683. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SfxDispatchRuntimeNonConcurrentOrEnsureOrderedDispatch)));
  684. }
  685. }
  686. internal SynchronizedCollection<T> NewBehaviorCollection<T>()
  687. {
  688. return new DispatchBehaviorCollection<T>(this);
  689. }
  690. internal void SetDebugFlagInDispatchOperations(bool includeExceptionDetailInFaults)
  691. {
  692. foreach (DispatchOperation dispatchOperation in this.operations)
  693. {
  694. dispatchOperation.IncludeExceptionDetailInFaults = includeExceptionDetailInFaults;
  695. }
  696. }
  697. internal class UnhandledActionInvoker : IOperationInvoker
  698. {
  699. DispatchRuntime dispatchRuntime;
  700. public UnhandledActionInvoker(DispatchRuntime dispatchRuntime)
  701. {
  702. this.dispatchRuntime = dispatchRuntime;
  703. }
  704. public bool IsSynchronous
  705. {
  706. get { return true; }
  707. }
  708. public object[] AllocateInputs()
  709. {
  710. return new object[1];
  711. }
  712. public object Invoke(object instance, object[] inputs, out object[] outputs)
  713. {
  714. outputs = EmptyArray<object>.Allocate(0);
  715. Message message = inputs[0] as Message;
  716. if (message == null)
  717. {
  718. return null;
  719. }
  720. string action = message.Headers.Action;
  721. if (DiagnosticUtility.ShouldTraceInformation)
  722. {
  723. TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.UnhandledAction,
  724. SR.GetString(SR.TraceCodeUnhandledAction),
  725. new StringTraceRecord("Action", action),
  726. this, null, message);
  727. }
  728. FaultCode code = FaultCode.CreateSenderFaultCode(AddressingStrings.ActionNotSupported,
  729. message.Version.Addressing.Namespace);
  730. string reasonText = SR.GetString(SR.SFxNoEndpointMatchingContract, action);
  731. FaultReason reason = new FaultReason(reasonText);
  732. FaultException exception = new FaultException(reason, code);
  733. ErrorBehavior.ThrowAndCatch(exception);
  734. ServiceChannel serviceChannel = OperationContext.Current.InternalServiceChannel;
  735. OperationContext.Current.OperationCompleted +=
  736. delegate(object sender, EventArgs e)
  737. {
  738. ChannelDispatcher channelDispatcher = this.dispatchRuntime.ChannelDispatcher;
  739. if (!channelDispatcher.HandleError(exception) && serviceChannel.HasSession)
  740. {
  741. try
  742. {
  743. serviceChannel.Close(ChannelHandler.CloseAfterFaultTimeout);
  744. }
  745. catch (Exception ex)
  746. {
  747. if (Fx.IsFatal(ex))
  748. {
  749. throw;
  750. }
  751. channelDispatcher.HandleError(ex);
  752. }
  753. }
  754. };
  755. if (this.dispatchRuntime.shared.EnableFaults)
  756. {
  757. MessageFault fault = MessageFault.CreateFault(code, reason, action);
  758. return Message.CreateMessage(message.Version, fault, message.Version.Addressing.DefaultFaultAction);
  759. }
  760. else
  761. {
  762. OperationContext.Current.RequestContext.Close();
  763. OperationContext.Current.RequestContext = null;
  764. return null;
  765. }
  766. }
  767. public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
  768. {
  769. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  770. }
  771. public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
  772. {
  773. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  774. }
  775. }
  776. class DispatchBehaviorCollection<T> : SynchronizedCollection<T>
  777. {
  778. DispatchRuntime outer;
  779. internal DispatchBehaviorCollection(DispatchRuntime outer)
  780. : base(outer.ThisLock)
  781. {
  782. this.outer = outer;
  783. }
  784. protected override void ClearItems()
  785. {
  786. this.outer.InvalidateRuntime();
  787. base.ClearItems();
  788. }
  789. protected override void InsertItem(int index, T item)
  790. {
  791. if (item == null)
  792. {
  793. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
  794. }
  795. this.outer.InvalidateRuntime();
  796. base.InsertItem(index, item);
  797. }
  798. protected override void RemoveItem(int index)
  799. {
  800. this.outer.InvalidateRuntime();
  801. base.RemoveItem(index);
  802. }
  803. protected override void SetItem(int index, T item)
  804. {
  805. if (item == null)
  806. {
  807. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
  808. }
  809. this.outer.InvalidateRuntime();
  810. base.SetItem(index, item);
  811. }
  812. }
  813. class OperationCollection : SynchronizedKeyedCollection<string, DispatchOperation>
  814. {
  815. DispatchRuntime outer;
  816. internal OperationCollection(DispatchRuntime outer)
  817. : base(outer.ThisLock)
  818. {
  819. this.outer = outer;
  820. }
  821. protected override void ClearItems()
  822. {
  823. this.outer.InvalidateRuntime();
  824. base.ClearItems();
  825. }
  826. protected override string GetKeyForItem(DispatchOperation item)
  827. {
  828. return item.Name;
  829. }
  830. protected override void InsertItem(int index, DispatchOperation item)
  831. {
  832. if (item == null)
  833. {
  834. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
  835. }
  836. if (item.Parent != this.outer)
  837. {
  838. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxMismatchedOperationParent));
  839. }
  840. this.outer.InvalidateRuntime();
  841. base.InsertItem(index, item);
  842. }
  843. protected override void RemoveItem(int index)
  844. {
  845. this.outer.InvalidateRuntime();
  846. base.RemoveItem(index);
  847. }
  848. protected override void SetItem(int index, DispatchOperation item)
  849. {
  850. if (item == null)
  851. {
  852. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
  853. }
  854. if (item.Parent != this.outer)
  855. {
  856. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.SFxMismatchedOperationParent));
  857. }
  858. this.outer.InvalidateRuntime();
  859. base.SetItem(index, item);
  860. }
  861. }
  862. class CallbackInstanceProvider : IInstanceProvider
  863. {
  864. object IInstanceProvider.GetInstance(InstanceContext instanceContext)
  865. {
  866. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCannotActivateCallbackInstace)));
  867. }
  868. object IInstanceProvider.GetInstance(InstanceContext instanceContext, Message message)
  869. {
  870. throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCannotActivateCallbackInstace)), message);
  871. }
  872. void IInstanceProvider.ReleaseInstance(InstanceContext instanceContext, object instance)
  873. {
  874. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxCannotActivateCallbackInstace)));
  875. }
  876. }
  877. }
  878. }