SingletonInstanceContextProvider.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Dispatcher
  5. {
  6. using System;
  7. using System.ServiceModel;
  8. using System.ServiceModel.Channels;
  9. internal class SingletonInstanceContextProvider : InstanceContextProviderBase
  10. {
  11. InstanceContext singleton;
  12. object thisLock;
  13. internal SingletonInstanceContextProvider(DispatchRuntime dispatchRuntime)
  14. : base(dispatchRuntime)
  15. {
  16. this.thisLock = new Object();
  17. }
  18. internal InstanceContext SingletonInstance
  19. {
  20. get
  21. {
  22. if (this.singleton == null)
  23. {
  24. lock (this.thisLock)
  25. {
  26. if (this.singleton == null)
  27. {
  28. InstanceContext instanceContext = this.DispatchRuntime.SingletonInstanceContext;
  29. if (instanceContext == null)
  30. {
  31. instanceContext = new InstanceContext(this.DispatchRuntime.ChannelDispatcher.Host, false);
  32. instanceContext.Open();
  33. }
  34. else if (instanceContext.State != CommunicationState.Opened)
  35. {
  36. // we need to lock against the instance context for open since two different endpoints could
  37. // share the same instance context, but different providers. So the provider lock does not guard
  38. // the open process
  39. lock (instanceContext.ThisLock)
  40. {
  41. if (instanceContext.State != CommunicationState.Opened)
  42. {
  43. instanceContext.Open();
  44. }
  45. }
  46. }
  47. //Set the IsUsercreated flag to false for singleton mode even in cases when users create their own runtime.
  48. instanceContext.IsUserCreated = false;
  49. //Delay assigning the potentially newly created InstanceContext (till after its opened) to this.Singleton
  50. //to ensure that it is opened only once.
  51. this.singleton = instanceContext;
  52. }
  53. }
  54. }
  55. return this.singleton;
  56. }
  57. }
  58. #region IInstanceContextProvider Members
  59. public override InstanceContext GetExistingInstanceContext(Message message, IContextChannel channel)
  60. {
  61. ServiceChannel serviceChannel = this.GetServiceChannelFromProxy(channel);
  62. if (serviceChannel != null && serviceChannel.HasSession)
  63. {
  64. this.SingletonInstance.BindIncomingChannel(serviceChannel);
  65. }
  66. return this.SingletonInstance;
  67. }
  68. public override void InitializeInstanceContext(InstanceContext instanceContext, Message message, IContextChannel channel)
  69. {
  70. //no-op
  71. }
  72. public override bool IsIdle(InstanceContext instanceContext)
  73. {
  74. //By default return false
  75. return false;
  76. }
  77. public override void NotifyIdle(InstanceContextIdleCallback callback, InstanceContext instanceContext)
  78. {
  79. //no-op
  80. }
  81. #endregion
  82. }
  83. }