tags:

views:

51

answers:

1

In the following config file excerpt, the WCF service has two endpoints.

  <service behaviorConfiguration="AtomTcpHub.Behavior" 
           name="AtomTcpHub.HubTcp">
    <endpoint address="" binding="netTcpBinding" 
              name="AtomHubEndpoint" contract="AtomLib.IAtomPublisher">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" 
              name="" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8731/AtomTcpHub/" />
        <add baseAddress="net.tcp://dv-pw/AtomTcpHub/" />
      </baseAddresses>
    </host>
  </service>

In my code there is discovery logic, which responds to a UDP request by replying with the connection Uri for the WCF service. Obtaining a collection of endpoints is straightforward.

System.Configuration.Configuration config = System.Configuration
  .ConfigurationManager
  .OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None);
ServicesSection section = config.SectionGroups["system.serviceModel"]
  .Sections["services"] as ServicesSection;
ServiceEndpointElementCollection seec = 
  section.Services["AtomTcpHub.HubTcp"].Endpoints;

The problem is extracting the ServiceEndpointElement. We can have it by index:

ServiceEndpointElement see = seec[0];

but this is brittle; if the order of nodes changes it will break. Visual Studio tells me there is another indexer permitting an object value, but there is no further indication. Experimentation tells me that it isn't the value of the name attribute.

The following code works, but it's just hideous.

string serviceEndpointUri;
foreach(ServiceEndpointElement serviceEndpointElement in seec)
  if (serviceEndpointElement.Name == "AtomHubEndpoint")
  {
    _serviceEndpointUri = serviceEndpointElement.Address.AbsoluteUri;
    break;
  }

Is there a more direct or more elegant way to do this?

+1  A: 

You could always use some Linq to accomplish this, to simply shorten things a bit.

ServiceEndpointElement element =
seec.OfType<ServiceEndpointElement>()
.FirstOrDefault(s => s.Name == "AtomHubEndpoint");
David Morton
Not quite a hash lookup; it just hides the loop. But I think this is as good as it's likely to get.
Peter Wone