ConfigWriter.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Description
  5. {
  6. using System;
  7. using System.ServiceModel.Channels;
  8. using System.Configuration;
  9. using System.Collections.Generic;
  10. using System.ServiceModel;
  11. using System.ServiceModel.Configuration;
  12. using System.ServiceModel.Diagnostics;
  13. internal class ConfigWriter
  14. {
  15. readonly Dictionary<Binding, BindingDictionaryValue> bindingTable;
  16. readonly BindingsSection bindingsSection;
  17. readonly ChannelEndpointElementCollection channels;
  18. readonly Configuration config;
  19. internal ConfigWriter(Configuration configuration)
  20. {
  21. this.bindingTable = new Dictionary<Binding, BindingDictionaryValue>();
  22. this.bindingsSection = BindingsSection.GetSection(configuration);
  23. ServiceModelSectionGroup serviceModelSectionGroup = ServiceModelSectionGroup.GetSectionGroup(configuration);
  24. this.channels = serviceModelSectionGroup.Client.Endpoints;
  25. this.config = configuration;
  26. }
  27. internal ChannelEndpointElement WriteChannelDescription(ServiceEndpoint endpoint, string typeName)
  28. {
  29. ChannelEndpointElement channelElement = null;
  30. // Create Binding
  31. BindingDictionaryValue bindingDV = CreateBindingConfig(endpoint.Binding);
  32. channelElement = new ChannelEndpointElement(endpoint.Address, typeName);
  33. // [....]: review: Use decoded form to preserve the user-given friendly name, however, beacuse our Encoding algorithm
  34. // does not touch ASCII names, a name that looks like encoded name will not roundtrip(Example: "_x002C_" will turned into ",")
  35. channelElement.Name = NamingHelper.GetUniqueName(NamingHelper.CodeName(endpoint.Name), this.CheckIfChannelNameInUse, null);
  36. channelElement.BindingConfiguration = bindingDV.BindingName;
  37. channelElement.Binding = bindingDV.BindingSectionName;
  38. channels.Add(channelElement);
  39. return channelElement;
  40. }
  41. internal void WriteBinding(Binding binding, out string bindingSectionName, out string configurationName)
  42. {
  43. BindingDictionaryValue result = CreateBindingConfig(binding);
  44. configurationName = result.BindingName;
  45. bindingSectionName = result.BindingSectionName;
  46. }
  47. BindingDictionaryValue CreateBindingConfig(Binding binding)
  48. {
  49. BindingDictionaryValue bindingDV;
  50. if (!bindingTable.TryGetValue(binding, out bindingDV))
  51. {
  52. // [....]: review: Use decoded form to preserve the user-given friendly name, however, beacuse our Encoding algorithm
  53. // does not touch ASCII names, a name that looks like encoded name will not roundtrip(Example: "_x002C_" will turned into ",")
  54. string bindingName = NamingHelper.GetUniqueName(NamingHelper.CodeName(binding.Name), this.CheckIfBindingNameInUse, null);
  55. string bindingSectionName;
  56. if (!BindingsSection.TryAdd(bindingName, binding, config, out bindingSectionName))
  57. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.ConfigBindingCannotBeConfigured), "endpoint.Binding"));
  58. bindingDV = new BindingDictionaryValue(bindingName, bindingSectionName);
  59. bindingTable.Add(binding, bindingDV);
  60. }
  61. return bindingDV;
  62. }
  63. bool CheckIfBindingNameInUse(string name, object nameCollection)
  64. {
  65. foreach (BindingCollectionElement bindingCollectionElement in this.bindingsSection.BindingCollections)
  66. if (bindingCollectionElement.ContainsKey(name))
  67. return true;
  68. return false;
  69. }
  70. bool CheckIfChannelNameInUse(string name, object namingCollection)
  71. {
  72. foreach (ChannelEndpointElement element in this.channels)
  73. if (element.Name == name)
  74. return true;
  75. return false;
  76. }
  77. sealed class BindingDictionaryValue
  78. {
  79. public readonly string BindingName;
  80. public readonly string BindingSectionName;
  81. public BindingDictionaryValue(string bindingName, string bindingSectionName)
  82. {
  83. this.BindingName = bindingName;
  84. this.BindingSectionName = bindingSectionName;
  85. }
  86. }
  87. }
  88. }