>
 Monday, October 03, 2005
« WCF Coding Practices: Proxy vs. ChannelF... | Main | WCF Coding Practices: Decouple Services ... »

I had several conversations this weekend with Steve Swartz (one of my favorite people, not just because he's smart, but he's a really cool guy too!) about best practices in various aspects of the service model. I'll eventually get a chance to blurt all of my thoughts on this (and confirmations a-la Steve) but let's start with the subject: base address and endpoints...how “should” it work?

Consider this example that creates a new self-hosted service with a base address and endpoint Uri as shown here hard-coded:

Uri baseAddress = new Uri("http://localhost:8000/HelloIndigo");
using (ServiceHost host = new ServiceHost(typeof(HelloIndigo.Service), baseAddress))
{

host.AddEndpoint(typeof(HelloIndigo.IService), new BasicHttpBinding(), new Uri("http://localhost:8000/HelloIndigo/Service"));

host.Open();
Console.ReadLine();
host.Close();
}

Seems harmless, and it will work. Clients will bind against the target Uri of the endpoint:

http://localhost:8000/HelloIndigo/Service

But the truth of the matter is that the base address should be relied on as the...well as the base address for all endpoints that share the same protocol, port, etc. In the above example that would suggest that when I add an endpoint to the service host, I should only submit “Service“ as a string (something you can do with one of the overloaded methods for AddEndpoint):

host.AddEndpoint(typeof(HelloIndigo.IService), new BasicHttpBinding(), "Service");

The same goes for declarative configuration for the service host, no need to specify the complete Uri, it will be inferred from the base address:

<service type="HelloIndigo.Service" >
  <endpoint address="Service" contract="HelloIndigo.IService, HelloIndigo"
binding="basicHttpBinding" />
</service>

This makes your services more configurable, modify the base address and relative Uri will follow suit.


 

10/3/2005 8:06 AM Indigo  | Comments [18]  |  View reactions  |  Trackback
Monday, October 03, 2005 3:29:44 PM (GMT Standard Time, UTC+00:00)
Sounds great but you lost fidelity. Where did the service port go?
Monday, October 03, 2005 3:36:21 PM (GMT Standard Time, UTC+00:00)
If I understand the commment, you are wondering how the port is identified when the endpoint is defined as 'Service'. The service port is identified by the base address.
Monday, October 10, 2005 3:31:42 PM (GMT Standard Time, UTC+00:00)
I'm confused. Though I understand just identifying the address in one place and sticking with that, I don't understand why (2nd example) you would hard code the endpoint address into the service class when you are using a config file to set up the rest of the service configuration. Or are you just saying "however you do it, just do it once" - which does make sense.
Saturday, October 15, 2005 4:28:22 AM (GMT Standard Time, UTC+00:00)
Michele, let's take you one step further. :-) Any "configuration" strings should go in your configuration file. This goes doubly for services. Take this example (against Beta2 code). Do this with your config file:

< appSettings >
< !-- use appSetting to configure base address provided by host -- >
< add key="baseAddress" value="http://localhost:8080/ServiceMetadata" / >
< /appSettings >

and then in your host file:

using System;
using System.Configuration;
using System.Collections.Generic;
using System.ServiceModel;
using System.Text;

namespace Microsoft.WCF.Documentation
{
class HostApplication
{

static void Main()
{
HostApplication app = new HostApplication();
app.Run();
}

private void Run()
{
// Get base address from app settings in configuration if you want.
Uri baseAddress = new Uri(ConfigurationManager.AppSettings["baseAddress"]);

// Create a ServiceHost for the service type and provide the base address.
using (ServiceHost serviceHost = new ServiceHost(typeof(SampleService), baseAddress))
{
try
{
// Open the ServiceHostBase to create listeners and start listening for messages.
serviceHost.Open();

// The service can now be accessed.
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("The service is ready.");
Console.WriteLine("Press ENTER to terminate service.");
Console.WriteLine();
Console.ReadLine();

// Close the ServiceHostBase to shutdown the service.
serviceHost.Close();
Console.ResetColor();
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message);
}
}
}
}
}
ralph
Wednesday, October 19, 2005 6:13:33 PM (GMT Standard Time, UTC+00:00)
I think there was some confusion with the purpose of my post.

Julie - I was not referring to how you 'hard-code' or don't configuration...I was referring to the fact that the base address for each protocol should be just that: a base address for all endpoints exposed. So, that means when you define your endpoints, you should only specify "ServiceA" and "ServiceB" for example as the different endpoint addresses, instead of "http://localhost:8000/HelloIndigo/ServiceA" and "http://localhost:8000/HelloIndigo/ServiceB". Make sense?

Ralph - yes, absolutely agreed that configuration should be external for everything. I was simplifying by hard-coding in the sample but my goal was to talk about base addresses and endpoints. QUestion for you...why use "appSettings" instead of the new .NET 2.0 way with strongly typed application settings?

Thanks for the comments, I will post new entries on these topics as well...soon.
Wednesday, October 19, 2005 9:17:53 PM (GMT Standard Time, UTC+00:00)
No reason at all! Or rather, this was faster typing for me. :-) As with your example, I was demonstrating a principle. So let's say we're getting closer to a Best Practices service, eh? Cheers, me.
Tuesday, December 27, 2005 4:27:32 PM (GMT Standard Time, UTC+00:00)
That makes total sence to me. I don't get the proporse of endponints if you can't simply say that it's "MyService". ServiceHost should see that this is an HttpBinding and concat the MyService with the base address.

Hmm.. Even on other bindings the behavior should be the same. Base address should not do anything at all, it should be only a "root" for all endpoints added to that servicehost. If you add an "" endpoint, then yes the baseAddress may expose a service.
Monday, December 03, 2007 8:44:41 PM (GMT Standard Time, UTC+00:00)
enqzg tscj mteuiv dvatikwh vybz kbvlgmzw hknvu
Saturday, January 05, 2008 6:29:42 PM (GMT Standard Time, UTC+00:00)
cyew hnug rlkhexian gkzwvj jqfk dyrk pszy
Saturday, January 05, 2008 6:30:35 PM (GMT Standard Time, UTC+00:00)
cyew hnug rlkhexian gkzwvj jqfk dyrk pszy
Thursday, January 31, 2008 11:05:10 AM (GMT Standard Time, UTC+00:00)
Useful site. Thank you!!!
Thursday, January 31, 2008 12:13:46 PM (GMT Standard Time, UTC+00:00)
Useful site. Thanks!
Tuesday, February 05, 2008 9:18:12 PM (GMT Standard Time, UTC+00:00)
Useful site. Thank you:-)
Monday, February 11, 2008 11:11:26 PM (GMT Standard Time, UTC+00:00)
Useful site. Thanks!!




Monday, February 11, 2008 11:46:18 PM (GMT Standard Time, UTC+00:00)
Useful site. Thanks!!!




Tuesday, February 12, 2008 5:46:05 AM (GMT Standard Time, UTC+00:00)
Useful site. Thank you:-)




Tuesday, February 12, 2008 2:41:56 PM (GMT Standard Time, UTC+00:00)
Useful site. Thank you!!


Tuesday, February 12, 2008 2:41:57 PM (GMT Standard Time, UTC+00:00)
Useful site. Thank you!!


Name
E-mail
(will show your gravatar icon)
Home page

Comment (HTML not allowed)  

    ON THIS PAGE
    SEARCH
    CATEGORIES
    ARCHIVES
    BLOGROLL

Designed by NUKEATION STUDIOS