| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using System.Collections; |
| | | 6 | | using System.Configuration; |
| | | 7 | | using System.IO; |
| | | 8 | | using System.Linq; |
| | | 9 | | using System.Reflection; |
| | | 10 | | using System.Runtime.InteropServices; |
| | | 11 | | using Microsoft.Extensions.DependencyInjection; |
| | | 12 | | using Microsoft.Extensions.Options; |
| | | 13 | | |
| | | 14 | | namespace CoreWCF.Configuration |
| | | 15 | | { |
| | | 16 | | internal class ConfigurationManagerServiceModelOptions : IConfigureNamedOptions<ServiceModelOptions> |
| | | 17 | | { |
| | | 18 | | private readonly Lazy<ServiceModelSectionGroup> _section; |
| | | 19 | | |
| | | 20 | | private readonly IConfigurationHolder _holder; |
| | | 21 | | |
| | 40 | 22 | | public ConfigurationManagerServiceModelOptions(IServiceProvider builder, string path) |
| | | 23 | | { |
| | 40 | 24 | | _holder = builder.GetRequiredService<IConfigurationHolder>(); |
| | | 25 | | |
| | 40 | 26 | | _section = new Lazy<ServiceModelSectionGroup>(() => |
| | 40 | 27 | | { |
| | 40 | 28 | | var assembly = Assembly.GetEntryAssembly(); |
| | 40 | 29 | | var basePath = string.IsNullOrEmpty(assembly?.Location) ? AppContext.BaseDirectory : Path.GetDirectoryNa |
| | 40 | 30 | | |
| | 40 | 31 | | // hack - in .net core 2.1 on linux directory not correct(on unit tests), |
| | 40 | 32 | | // for example: |
| | 40 | 33 | | // /home/vsts/.nuget/packages/microsoft.testplatform.testhost/16.7.1/lib/netcoreapp2.1/ |
| | 40 | 34 | | var isNetCore21 = RuntimeInformation.FrameworkDescription.Contains(".NET Core 4.6"); |
| | 40 | 35 | | if (isNetCore21 && RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) |
| | 40 | 36 | | { |
| | 0 | 37 | | basePath = AppContext.BaseDirectory; |
| | 40 | 38 | | } |
| | 40 | 39 | | |
| | 40 | 40 | | var configMap = new ExeConfigurationFileMap(Path.Combine(basePath, "CoreWCF.machine.config")) |
| | 40 | 41 | | { |
| | 40 | 42 | | ExeConfigFilename = path |
| | 40 | 43 | | }; |
| | 40 | 44 | | System.Configuration.Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(confi |
| | 40 | 45 | | var section = ServiceModelSectionGroup.GetSectionGroup(configuration); |
| | 40 | 46 | | |
| | 40 | 47 | | if (section is null) |
| | 40 | 48 | | { |
| | 0 | 49 | | throw new ServiceModelConfigurationException("Section not found"); |
| | 40 | 50 | | } |
| | 40 | 51 | | |
| | 40 | 52 | | return section; |
| | 40 | 53 | | }, true); |
| | 40 | 54 | | } |
| | | 55 | | |
| | | 56 | | public void Configure(string name, ServiceModelOptions options) |
| | | 57 | | { |
| | 2 | 58 | | Configure(options); |
| | 2 | 59 | | } |
| | | 60 | | |
| | | 61 | | public void Configure(ServiceModelOptions options) |
| | | 62 | | { |
| | 40 | 63 | | var configHolder = ParseConfig(); |
| | 102 | 64 | | foreach (var serviceEndPoint in configHolder.Endpoints) |
| | | 65 | | { |
| | 13 | 66 | | IXmlConfigEndpoint configEndpoint = configHolder.GetXmlConfigEndpoint(serviceEndPoint); |
| | 13 | 67 | | options.ConfigureService(configEndpoint.Service, serviceConfig => |
| | 13 | 68 | | { |
| | 2 | 69 | | serviceConfig.AddServiceEndpoint(configEndpoint.Contract, configEndpoint.Binding, configEndpoint.Add |
| | 15 | 70 | | }); |
| | | 71 | | } |
| | 38 | 72 | | } |
| | | 73 | | |
| | | 74 | | private void ReadConfigSection(ServiceModelSectionGroup group) |
| | | 75 | | { |
| | 40 | 76 | | if (group is null) |
| | | 77 | | { |
| | 0 | 78 | | return; |
| | | 79 | | } |
| | | 80 | | |
| | 40 | 81 | | AddBinding(group.Bindings?.BasicHttpBinding.Bindings); |
| | 40 | 82 | | AddBinding(group.Bindings?.NetTcpBinding.Bindings); |
| | 40 | 83 | | AddBinding(group.Bindings?.NetHttpBinding.Bindings); |
| | 40 | 84 | | AddBinding(group.Bindings?.wsHttpBinding.Bindings); |
| | 40 | 85 | | AddBinding(group.Bindings?.WebHttpBinding.Bindings); |
| | 40 | 86 | | AddBinding(group.Bindings?.CustomBinding.Bindings); |
| | 38 | 87 | | AddEndpoint(group.Services?.Services); |
| | 38 | 88 | | } |
| | | 89 | | |
| | | 90 | | private void AddEndpoint(IEnumerable endpoints) |
| | | 91 | | { |
| | 96 | 92 | | foreach (ServiceElement bindingElement in endpoints.OfType<ServiceElement>()) |
| | | 93 | | { |
| | 10 | 94 | | string serviceName = bindingElement.Name; |
| | | 95 | | |
| | 46 | 96 | | foreach (ServiceEndpointElement endpoint in bindingElement.Endpoints.OfType<ServiceEndpointElement>()) |
| | | 97 | | { |
| | 13 | 98 | | _holder.AddServiceEndpoint( |
| | 13 | 99 | | endpoint.Name, |
| | 13 | 100 | | serviceName, |
| | 13 | 101 | | endpoint.Address, |
| | 13 | 102 | | endpoint.Contract, |
| | 13 | 103 | | endpoint.Binding, |
| | 13 | 104 | | endpoint.BindingConfiguration, |
| | 13 | 105 | | endpoint.BindingNamespace); |
| | | 106 | | } |
| | | 107 | | } |
| | 38 | 108 | | } |
| | | 109 | | |
| | | 110 | | private void AddBinding(IEnumerable bindings) |
| | | 111 | | { |
| | 556 | 112 | | foreach (IStandardBindingElement bindingElement in bindings.OfType<IStandardBindingElement>()) |
| | | 113 | | { |
| | 39 | 114 | | Channels.Binding binding = bindingElement.CreateBinding(); |
| | 37 | 115 | | _holder.AddBinding(binding); |
| | | 116 | | } |
| | 238 | 117 | | } |
| | | 118 | | |
| | | 119 | | private IConfigurationHolder ParseConfig() |
| | | 120 | | { |
| | 40 | 121 | | ReadConfigSection(_section.Value); |
| | 38 | 122 | | return _holder; |
| | | 123 | | } |
| | | 124 | | |
| | | 125 | | |
| | | 126 | | } |
| | | 127 | | } |