So far in this chapter, I have shown you different ways to create services, how to
expose a service endpoint and metadata exchange endpoint, how to generate client
proxies, how to work with metadata, and how to configure service behaviors. In this
section, I’ll place the emphasis on endpoints, binding configuration, and allocation
of assemblies for a more complex solution.
WCF includes a number of standard bindings that allow you to quickly configure a
service for a particular set of protocols. Clients must use compatible protocols when
they communicate with each endpoint. Services can expose multiple endpoints for
the same service contract in order to expose functionality over different protocols.
For example, a service may be called by internal clients over TCP, but by external clients
over HTTP. In addition to supporting different protocols, internal and external
clients may not have access to the same service contracts. Some operations may be
allowed only by clients within the domain, while others are publicly available to
remote clients on the Internet.
In this lab you will configure multiple endpoints for a service to support different endpoint
and binding configurations. In the process you’ll explore the following concepts:
Hosting multiple services
Configuring multiple endpoints for a service
Accessing a service from a Windows client application
Initializing proxies from multiple endpoint and binding configurations
Comparing proxy generation to sharing types between services and clients
Lab: Hosting Multiple Services and Sharing Types
In this lab, you’ll modify an existing solution to implement a service contract and an
administrative contract on two distinct services. You’ll then host each service in the
same host process, a console application. An internal client presumed to be behind
the firewall will consume each service using network protocols such as TCP and
named pipes. This client will have access to service operations exposed by the service
contract and administrative contract. An external client, presumed to be accessing
the service over the Internet will have access only to operations exposed by the
service contract over HTTP. The internal client will share class libraries to access service
contracts, while the external client will use traditional methods for generating
service proxies.
Implementing multiple contracts on a service
In this section, you’re going to implement the predefined service contracts on two
distinct services. Each service will expose two contracts: one for business functionality
core to the service, the other for administrative functionality. Both services will
implement the same administrative contract. This illustrates an example of contract
factoring for reuse.
Start by opening the solution <YourLearningWCFPath>\Labs\Chapter1\MultiContractService\MultiContractService.sln.
This solution contains several
shell projects, including a service library, a host, and two Windows client applications
as follows:
BusinessServiceContracts
A class library containing three contracts: IAdmin, IServiceA, and IServiceB.
IAdmin defines administrative operations. IServiceA and IServiceB respectively
describe functionality to be exposed by ServiceA and ServiceB.
BusinessServices
A class library that will contain two services: ServiceA and ServiceB.
Host
A console application that will host ServiceA and ServiceB.
InternalClient
A windows client application that will access services behind the firewall.
ExternalClient
A windows client application that will access services over the Internet.
Putting service contracts into a separate class library facilitates sharing
metadata with client applications when you own both sides of the
development effort.
The first thing you’ll do is provide an implementation for ServiceA, which is
located in the BusinessServices class library. First, take a look at the contracts
you will implement. Go to the BusinessServiceContracts project and open
IServiceA.cs; you’ll see a contract with two operations. Now open IAdmin.cs and
you’ll see another contract with two different operations.
To implement these contracts, go to the BusinessServices project. First, add a
reference to the BusinessServiceContracts project so you can access the contracts
it defines. Then open ServiceA.cs and add a using statement for the
BusinessServiceContracts namespace, as shown here:
using BusinessServiceContracts;
Modify the definition of ServiceA so that it derives from IServiceA and IAdmin as
follows:
Implement both contracts implicitly. You can use a shortcut by hovering your
mouse over IServiceA and using the smart tag to select "Implement interface
IServiceA," as shown in Figure 1-29.
Complete the implementation by adding the code shown in Example 1-17.
Follow a similar set of steps to implement ServiceB. Open ServiceB.cs and derive
the class from IServiceB and IAdmin. Implement both interfaces implicitly so that
the result looks like the code in Example 1-18. Don’t forget to add the using
statement for the BusinessServiceContracts namespace.
Verify that the BusinessServices project compiles without error.
Hosting two services with multiple contracts
Now you will host both services in a single console application. This will require you
to create two ServiceHost instances and provide two <service> configuration sections,
one for each service type.
First, make sure the Host project can access the service contracts and service
types. Go to the Host project and add assembly references to two projects:
BusinessServiceContracts and BusinessServices.
2. In the application configuration file provided for the Host, provide configuration
settings for both services. Open the app.config file and add the <system.serviceModel> section shown in Example 1-19. This section belongs inside the
<configuration> section of the file.
The configuration section for ServiceA exposes two endpoints for the service
contract IServiceA: one for Internet access over HTTP, another for TCP access
behind the firewall. ServiceB also exposes two endpoints for the service contract
IServiceB: one for Internet access and another for named pipe access restricting
communications to the same machine.
Both services expose the IAdmin contract over TCP and named pipes, respectively,
allowing callers on the same machine, or on remote machines behind the
firewall. They also expose mex endpoints and enable the service metadata
behavior for proxy generation.
Each service configuration also provides the appropriate base addresses for the
protocols they support across all endpoints.
Example 1-19. Service model configuration for ServiceA and ServiceB
Each <service> section holds configuration settings for its own base
addresses and endpoints. Recall that the configuration for a particular
service is used to initialize a ServiceHost instance for that service type.
Be mindful that base addresses across all sections must have unique
ports since a port can be opened only once per machine.
Now that service model configuration has been provided for each service, you
will write code to initialize and open a ServiceHost instance for both. Go to the
Host project and open Program.cs. Modify the Main( ) entry point so that it
includes the code shown in Example 1-20. You will also need to add a using
statement for System.ServiceModel.
This code creates two distinct ServiceHost instances, one for each service. They
are both constructed and opened within a try…finally block to ensure that
Close( ) is called for each when the host shuts down or if a fatal exception
occurs.
Example 1-20. Initializing the ServiceHost for ServiceA and ServiceB
Compile and run the Host project once to verify that no errors occur.
Because metadata browsing is enabled in the configuration section for each service
type, you can browse to the WSDL document for each service by providing the
HTTP base address for each service. Note that each service has its own distinct
WSDL document, but for each individual service, all endpoints for the service are
included in its WSDL document.
Consuming internal services using shared contracts
In this part of the lab, you will implement the internal client application and invoke
service operations over TCP and named pipe protocols. The purpose of this exercise
is to illustrate how you might share service metadata when you own both sides of the
development effort for intranet clients. Sharing contract libraries ensures both sides
are compiling against the latest contract versions throughout the development cycle.
In addition, this exercise will illustrate the use of different standard bindings for TCP
and named pipes.
First, go to the InternalClient project and add a reference to the
BusinessServiceContracts project. This will give the client application direct access
to the service contract necessary to invoke the service.
2. The client application requires prior knowledge of the service endpoints it can
reach before it can configure a proxy. Under the assumption that you own both
sides, client developers will manually configure client endpoints to reach each
service endpoint. In this
case, you’ll consume ServiceA over TCP and ServiceB
over named pipes.
Open the app.config file and add the <system.serviceModel> section shown in
Example 1-21. This includes two endpoints for each service: one for the main
service contract, the other for the administrative contract. The binding for each
endpoint matches the binding configuration for the same endpoint at the service.
In this case, TCP endpoints use netTcpBinding, and named pipe endpoints
use netNamedPipeBinding.
Example 1-21. Service model configuration for the InternalClient
Remember that when you select a binding, you are selecting a transport
protocol, a message encoding format, and possibly other messaging
protocols for security and reliability, for example. The details of
what goes into a binding will be discussed in Chapter 3. The important
thing is that if you use the defaults on both sides, the communication
channel at each end will be compatible.
Now you will write some code to invoke each service endpoint on both services.
To do this, you will need four proxy references: one for each service and contract.
Open Form1.cs and add a using statement for BusinessServiceContracts. In
addition, declare a proxy for each contract, scoped to the lifetime of the application,
adding the following definitions as members of Form1:
using BusinessServiceContracts;
public partial class Form1 : Form
{
IServiceA m_proxyA;
IAdmin m_adminProxyA;
IServiceB m_proxyB;
IAdmin m_adminProxyB;
// more code
}
In the form constructor, initialize each proxy using ChannelFactory<T>. The
proxies for IServiceA and IServiceB can use the default client endpoint for each
contract. Because there is only one endpoint for each contract type, you don’t
have to specify which <endpoint> section will initialize the proxy.
Since IAdmin has two endpoints defined, one for TCP and another for named
pipes, you must specify which endpoint will initialize the proxy when you construct
ChannelFactory<T>. Do this by passing the appropriate endpoint name
from Example 1-21.
You’ll see the resulting code for the form constructor in Example 1-22. You must
also add a reference to System.ServiceModel, as shown.
Example 1-22. Code to initialize ServiceA and ServiceB proxies
using System.ServiceModel;
public Form1( )
{
InitializeComponent( );
ChannelFactory<IServiceA> factoryA = new
ChannelFactory<IServiceA>("");
m_proxyA = factoryA.CreateChannel( );
ChannelFactory<IAdmin> adminFactoryA = new
ChannelFactory<IAdmin>("TCP_IAdmin");
m_adminProxyA = adminFactoryA.CreateChannel( );
ChannelFactory<IServiceB> factoryB = new
ChannelFactory<IServiceB>("");
m_proxyB = factoryB.CreateChannel( );
ChannelFactory<IAdmin> adminFactoryB = new
ChannelFactory<IAdmin>("IPC_IAdmin");
m_adminProxyB = adminFactoryB.CreateChannel( );
}
The user interface for the client has already been created. If you look at Form1.cs
in design view, you’ll see a button to test each service and administrative operation.
Now you’ll add code to invoke each operation using the appropriate proxy.
For each button on the form, add a handler for the Click event; you can do this
by double-clicking each button from design view. Inside each Click event handler,
add code to invoke the appropriate operation and show the result in a message
box. The resulting code for each of these handlers is shown in
Example 1-23.
Just adding the code from Example 1-23 will not be sufficient to hook
up the event handlers. When you double-click each button in design
view, this generates designer code to hook up each event handler to its
Button control.
Example 1-23. Code to invoke all service operations
It is always good practice to release resources when you are finished with them.
To make sure that each of the channels are properly disposed of when the application
exits, add code to explicitly close each proxy. First, add a new private
function named CloseProxy( ) that will cast each proxy to ICommunicationObject
and safely invoke its Close( ) operation, swallowing any errors that may occur to
prevent an exception during exit. Then, add an event handler for the
FormClosing event of Form1 and add code to call CloseProxy( ) for each proxy.
The code to add is shown in Example 1-24.
Example 1-24. Code to close each proxy
private void CloseProxy(ICommunicationObject proxy)
{
try
{
if (proxy != null)
proxy.Close( );
}
catch { }
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
CloseProxy(m_proxyA as ICommunicationObject);
CloseProxy(m_proxyB as ICommunicationObject);
CloseProxy(m_adminProxyA as ICommunicationObject);
CloseProxy(m_adminProxyB as ICommunicationObject);
}
Compile the solution and test the internal client. Run the Host project first, and
then run InternalClient. Click each button to invoke operations exposed by
ServiceA and ServiceB.
Consuming external services with a generated proxy
Now you will implement the external client application and invoke service operations
over HTTP. In this case, the client will rely on the WSDL document to generate
a proxy and related configuration to call the service. This exercise will illustrate
how the proxy generation process handles multiple contracts and endpoints.
Start by running the Host project so that you can generate proxies for each service.
Go to the ExternalClient project in Solution Explorer and add a service reference
for ServiceA. Provide the base address http://localhost:8000 and name the
reference ServiceA. This will generate a proxy for each contract exposed by
ServiceA and create an application configuration file with client endpoints.
Now add a service reference for ServiceB. This time, provide the base address
http://localhost:8001 and name the reference ServiceB. This will generate a proxy
for each contract exposed by ServiceB, adding new client endpoints to the application
configuration file.
The application configuration file is not overwritten when you add
new service references. A merge is performed to add to configuration
settings. SvcUtil also supports merge through command-line options.
This application will invoke each service using the proxies generated by SvcUtil.
Like with the InternalClient application, you’ll create a proxy reference for each
service contract, initialize them in the form constructor, and then close them in
the FormClosing event. The code will be simplified somewhat since the generated
proxy hides some of the complexity of creating the communication channel,
and directly exposes close functionality. The resulting code is shown in
Example 1-25.
Example 1-25. Code to initialize and close generated proxies for ServiceA and ServiceB
public partial class Form1 : Form
{
ServiceA.ServiceAClient m_proxyA;
ServiceB.ServiceBClient m_proxyB;
public Form1( )
{
InitializeComponent( );
m_proxyA = new ExternalClient.ServiceA.ServiceAClient("BasicHttpBinding_IServiceA");
m_proxyB = new ExternalClient.ServiceB.ServiceBClient("BasicHttpBinding_IServiceB");
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
this.m_proxyA.Close( );
this.m_proxyB.Close( );
}
}
You’ll notice that each proxy is initialized by passing the name of a particular
endpoint from the application configuration file. Each service exposes multiple
endpoints, but because this is an Internet client, the assumption is that the client
won’t have permissions to call the TCP nor be able to invoke services over
named pipes (named pipes requires same-machine calls). Still, add service reference
generated configuration for all endpoints because the WSDL document
includes all endpoints for a service.
Now you can add code to invoke each operation. If you look at the form in
design view, you’ll see that only three buttons are present to invoke the collective
operations of both service contracts. Create Click event handlers for each
button and add code to invoke each operation through the appropriate proxy.
Example 1-26 shows the resulting code.
Example 1-26. Code to invoke each service operation
Compile and test the external client application. First run the Host, and then run
ExternalClient. Click each button to invoke the service operations exposed by
ServiceA and ServiceB.
Let’s look at the new concepts and tools introduced in this lab.
Implementing Multiple Contracts
Designing service contracts is not as simple as just exposing existing business components
as services. In all likelihood, services will aggregate calls to many logically related
business components. This requires forethought into the use cases through each service.
Irrespective of this aggregation and design effort, it is still possible that the functionality
exposed by a single service should not be lumped into one big service contract.
Here are some cases in which multiple contracts could exist on a single service:
To separate logically related operations for different features
To separate queued operations from non-queued operations
To provide a different entry point for external and internal consumers of the service
If your service contracts are implemented on CLR interfaces (as I’ve recommended)
then implementing multiple contracts on a service is as simple as implementing multiple
interfaces. In this lab, each service implements a main service contract
(IServiceA and IServiceB, respectively) and an administrative contract (IAdmin).
Contracts can facilitate the logical separation of functionality exposed by a service.
For example, in the lab the main service contract for each service holds core business
operations for the service. The administrative contract provides a consistent set
of administrative functions that any service can expose. Both services implement the
same administrative contract, which means both services expose a consistent set of
operations, although the internal implementation may be quite different. Because of
the presumed sensitivity of administrative operations, the lab exposes these operations
over TCP or named pipes, which implies access behind the firewall. To enable
internal applications and business partners to access the core service functionality,
the main service contracts are exposed over two endpoints: one for TCP or named
pipes, the other for Internet access over HTTP.
Hosting Multiple Services
A ServiceHost instance is required for each service type in order to expose endpoints
to calling clients. When you host in IIS or WAS, a .svc endpoint is supplied for each
service type, with a @ServiceHost directive that links the .svc endpoint to the actual
service type. Thus, if you have multiple services to host in IIS, you provide a .svc for
each to support message-based activation and configure the service model section as
you would for any service type.
In self-hosting environments, you are responsible for initializing each ServiceHost
instance. You can initialize a ServiceHost for each service type as shown here (the
complete code listing is shown in Example 1-20):
ServiceHost hostA = new ServiceHost(typeof(BusinessServices.ServiceA));
ServiceHost hostB = new ServiceHost(typeof(BusinessServices.ServiceB));
hostA.Open( );
hostB.Open( );
Each ServiceHost is initialized with its own base addresses and service endpoints
according to the <service> section with the matching type (see Example 1-19). Each
ServiceHost can also be programmatically initialized using the techniques illustrated
earlier in this chapter.
Proxy Generation for Multiple Contracts and Endpoints
Adding a service reference generates the proxy and configuration settings necessary
to access a particular service. If the service implements multiple contracts, a proxy
type is generated for each contract. For example, in this lab when you add a service
reference to ServiceA in the ExternalClient project, the following proxies are generated—
one for IServiceA, another for IAdmin:
public partial class ServiceAClient :
System.ServiceModel.ClientBase<ExternalClient.ServiceA.IServiceA>,
ExternalClient.ServiceA.IServiceA
public partial class AdminClient :
System.ServiceModel.ClientBase<ExternalClient.ServiceA.IAdmin>,
ExternalClient.ServiceA.IAdmin
Likewise, when you add a service reference to ServiceB a proxy is generated for both
contracts: IServiceB and IAdmin.
In theory, because the IAdmin service contract is the same for both services,
they could share a proxy, but SvcUtil generates proxy types for all
contracts and has no knowledge of the code you have already generated.
In addition to generating proxies, SvcUtil generates the configuration necessary for each
endpoint exposed by each service. SvcUtil always provides a name for each <endpoint>
element, so you can specify the correct endpoint to use by name when constructing each
proxy. Example 1-27 shows the client endpoints generated for ServiceA and ServiceB;
the endpoints used in the lab for the ExternalClient are shown in bold.
Example 1-27. Client endpoints generated for ServiceA and ServiceB
Although the client may not have network rights to invoke the TCP or named pipe
endpoints, these endpoints are still part of the service description (WSDL) and therefore
are visible to the client.
Recall that a WSDL document is created for each service type. Thus, to prevent
remote clients from seeing internal endpoints that they should not access, you can
create different service types for internal and external use—funneling them to the
same implementation code. On external service types, you can expose endpoints
only for supported contracts over HTTP. For internal service types, you can expose
internal contracts and TCP and named pipes endpoints. To modify the lab in support
of this scenario, you might see the following service types:
public class ServiceA : IServiceA {...}
public class InternalServiceA : IServiceA, IAdmin {...}
public class ServiceB : IServiceB {...}
public class InternalServiceB : IServiceB, IAdmin {...}
In the host configuration, each service type would be defined in a separate <service>
element, exposing only the required endpoints. A compressed view of the required
<service> elements is shown here:
The following sample illustrates this scenario: <YourLearningWCFPath>\Samples\ServiceContracts\MultiContractServices_UniqueServiceTypes.
Proxy Initialization and Lifetime
Each client proxy opens a communication channel to invoke a service endpoint. The
proxy can be programmatically initialized in code or declaratively initialized per the
client’s service model configuration. If there is only one endpoint configured for a
particular service contract, there is no need to specify an endpoint configuration
name to the constructor of the channel factory or proxy.
When you use ChannelFactory<T> to create the channel from the default endpoint,
you pass empty quotes to the constructor. This example expects that only one endpoint
is configured for IServiceA:
ChannelFactory<IServiceA> factoryA = new
ChannelFactory<IServiceA>("");
m_proxyA = factoryA.CreateChannel( );
Generated proxies provide a default constructor to achieve the same result:
m_proxyA = new ExternalClient.ServiceA.ServiceAClient( );
On the other hand, when multiple endpoints exist for the same contract, you must
provide a configuration name as shown here for ChannelFactory<T> and for a generated
proxy:
ChannelFactory<BusinessServiceContracts.IServiceA> factoryA = new
ChannelFactory<BusinessServiceContracts.IServiceA>("BasicHttpBinding_IServiceA");
proxyA = factoryA.CreateChannel( );
m_proxyA = new
ExternalClient.ServiceA.ServiceAClient("BasicHttpBinding_IServiceA");
In either case, the lifetime of the communication channel is controlled by the proxy
reference. If the client application intends to invoke the service endpoint repeatedly,
it is better not to recreate the proxy each time an operation is invoked. Instead, the
proxy should be scoped to the lifetime of the application.
When the application is shutting down, you should close the proxy to speed up the
release of resources. When you are working with a channel factory to create the
proxy reference, you must cast to ICommunicationObject in order to call its Close( )
method (see Example 1-24). The equivalent inline steps would be as follows:
ICommunicationObject proxyACommunication = m_proxyA as ICommunicationObject;
...
proxyACommunication.Close( );
This step is required because the channel factory returns a reference to the service
contract, which doesn’t expose a Close( ) method. Still, the underlying object is a
CommunicationObject that implements ICommunicationObject.
Proxies generated with SvcUtil include code to wrap the inner communication
channel. In addition, each generated proxy type implements ICommunicationObject
directly, and thus provides a Close( ) method.
Be aware that the channel stack beneath the proxy reference can be
put into a faulted or invalid state. For example, if the service is no
longer available, or if the service throws an exception, or if a timeout
occurs at either end. In Chapter 8, I’ll discuss exception handling.
Another point to note is that the lifetime of the communication channel should not
be confused with the lifetime of the service instance instantiated by the host to handle
a request. In fact, a different service instance may be allocated for every call even
if the client uses the same channel. This behavior is controlled by the service. Service
instancing and throttling behaviors are covered in Chapter 5.
Sharing Service Contracts
This lab illustrates an alternate approach for sharing metadata with the client.
Instead of generating a proxy using SvcUtil, a class library containing only service
contracts is shared by the service library and the internal client application. This
approach is useful in an environment where you own both sides: client and service.
This approach can simplify steps in development, help you avoid the internal complexity
of types generated by SvcUtil, and even allow you to exercise more control
over service contract versioning on both ends.
Realistically, remote clients such as Internet clients may not be owned, which is why
the more traditional approach of sharing contracts via add service reference is used.
Duplicating Operations
This lab illustrates exposing two different contracts on each service. These contracts
each have unique operations: a set for the business functionality exposed by the service,
and a set for administrative functions. You may also want to expose a subset of
business operations for external clients while exposing the complete set of business
functionality to internal clients.
To achieve this, you could create internal and external interfaces for the service contract,
for example: IServiceA and IInternalServiceA. The external interface,
IServiceA, would in this case contain a subset of the functionality exposed by
IInternalServiceA (see Example 1-28).
Example 1-28. Internal and external service contracts with duplicate operations
If you expose each of these contracts on their own service types (ServiceA and
InternalServiceA, respectively), external clients will never see the functionality
exposed to internal clients because they work from a different WSDL document.
However, the implementation can still be the same for each service implementation.
The following sample illustrates the scenario:
<YourLearningWCFPath>\ServiceContracts\Samples\InternalExternalServiceTypes.sln.
SUMMARY
This chapter covered a lot of ground, beginning with a look at the purpose of WCF,
the problems it solves and its alignment with SOA, through discussion of the fundamentals
developers should know before they begin working with WCF. I also
touched on the overall architecture of WCF, though this is covered in greater detail
in Chapter 3. Through hands-on practice and discussion you should be comfortable
now with the following concepts:
Defining service contracts and services
Hosting services in a console application or in IIS
Exposing endpoints for a service using various standard bindings
Working with Visual Studio templates and WCF tools to improve productivity
Working with service metadata and configuring related service behaviors
Generating proxies to invoke services
Of course, the next step is to start diving into the details of service contracts, bindings,
and hosting. In addition, you’ll need to learn more about service behaviors and
messaging protocols that handle instancing, throttling, reliability, security and
exception handling.
Since service contracts are central to defining the messages exchanged between clients
and services, the next chapter will focus on this subject. In Chapter 2, I’ll
explain how to approach service contract design, how to work with complex types
and how to control serialization on many levels. In the process of reading Chapter 2,
you’ll further solidify your knowledge of the fundamental concepts touched on in
this chapter.
WinConnections Conference Fall 2008 Don’t miss the premier event for Microsoft IT Professionals in Las Vegas, November 10-13. Register and book your room by August 25 and receive a FREE room night (based on a three night minimum stay).
Master SharePoint with 3 eLearning Seminars Learn how to build a better SharePoint infrastructure and enable powerful collaboration with MVPs Dan Holme and Michael Noel. Register today!
SharePointConnections Conference Fall 2008 Don’t miss the premier event for Microsoft IT Professionals in Las Vegas, November 10-13. Register and book your room by August 25 and receive a FREE room night (based on a three night minimum stay).
VMworld 2008 - Sign Up Today! Join your peers on September 15-18 at The Venetian Hotel in Las Vegas as VMware hosts VMworld 2008, the leading Virtualization event.
Microsoft® Tech•Ed EMEA 2008 IT Professionals Advance your thinking with new ideas and practical real-world solutions at Microsoft’s FIVE day technical infrastructure conference 3-7 Nov., 2008. Register before 26 September 2008 to save €300.
Order Your Fundamentals CD Today! Gain an introduction to Exchange, learn server security requirements, and understand how unified communications can play a role in your messaging strategies with this free Exchange CD.
Are You Really Compliant with Software Regulations? View this web seminar that will help you with compliance best practices and check out a management solution to assure that you won’t be in jeopardy of an audit.
Virtualization Congress Oct. 14-16 in London Don't miss Virtualization Congress, the premiere EMEA conference dedicated to hardware, OS and application virtualization. Oct. 14-16 in London.