修改服务主机基地址,无需重写应用配置文件

发布于 2024-10-06 10:28:25 字数 1634 浏览 1 评论 0原文

我试图在启动 WCF 服务主机之前调整主机基地址,以将 instanceName 添加到基地址:

var baseAddresses = Utils<Uri>.EmptyList;

var cfg = ConfigurationManager.OpenExeConfiguration(
    ConfigurationUserLevel.None);
var serviceModelGroup = cfg.GetSectionGroup("system.serviceModel") as 
    ServiceModelSectionGroup;

var wcfPortalServiceElement = serviceModelGroup.Services.
    Services[typeof(WcfPortal).FullName];
if (wcfPortalServiceElement != null && wcfPortalServiceElement.Host != null)
{
  baseAddresses = wcfPortalServiceElement.Host
        .BaseAddresses
        .Cast<BaseAddressElement>()
        .Select(e => new Uri(e.BaseAddress + "/" + instanceName, 
            UriKind.Absolute))
        .ToArray();
}

app.config 文件如下所示:

<services>
  <service name="MyCompany.Common.Csla.WcfPortal" 
      behaviorConfiguration="serviceBehavior">
    <endpoint contract="Csla.Server.Hosts.IWcfPortal"
              binding="customBinding"
              bindingConfiguration="compressed_httpConfig"/>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8001/MyAgent" />
      </baseAddresses>
    </host>
  </service>
</services>

动机:我希望能够在同一台计算机上多次运行相同的代理进程。每个实例都有不同的名称(在命令行上给出),该名称应包含在主机基地址中。 现在,如果 app.config 根本不包含 baseAddresses 集合,那么这很容易做到。但是,我希望它存在,以防在没有给出实例名称的情况下运行单个代理进程。

问题在于服务主机将其构造函数中给出的基地址与 app.config 中出现的基地址合并。当然,它会失败并出现异常,因为它发现了两个具有 http 方案的地址。

另外:当尝试根据正在运行的实例修改 WCF 地址时,我是否遵循主流 WCF 理念?如果我在黑客的迷宫中迷路了 - 请告诉我回到主路的路。

I am trying to adjust the host base address prior to launching the WCF service host to add an instanceName to the base address:

var baseAddresses = Utils<Uri>.EmptyList;

var cfg = ConfigurationManager.OpenExeConfiguration(
    ConfigurationUserLevel.None);
var serviceModelGroup = cfg.GetSectionGroup("system.serviceModel") as 
    ServiceModelSectionGroup;

var wcfPortalServiceElement = serviceModelGroup.Services.
    Services[typeof(WcfPortal).FullName];
if (wcfPortalServiceElement != null && wcfPortalServiceElement.Host != null)
{
  baseAddresses = wcfPortalServiceElement.Host
        .BaseAddresses
        .Cast<BaseAddressElement>()
        .Select(e => new Uri(e.BaseAddress + "/" + instanceName, 
            UriKind.Absolute))
        .ToArray();
}

The app.config file looks as following:

<services>
  <service name="MyCompany.Common.Csla.WcfPortal" 
      behaviorConfiguration="serviceBehavior">
    <endpoint contract="Csla.Server.Hosts.IWcfPortal"
              binding="customBinding"
              bindingConfiguration="compressed_httpConfig"/>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8001/MyAgent" />
      </baseAddresses>
    </host>
  </service>
</services>

Motivation: I want to be able to run the same agent process several times on the same machine. Each instance has distinct name (given on the command line), which should be incorporated in the host base address.
Now, this is easy to do if the app.config does not include the baseAddresses collection at all. However, I would like it to be there in case a single agent process is run without being given the instance name.

The problem is that the service host merges the base addresses given in its constructor with those appearing in app.config. Naturally it fails with an exception, because it discovers two addresses with the http scheme.

Also: am I following the mainstream WCF philosophy, when trying to modify the WCF address, depending on a running instance? If I am lost in the labyrinth of hacks - please show the way back to the main road.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

勿忘心安 2024-10-13 10:28:25

只是想一个真正简单的方法。如果您已经有一种在不存在基地址的情况下连接到实例的方法,那么我将删除基地址。然后,我会将基地址和默认实例名称放入 app.config appsetings 部分。然后在代码中结合命令行中给出的基址和实例名称,或者如果未给出实例名称,则使用 appSettings 中的 DefaultInstance 名称。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="BaseAddress" value="http://localhost:8001/" />
    <add key="DefaultInstance" value="MyAgent" />
  </appSettings>
</configuration>

为了充分披露,您可以使用此代码轻松读取这些值。

System.Configuration.ConfigurationManager.AppSettings["BaseAddress"]

Just thinking of a real simple approach. If you already have a method for connecting to an instance if no base address is present, I would remove the base address. Then I would place the base address and the default instance name into the app.config appsetings section. Then in code combine the base address and instance name given at the command line or if no instance name is given then use DefaultInstance name from appSettings.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="BaseAddress" value="http://localhost:8001/" />
    <add key="DefaultInstance" value="MyAgent" />
  </appSettings>
</configuration>

And just for full disclosure you can read these values easily with this code.

System.Configuration.ConfigurationManager.AppSettings["BaseAddress"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文