Сервисная пользовательская конфигурация WCF

Я думаю, что вы используете дистрибутив OSS Elasticsearch и пакет не-OSS Kibana.

Можете ли вы попробовать с docker.elastic.co/kibana/kibana-oss:6.5.4?

6
задан 17 October 2008 в 04:59
поделиться

4 ответа

Я знаю, что это старо, но это никогда не отмечалось, ответил, таким образом, я думал, что сделаю снимок. Если я понимаю то, что Вы после, можно сделать это с пользовательским ServiceHostFactory.
Хорошее сообщение на этом здесь.

Вы создаете yuour пользовательский ServiceHostFactory как так:

<%@ ServiceHost
 Language="C#"
 Debug="true"
 Service="Ionic.Samples.Webservices.Sep20.CustomConfigService"
 Factory="Ionic.ServiceModel.ServiceHostFactory"%>

Затем в Вашем ServiceHostFactory можно переопределить метод под названием ApplyConfiguration. Обычно для приложений WCF, размещенных в IIS, WCF автоматически искал бы конфигурацию в web.config. В этом примере мы переопределяем то поведение для первого поиска файла конфигурации, названного в честь Сервисного Описания WCF.

protected override void ApplyConfiguration()
{
    // generate the name of the custom configFile, from the service name:
    string configFilename = System.IO.Path.Combine ( physicalPath,
        String.Format("{0}.config", this.Description.Name));

    if (string.IsNullOrEmpty(configFilename) || !System.IO.File.Exists(configFilename))
        base.ApplyConfiguration();
    else
        LoadConfigFromCustomLocation(configFilename);
}

Вы могли заменить это "чем-либо" - например, ища конфигурацию в таблице базы данных.

Еще несколько методов завершают загадку.

private string _physicalPath = null;
private string physicalPath
{
    get
    {
        if (_physicalPath == null)
        {
            // if hosted in IIS
            _physicalPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;

            if (String.IsNullOrEmpty(_physicalPath))
            {
                // for hosting outside of IIS
                _physicalPath= System.IO.Directory.GetCurrentDirectory();
            }
        }
        return _physicalPath;
    }
}


private void LoadConfigFromCustomLocation(string configFilename)
{
    var filemap = new System.Configuration.ExeConfigurationFileMap();
    filemap.ExeConfigFilename = configFilename;
    System.Configuration.Configuration config =
        System.Configuration.ConfigurationManager.OpenMappedExeConfiguration
        (filemap,
         System.Configuration.ConfigurationUserLevel.None);
    var serviceModel = System.ServiceModel.Configuration.ServiceModelSectionGroup.GetSectionGroup(config);
    bool loaded= false;
    foreach (System.ServiceModel.Configuration.ServiceElement se in serviceModel.Services.Services)
    {
        if(!loaded)
            if (se.Name == this.Description.ConfigurationName)
            {
                base.LoadConfigurationSection(se);
                loaded= true;
            }
    }

    if (!loaded)
        throw new ArgumentException("ServiceElement doesn't exist");
}
8
ответ дан 9 December 2019 в 22:42
поделиться

Это во многом зависит того, где и то, как Вы ожидаете использовать, сказало информацию. Если это не что-то, что это собирается сделать много с инфраструктурой (т.е. заставляет сервисы выполнять и обрабатывает запросы), я испытал бы желание сказать, что, пытаясь продвинуть это в поведения WCF могло бы добавлять больше сложности, чем это стоит. Вероятно, было бы более просто просто использовать собственный раздел пользовательской конфигурации.

Вы могли разъяснить, как Вы ожидаете использовать эту информацию во времени выполнения? Возможно, тот путь мы можем предоставить более явную консультацию...

0
ответ дан 9 December 2019 в 22:42
поделиться

Ну, я думал пример, который я дал, было довольно тщательно продумано. Я попытаюсь уточнить далее...

В основном я хочу смочь передать данные пользовательской конфигурации службе WCF в приложении, где может быть несколько сервисных выполнений WCF.

Таким образом, то, что это означает, находится в экземпляр сервиса, работающего в приложении, я хочу получить доступ к данным, которые были настроены специально для того сервиса (и не другого сервиса). Я предполагаю, что мог сделать это просто при помощи параметров настройки приложения и использования типа сервиса как ключ. Я надеялся, что WCF мог бы иметь некоторые лучшие конструкции для этого.

0
ответ дан 9 December 2019 в 22:42
поделиться

У меня была похожая проблема, но я использовал DuplexChannel. На основании пост я обнаружил, что нашел, что решил эту проблему так:

public class CustomDuplexChannelFactory<TChannel> : DuplexChannelFactory<TChannel>
{
    public static string ConfigurationPath { get; set; }

    public CustomDuplexChannelFactory(InstanceContext callbackInstance)
        : base(callbackInstance)
    {
    }

