1

We are in the process of migrating legacy .Net Remoting services to WCF. After reading on the subject for a while, I stumbled upon this metadata talk and building proxies dynamically on the client: it seemed promising.

What I wanted to achieve, if possible, is to expose the services on one web application with minimal configuration (i.e., no explicit <services> node on the config file), and build the proxies in the client (by sharing the interface) also with minimal configuration.

I know it is possible to expose metadata for all services by default, but the way this seems to work is useless, since it generates different urls for each service, and I would then need to maintain dozens of hardcoded strings on my client.

This is my current config file:

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

  <behaviors>
    <serviceBehaviors>
      <behavior>
        <serviceMetadata httpGetEnabled="true" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

I wanted to have a single URL on the server (perhaps the base address itself, 'http://localhost/VirtualDir') and use this endpoint to automatically resolve any service interface from the client. I came across this somewhat old post, which is more or less what I would like to achieve. At the time, there seemed to not be any way to do that gracefully.

Isn't there a way to perhaps expose a single MEX endpoint on the server, and then resolve any contract interface on it? This way I would be able to:

  1. store a single URL on the client
  2. retrieve the endpoint using the MetadataResolver class for a given interface
  3. create the proxy using a ChannelFactory<T> using the resolved endpoint

I wanted to do this inside some kind of factory class, and use it with the Unity IoC container.

I think I can still make this work using some kind of convention to build the many real endpoint addresses using a known format. I would like to avoid that though, since it can still lead to problems.

julealgon
  • 7,072
  • 3
  • 32
  • 77

1 Answers1

1

There are two ways I can think of how you could approach this:

  1. Use WCF Routing Service and employ filters to route based on soap action, or other content.
  2. Create an endpoint which handles Message instances in the request, and then convert them internally.

The drawback of WCF routing is that this is itself another WCF service. And I am not certain if option 2 is even possible exactly how you describe you want it.

Check this MSDN magazine article.

Also MetadataResolver is primarily for use on the client to dynamically resolve endpoints on a service before calling them. I have not seen this implemented before on the service end as you describe.

Additionally, and a minor point, WCF is designed to be used to define an explicit boundary across which two applications communicate. This separation is explicit and expressed as the mutual acceptance of an abstract, verbose, external contract. To attempt to get away from this kind of explicit contract in my opinion would call into question why you need the boundary in the first place. It's almost always better to make calls to services running in-process if you can.

tom redfern
  • 30,562
  • 14
  • 91
  • 126
  • I think you misunderstood some things from my question. I'm not proposing to use the MetadataResolver on the server. What I wanted to achieve is a single URL to the server, and then using Resolve on it, from the client, passing the required interface. As for the in-process calls, I'm not sure I get what you're saying. We need these calls to be remote ones, since the server is a web application and the clients are either other web applications, windows services or desktop applications. I'll see how this routing option works, thanks for the tip. – julealgon Sep 26 '13 at 15:22
  • After just starting to read about the Routing Service, I'm seeing it only supports SOAP messages? That would be a deal breaker since we use generic lists in some places, and the SOAP serializer cannot handle generic classes (we use binary serialization at the moment for all services). – julealgon Sep 26 '13 at 15:38
  • Bummer - well sorry I couldn't be of more help. Regarding the in-process thing - have noticed that people introduce service boundaries all over the place where they're not needed - but sounds like you are not one of them ;) – tom redfern Sep 26 '13 at 15:46
  • Ah ok, I can see why you suggested direct calls now. Unfortunately, this really is not an option for us. We have a bunch of components on our system, and each component can potentially be on a different computer on the network, or even across networks. Also, each component has a very distinct responsibility, so even if it would be possible to directly call the methods, we would have to share a lot of other classes, config files, connectionstrings and stuff like that to make the calls work locally. I feel we would make a huge violation of SRP by doing it, and it would be a mess to manage it too – julealgon Sep 26 '13 at 15:54