ContractInstanceProvider.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Administration
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Diagnostics;
  9. using System.Globalization;
  10. using System.Reflection;
  11. using System.Runtime;
  12. using System.ServiceModel.Channels;
  13. using System.ServiceModel.Description;
  14. class ContractInstanceProvider : ProviderBase, IWmiProvider
  15. {
  16. static Dictionary<string, ContractDescription> knownContracts = new Dictionary<string, ContractDescription>();
  17. internal static string ContractReference(string contractName)
  18. {
  19. return String.Format(CultureInfo.InvariantCulture,
  20. AdministrationStrings.Contract +
  21. "." +
  22. AdministrationStrings.Name +
  23. "='{0}'," +
  24. AdministrationStrings.ProcessId +
  25. "={1}," +
  26. AdministrationStrings.AppDomainId +
  27. "={2}",
  28. contractName,
  29. AppDomainInfo.Current.ProcessId,
  30. AppDomainInfo.Current.Id);
  31. }
  32. internal static void RegisterContract(ContractDescription contract)
  33. {
  34. lock (ContractInstanceProvider.knownContracts)
  35. {
  36. if (!ContractInstanceProvider.knownContracts.ContainsKey(contract.Name))
  37. {
  38. ContractInstanceProvider.knownContracts.Add(contract.Name, contract);
  39. }
  40. }
  41. }
  42. static void FillContract(IWmiInstance contract, ContractDescription contractDescription)
  43. {
  44. Fx.Assert(null != contractDescription, "contractDescription cannot be null");
  45. contract.SetProperty(AdministrationStrings.Type, contractDescription.ContractType.Name);
  46. if (null != contractDescription.CallbackContractType)
  47. {
  48. contract.SetProperty(AdministrationStrings.CallbackContract, ContractReference(contractDescription.CallbackContractType.Name));
  49. }
  50. contract.SetProperty(AdministrationStrings.Name, contractDescription.Name);
  51. contract.SetProperty(AdministrationStrings.Namespace, contractDescription.Namespace);
  52. contract.SetProperty(AdministrationStrings.SessionMode, contractDescription.SessionMode.ToString());
  53. IWmiInstance[] operations = new IWmiInstance[contractDescription.Operations.Count];
  54. for (int j = 0; j < operations.Length; ++j)
  55. {
  56. OperationDescription operationDescription = contractDescription.Operations[j];
  57. Fx.Assert(operationDescription.Messages.Count > 0, "");
  58. IWmiInstance operation = contract.NewInstance(AdministrationStrings.Operation);
  59. FillOperation(operation, operationDescription);
  60. operations[j] = operation;
  61. }
  62. contract.SetProperty(AdministrationStrings.Operations, operations);
  63. FillBehaviorsInfo(contract, contractDescription.Behaviors);
  64. }
  65. static void FillOperation(IWmiInstance operation, OperationDescription operationDescription)
  66. {
  67. operation.SetProperty(AdministrationStrings.Name, operationDescription.Name);
  68. operation.SetProperty(AdministrationStrings.Action, FixWildcardAction(operationDescription.Messages[0].Action));
  69. if (operationDescription.Messages.Count > 1)
  70. {
  71. operation.SetProperty(AdministrationStrings.ReplyAction, FixWildcardAction(operationDescription.Messages[1].Action));
  72. }
  73. operation.SetProperty(AdministrationStrings.IsOneWay, operationDescription.IsOneWay);
  74. operation.SetProperty(AdministrationStrings.IsInitiating, operationDescription.IsInitiating);
  75. operation.SetProperty(AdministrationStrings.IsTerminating, operationDescription.IsTerminating);
  76. operation.SetProperty(AdministrationStrings.AsyncPattern, null != operationDescription.BeginMethod);
  77. if (null != operationDescription.SyncMethod)
  78. {
  79. if (null != operationDescription.SyncMethod.ReturnType)
  80. {
  81. operation.SetProperty(AdministrationStrings.ReturnType, operationDescription.SyncMethod.ReturnType.Name);
  82. }
  83. operation.SetProperty(AdministrationStrings.MethodSignature, operationDescription.SyncMethod.ToString());
  84. ParameterInfo[] parameterInfo = operationDescription.SyncMethod.GetParameters();
  85. string[] parameterTypes = new string[parameterInfo.Length];
  86. for (int i = 0; i < parameterInfo.Length; i++)
  87. {
  88. parameterTypes[i] = parameterInfo[i].ParameterType.ToString();
  89. }
  90. operation.SetProperty(AdministrationStrings.ParameterTypes, parameterTypes);
  91. }
  92. operation.SetProperty(AdministrationStrings.IsCallback, operationDescription.Messages[0].Direction == MessageDirection.Output);
  93. FillBehaviorsInfo(operation, operationDescription.Behaviors);
  94. }
  95. static void FillBehaviorsInfo(IWmiInstance operation, KeyedByTypeCollection<IOperationBehavior> behaviors)
  96. {
  97. List<IWmiInstance> behaviorInstances = new List<IWmiInstance>(behaviors.Count);
  98. foreach (IOperationBehavior behavior in behaviors)
  99. {
  100. IWmiInstance behaviorInstance;
  101. FillBehaviorInfo(behavior, operation, out behaviorInstance);
  102. if (null != behaviorInstance)
  103. {
  104. behaviorInstances.Add(behaviorInstance);
  105. }
  106. }
  107. operation.SetProperty(AdministrationStrings.Behaviors, behaviorInstances.ToArray());
  108. }
  109. static void FillBehaviorsInfo(IWmiInstance operation, KeyedByTypeCollection<IContractBehavior> behaviors)
  110. {
  111. List<IWmiInstance> behaviorInstances = new List<IWmiInstance>(behaviors.Count);
  112. foreach (IContractBehavior behavior in behaviors)
  113. {
  114. IWmiInstance behaviorInstance;
  115. FillBehaviorInfo(behavior, operation, out behaviorInstance);
  116. if (null != behaviorInstance)
  117. {
  118. behaviorInstances.Add(behaviorInstance);
  119. }
  120. }
  121. operation.SetProperty(AdministrationStrings.Behaviors, behaviorInstances.ToArray());
  122. }
  123. static void FillBehaviorInfo(IContractBehavior behavior, IWmiInstance existingInstance, out IWmiInstance instance)
  124. {
  125. Fx.Assert(null != existingInstance, "");
  126. Fx.Assert(null != behavior, "");
  127. instance = null;
  128. if (behavior is DeliveryRequirementsAttribute)
  129. {
  130. instance = existingInstance.NewInstance("DeliveryRequirementsAttribute");
  131. DeliveryRequirementsAttribute specificBehavior = (DeliveryRequirementsAttribute)behavior;
  132. instance.SetProperty(AdministrationStrings.QueuedDeliveryRequirements, specificBehavior.QueuedDeliveryRequirements.ToString());
  133. instance.SetProperty(AdministrationStrings.RequireOrderedDelivery, specificBehavior.RequireOrderedDelivery);
  134. if (null != specificBehavior.TargetContract)
  135. {
  136. instance.SetProperty(AdministrationStrings.TargetContract, specificBehavior.TargetContract.ToString());
  137. }
  138. }
  139. else if (behavior is IWmiInstanceProvider)
  140. {
  141. IWmiInstanceProvider instanceProvider = (IWmiInstanceProvider)behavior;
  142. instance = existingInstance.NewInstance(instanceProvider.GetInstanceType());
  143. instanceProvider.FillInstance(instance);
  144. }
  145. else
  146. {
  147. instance = existingInstance.NewInstance("Behavior");
  148. }
  149. if (null != instance)
  150. {
  151. instance.SetProperty(AdministrationStrings.Type, behavior.GetType().FullName);
  152. }
  153. }
  154. static void FillBehaviorInfo(IOperationBehavior behavior, IWmiInstance existingInstance, out IWmiInstance instance)
  155. {
  156. Fx.Assert(null != existingInstance, "");
  157. Fx.Assert(null != behavior, "");
  158. instance = null;
  159. if (behavior is DataContractSerializerOperationBehavior)
  160. {
  161. instance = existingInstance.NewInstance("DataContractSerializerOperationBehavior");
  162. DataContractSerializerOperationBehavior specificBehavior = (DataContractSerializerOperationBehavior)behavior;
  163. instance.SetProperty(AdministrationStrings.IgnoreExtensionDataObject, specificBehavior.IgnoreExtensionDataObject);
  164. instance.SetProperty(AdministrationStrings.MaxItemsInObjectGraph, specificBehavior.MaxItemsInObjectGraph);
  165. if (null != specificBehavior.DataContractFormatAttribute)
  166. {
  167. instance.SetProperty(AdministrationStrings.Style, specificBehavior.DataContractFormatAttribute.Style.ToString());
  168. }
  169. }
  170. else if (behavior is OperationBehaviorAttribute)
  171. {
  172. instance = existingInstance.NewInstance("OperationBehaviorAttribute");
  173. OperationBehaviorAttribute specificBehavior = (OperationBehaviorAttribute)behavior;
  174. instance.SetProperty(AdministrationStrings.AutoDisposeParameters, specificBehavior.AutoDisposeParameters);
  175. instance.SetProperty(AdministrationStrings.Impersonation, specificBehavior.Impersonation.ToString());
  176. instance.SetProperty(AdministrationStrings.ReleaseInstanceMode, specificBehavior.ReleaseInstanceMode.ToString());
  177. instance.SetProperty(AdministrationStrings.TransactionAutoComplete, specificBehavior.TransactionAutoComplete);
  178. instance.SetProperty(AdministrationStrings.TransactionScopeRequired, specificBehavior.TransactionScopeRequired);
  179. }
  180. else if (behavior is TransactionFlowAttribute)
  181. {
  182. instance = existingInstance.NewInstance("TransactionFlowAttribute");
  183. TransactionFlowAttribute specificBehavior = (TransactionFlowAttribute)behavior;
  184. instance.SetProperty(AdministrationStrings.TransactionFlowOption, specificBehavior.Transactions.ToString());
  185. }
  186. else if (behavior is XmlSerializerOperationBehavior)
  187. {
  188. instance = existingInstance.NewInstance("XmlSerializerOperationBehavior");
  189. XmlSerializerOperationBehavior specificBehavior = (XmlSerializerOperationBehavior)behavior;
  190. if (null != specificBehavior.XmlSerializerFormatAttribute)
  191. {
  192. instance.SetProperty(AdministrationStrings.Style, specificBehavior.XmlSerializerFormatAttribute.Style.ToString());
  193. instance.SetProperty(AdministrationStrings.Use, specificBehavior.XmlSerializerFormatAttribute.Use.ToString());
  194. instance.SetProperty(AdministrationStrings.SupportFaults, specificBehavior.XmlSerializerFormatAttribute.SupportFaults.ToString());
  195. }
  196. }
  197. else if (behavior is IWmiInstanceProvider)
  198. {
  199. IWmiInstanceProvider instanceProvider = (IWmiInstanceProvider)behavior;
  200. instance = existingInstance.NewInstance(instanceProvider.GetInstanceType());
  201. instanceProvider.FillInstance(instance);
  202. }
  203. else
  204. {
  205. instance = existingInstance.NewInstance("Behavior");
  206. }
  207. if (null != instance)
  208. {
  209. instance.SetProperty(AdministrationStrings.Type, behavior.GetType().FullName);
  210. }
  211. }
  212. static string FixWildcardAction(string action)
  213. {
  214. #pragma warning suppress 56507
  215. return null != action ? action : MessageHeaders.WildcardAction;
  216. }
  217. static void UpdateContracts()
  218. {
  219. foreach (ServiceInfo info in new ServiceInfoCollection(ManagementExtension.Services))
  220. {
  221. foreach (EndpointInfo endpointInfo in info.Endpoints)
  222. {
  223. ContractInstanceProvider.RegisterContract(endpointInfo.Contract);
  224. }
  225. }
  226. }
  227. void IWmiProvider.EnumInstances(IWmiInstances instances)
  228. {
  229. Fx.Assert(null != instances, "");
  230. int processId = AppDomainInfo.Current.ProcessId;
  231. int appDomainId = AppDomainInfo.Current.Id;
  232. lock (ContractInstanceProvider.knownContracts)
  233. {
  234. UpdateContracts();
  235. foreach (ContractDescription contract in ContractInstanceProvider.knownContracts.Values)
  236. {
  237. IWmiInstance instance = instances.NewInstance(null);
  238. instance.SetProperty(AdministrationStrings.ProcessId, processId);
  239. instance.SetProperty(AdministrationStrings.AppDomainId, appDomainId);
  240. FillContract(instance, contract);
  241. instances.AddInstance(instance);
  242. }
  243. }
  244. }
  245. bool IWmiProvider.GetInstance(IWmiInstance contract)
  246. {
  247. Fx.Assert(null != contract, "");
  248. bool bFound = false;
  249. if ((int)contract.GetProperty(AdministrationStrings.ProcessId) == AppDomainInfo.Current.ProcessId
  250. && (int)contract.GetProperty(AdministrationStrings.AppDomainId) == AppDomainInfo.Current.Id)
  251. {
  252. string contractName = (string)contract.GetProperty(AdministrationStrings.Name);
  253. ContractDescription contractDescription;
  254. UpdateContracts();
  255. if (ContractInstanceProvider.knownContracts.TryGetValue(contractName, out contractDescription))
  256. {
  257. bFound = true;
  258. FillContract(contract, contractDescription);
  259. }
  260. }
  261. return bFound;
  262. }
  263. }
  264. }