    protected override ServiceEndpoint CreateDescription()
    {
        ServiceEndpoint serviceEndpoint = base.CreateDescription();

        if(ConfigurationPath == null || !File.Exists(ConfigurationPath))
            return base.CreateDescription();

        ExeConfigurationFileMap executionFileMap = new ExeConfigurationFileMap();
        executionFileMap.ExeConfigFilename = ConfigurationPath;
        System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(executionFileMap, ConfigurationUserLevel.None);
        ServiceModelSectionGroup serviceModeGroup = ServiceModelSectionGroup.GetSectionGroup(config);
        ChannelEndpointElement selectedEndpoint = null;
        foreach(ChannelEndpointElement endpoint in serviceModeGroup.Client.Endpoints)
        {
            if(endpoint.Contract == serviceEndpoint.Contract.ConfigurationName)
            {
                selectedEndpoint = endpoint; break;
            }
        }
        if(selectedEndpoint != null)
        {
            if(serviceEndpoint.Binding == null)
            {
                serviceEndpoint.Binding = CreateBinding(selectedEndpoint.Binding, serviceModeGroup);
            } if(serviceEndpoint.Address == null)
            {
                serviceEndpoint.Address = new EndpointAddress(selectedEndpoint.Address,
                GetIdentity(selectedEndpoint.Identity), selectedEndpoint.Headers.Headers);
            } if(serviceEndpoint.Behaviors.Count == 0 && !String.IsNullOrEmpty(selectedEndpoint.BehaviorConfiguration))
            {
                AddBehaviors(selectedEndpoint.BehaviorConfiguration,
                    serviceEndpoint, serviceModeGroup);
            }
            serviceEndpoint.Name = selectedEndpoint.Contract;
        }
        return serviceEndpoint;
    }

    private Binding CreateBinding(string bindingName, ServiceModelSectionGroup group)
    {
        BindingCollectionElement bindingElementCollection = group.Bindings[bindingName];
        if(bindingElementCollection.ConfiguredBindings.Count > 0)
        {
            IBindingConfigurationElement be = bindingElementCollection.ConfiguredBindings[0];
            Binding binding = GetBinding(be); if(be != null)
            {
                be.ApplyConfiguration(binding);
            }
            return binding;
        }
        return null;
    }

    private void AddBehaviors(string behaviorConfiguration, ServiceEndpoint serviceEndpoint, ServiceModelSectionGroup group)
    {
        EndpointBehaviorElement behaviorElement = group.Behaviors.EndpointBehaviors[behaviorConfiguration];
        for(int i = 0; i < behaviorElement.Count; i++)
        {
            BehaviorExtensionElement behaviorExtension = behaviorElement[i];
            object extension = behaviorExtension.GetType().InvokeMember("CreateBehavior", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, behaviorExtension, null);
            if(extension != null)
            {
                serviceEndpoint.Behaviors.Add((IEndpointBehavior)extension);
            }
        }
    }

    private EndpointIdentity GetIdentity(IdentityElement element)
    {
        EndpointIdentity identity = null;
        PropertyInformationCollection properties = element.ElementInformation.Properties;
        if(properties["userPrincipalName"].ValueOrigin != PropertyValueOrigin.Default)
        {
            return EndpointIdentity.CreateUpnIdentity(element.UserPrincipalName.Value);
        }
        if(properties["servicePrincipalName"].ValueOrigin != PropertyValueOrigin.Default)
        {
            return EndpointIdentity.CreateSpnIdentity(element.ServicePrincipalName.Value);
        }
        if(properties["dns"].ValueOrigin != PropertyValueOrigin.Default)
        {
            return EndpointIdentity.CreateDnsIdentity(element.Dns.Value);
        }
        if(properties["rsa"].ValueOrigin != PropertyValueOrigin.Default)
        {
            return EndpointIdentity.CreateRsaIdentity(element.Rsa.Value);
        }
        if(properties["certificate"].ValueOrigin != PropertyValueOrigin.Default)
        {
            X509Certificate2Collection supportingCertificates = new X509Certificate2Collection();
            supportingCertificates.Import(Convert.FromBase64String(element.Certificate.EncodedValue));

            if(supportingCertificates.Count == 0)
            {
                throw new InvalidOperationException("UnableToLoadCertificateIdentity");
            }

            X509Certificate2 primaryCertificate = supportingCertificates[0]; supportingCertificates.RemoveAt(0);
            return EndpointIdentity.CreateX509CertificateIdentity(primaryCertificate, supportingCertificates);
        }
        return identity;
    }

    private Binding GetBinding(IBindingConfigurationElement configurationElement)
    {
        if(configurationElement is CustomBindingElement)
            return new CustomBinding();
        else if(configurationElement is BasicHttpBindingElement)
            return new BasicHttpBinding();
        else if(configurationElement is NetMsmqBindingElement)
            return new NetMsmqBinding();
        else if(configurationElement is NetNamedPipeBindingElement)
            return new NetNamedPipeBinding();
        else if(configurationElement is NetPeerTcpBindingElement)
            return new NetPeerTcpBinding();
        else if(configurationElement is NetTcpBindingElement)
            return new NetTcpBinding();
        else if(configurationElement is WSDualHttpBindingElement)
            return new WSDualHttpBinding();
        else if(configurationElement is WSHttpBindingElement)
            return new WSHttpBinding();
        else if(configurationElement is WSFederationHttpBindingElement)
            return new WSFederationHttpBinding();
        return null;
    }
}

Я обобщил это в своем блоге

3
ответ дан 9 December 2019 в 22:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: