WCF and Hosting - Self-Hosting
(Page 2 of 4 )
Self-hosting is the name for the technique used when the developer is responsible for providing and managing the life cycle of the host process. Self-hosting is used both in the case of wanting a process (or machine) boundary between the client and the service, and when using the service in-proc—that is, in the same process as the client. The process you need to provide can be any Windows process, such as a Windows Forms application, a Console application, or a Windows NT Service. Note that the process must be running before the client calls the service, which typically means you have to pre-launch it. This is not an issue for NT Services or in-proc. Providing a host can be done with only a few lines of code, and it does offer a few advantage over IIS hosting.
Similar to IIS hosting, the hosting application config file (App.Config) must list the types of the services you wish to host and expose to the world:
<system.serviceModel>
<services>
<service name = "MyNamespace.MyService">
...
</service>
</services>
</system.serviceModel>
In addition, the host process must explicitly register the service types at runtime and open the host for client calls, which is why the host process must be running before the client calls arrive. Creating the host is typically done in theMain()method using the classServiceHost, defined in Example 1-3.
Example 1-3. The ServiceHost class
public interface ICommunicationObject
{
void Open();
void Close();
//More members
}
public abstract class CommunicationObject : ICommunicationObject
{...}
public abstract class ServiceHostBase : CommunicationObject,IDisposable,...
{...}
public class ServiceHost : ServiceHostBase,...
{
public ServiceHost(Type serviceType,params Uri[] baseAddresses);
//More members
}
You need to provide the constructor ofServiceHostwith the service type, and optionally with default base addresses. The set of base addresses can be an empty set. Even if you provide base addresses, the service can be configured to use different base addresses. Having a set of base addresses enables the service to accept calls on multiple addresses and protocols, and to use only a relative URI. Note that eachServiceHost instance is associated with a particular service type, and if the host process needs to host multiple types of services, you will need a matching number ofServiceHostinstances. By calling theOpen() method on the host, you allow calls in, and by calling theClose()method, you gracefully exit the host instance, allowing calls in progress to complete, and yet refusing future client calls even if the host process is still running. Closing is typically done on host process shutdown. For example, to host this service in a Windows Forms application:
[ServiceContract]
interface IMyContract
{...}
class MyService : IMyContract
{...}
you would have the following hosting code:
public static void Main()
{
Uri baseAddress = new Uri(http://localhost:8000/);
ServiceHost host = new ServiceHost(typeof(MyService),baseAddress);
host.Open();
//Can do blocking calls:
Application.Run(new MyForm());
host.Close();
}
Opening a host loads the WCF runtime and launches worker threads to monitor incoming requests. Since worker threads are involved, you can perform blocking operations after opening the host. Having explicit control over opening and closing the host provides for a nice feature not easily accomplished with IIS hosting: you can build a custom application control applet where the administrator explicitly opens and closes the host at will, without ever shutting down the host.
Using Visual Studio 2005
Visual Studio 2005 allows you to add a WCF service to any application project by selecting WCF Service from the Add New Item dialog box. The service added this way is, of course, in-proc toward the host process, but can be accessed by out-of-proc clients as well.
Self-hosting and base addresses
You can launch a service host without providing any base address by omitting the base addresses altogether:
public static void Main()
{
ServiceHost host = new ServiceHost(typeof(MyService));
host.Open();
Application.Run(new MyForm());
host.Close();
}
Do not provide a null instead of an empty list, because that will throw an exception:
ServiceHost host;
host = new ServiceHost(typeof(MyService),null);
You can also register multiple base addresses separated by a comma, as long as the addresses do not use the same transport schema, as in the following snippet (note the use of theparams qualifier in Example 1-3):
Uri tcpBaseAddress = new Uri("net.tcp://localhost:8001/");
Uri httpBaseAddress = new Uri("http://localhost:8002/");
ServiceHost host = new ServiceHost(typeof(MyService),
tcpBaseAddress,httpBaseAddress);
WCF lets you also list the base addresses in the host config file:
<system.serviceModel>
<services>
<service name = "MyNamespace.MyService">
<host>
<baseAddresses>
<add baseAddress = "net.tcp://localhost:8001/"/>
<add baseAddress = "http://localhost:8002/"/>
</baseAddresses>
</host>
...
</service>
</services>
</system.serviceModel>
When you create the host, it will use whichever base address it finds in the config file, plus any base address you provide programmatically. Take extra care to ensure the configured base addresses and the programmatic ones do not overlap in the schema.
You can even register multiple hosts for the same type as long as the hosts use different base addresses:
Uri baseAddress1 = new Uri("net.tcp://localhost:8001/");
ServiceHost host1 = new ServiceHost(typeof(MyService),baseAddress1);
host1.Open();
Uri baseAddress2 = new Uri("net.tcp://localhost:8002/");
ServiceHost host2 = new ServiceHost(typeof(MyService),baseAddress2);
host2.Open();
However, with the exception of some threading issues discussed in Chapter 8, opening multiple hosts this way offers no real advantage. In addition, opening multiple hosts for the same type does not work with base addresses supplied in the config file and requires use of theServiceHostconstructor.
Next: Advanced hosting features >>
More Windows Scripting Articles
More By O'Reilly Media
|
This article is excerpted from chapter one of Programming WCF Services, written by Juval Lowy (O'Reilly, 2007; ISBN: 0596526997). Check it out today at your favorite bookstore. Buy this book now.
|
|