COM+ Integration: COM+ Hosted

Download sample

This sample demonstrates how to expose an interface from a COM+ application as a Windows Communication Foundation (WCF) service and how to call this from a WCF client. This sample consists of a client console program (.exe) and an Enterprise Services library application (.dll) registered within COM+. The sample is based on the Getting Started Sample sample that implements a calculator service and is similar to the COM+ Integration: Web Hosted sample. By using COM+ hosting and the TCP transport, this sample demonstrates an approach with better performance than that in the COM+ Integration: Web Hosted sample but does require the COM+ application to be explicitly activated before it can process requests.

NoteNote:

The setup procedure and build instructions for this sample are located at the end of this topic.

The Enterprise Services application contains a single component that implements a single ICalculator interface that exposes math methods (Add, Subtract, Multiply, and Divide).

// Define the component's interface.
public interface ICalculator
{
    double Add(double n1, double n2);
    double Subtract(double n1, double n2);
    double Multiply(double n1, double n2);
    double Divide(double n1, double n2);
}

This interface is exposed as a service contract that defines a request-reply communication pattern. The client makes synchronous requests to a math operation and the service and underlying component replies with the result. Client activity is visible in the console window.

The service is hosted in-process with COM+ and the application ServiceModelHostedSample must be manually started to activate the service endpoints. The ESCalculatorService class implementation calculates and returns the appropriate result.

// Supporting implementation for the ICalculator interface.
public class ESCalculatorService : ServicedComponent, ICalculator
{
    public double Add(double n1, double n2)
    {
        return n1 + n2;
    }
    public double Subtract(double n1, double n2)
    {
        return n1 - n2;
    }
    public double Multiply(double n1, double n2)
    {
        return n1 * n2;
    }
    public double Divide(double n1, double n2)
    {
        return n1 / n2;
    }
}
NoteNote:

The class does not include any ServiceModel-specific code and is a typical Enterprise Services assembly that is attributed with Enterprise Services attributes, which is signed and added to the Global Assembly Cache (GAC).

The COM+ Service Model Configuration Tool (ComSvcConfig.exe) is used to add a supporting service for the selected interface. The following code is used to perform this:

ComSvcConfig.exe /install /application:ServiceModelHostedSample /contract:"ServiceModelHostedSample.ESCalculator,ICalculator" /hosting:complus /mex /verbose

In this case, the tool adds a service for the ICalculator interface of the ServiceModelHostedSample.ESCalculator component, which is within the ServiceModelHostedSample application. The service is hosted within COM+, with a Metadata Exchange endpoint. A ServiceModelInitializer component is added the application to facilitate the integration and an application configuration file is generated in the COM+ application's application root directory - for this application, it is "%PROGRAMFILES%\ComPlus Applications\{4cdcdb2c-0b19-4534-95cd-fbbff4d67dd9}\". On application startup, the ServiceModelInitializer component checks the application configuration file and starts the appropriately configured service endpoints.

For COM+ hosted services, the COM+ Service Model Configuration Tool (ComSvcConfig.exe) tool creates service endpoints using the netNamedPipeBinding which only provides for same machine access. The configuration file must be further edited to provide endpoints on other transports. This sample uses a custom configuration file that exposes the application on TCP and HTTP by use of the netTcpBinding and wsHttpBinding bindings:

<!-- Specify the service (application and component GUIDs) and service and MEX endpoints -->
<services>
  <service behaviorConfiguration="ComServiceMexBehavior"
           name="{4CDCDB2C-0B19-4534-95CD-FBBFF4D67DD9},{C2B84940-AD54-4A44-B5F7-928130980AB9}">
    <endpoint
           address="ICalculator"
           binding="netTcpBinding"
           bindingConfiguration="comNonTransactionalBinding"
           contract="{8803CCEC-4DFB-49a7-925B-60025C32E5CD}" />
    <endpoint
           address="ICalculator"
           binding="wsHttpBinding"
           bindingConfiguration="comNonTransactionalBinding"
           contract="{8803CCEC-4DFB-49a7-925B-60025C32E5CD}" />
    <endpoint
           address="mex"
           binding="mexHttpBinding"
           contract="IMetadataExchange" />
    <host>
      <!-- Specify base addresses for both transports -->
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8081/ServiceModelHostedSample" />
        <add baseAddress="https://localhost:8082/ServiceModelHostedSample" />
      </baseAddresses>
    </host>
  </service>
</services>

In this sample, the configuration file also customizes the name and namespace for the service and can be used to expose only a subset of the operations offered by the component. In this case, the Divide method has been commented out and is omitted from the exposed service contract:

<!-- comContract specifying the name, namespace and methods for the service -->
<comContracts>
  <comContract
      contract="{8803CCEC-4DFB-49a7-925B-60025C32E5CD}"
      name="ICalculator"
      namespace="https://microsoft.com/Microsoft.ServiceModel.Samples/EnterpriseServicesHosted"
      requiresSession="true">
    <exposedMethods>
      <add exposedMethod="Add" />
      <add exposedMethod="Subtract" />
      <add exposedMethod="Multiply" />
      <!-- <add exposedMethod="Divide" /> -->
    </exposedMethods>
  </comContract>
</comContracts>

The client communicates on a contract using a client that is generated by the Service Metadata Utility Tool (Svcutil.exe). The client is contained in the generatedClient.cs file with a compatible configuration in App.config. This utility retrieves metadata for a service and generates a client used to communicate on a contract type. The hosted service must be available to generate the client code, because it is used to retrieve the service metadata. Run the following command from a command prompt in the client directory to generate the typed proxy:

svcutil.exe /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples https://localhost:8082/ServiceModelHostedSample/mex /out:generatedClient.cs /config:App.config

The client implementation constructs an instance of the generated client using the TCP binding configuration. It can then be used to begin communicating with the service.

// Create a client.
CalculatorClient client = new CalculatorClient("NetTcpBinding_ICalculator ");
WSHttpBinding_ICalculator
// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

// Call the Subtract service operation.
value1 = 145.00D;
value2 = 76.54D;
result = client.Subtract(value1, value2);
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

// Call the Multiply service operation.
value1 = 9.00D;
value2 = 81.25D;
result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

//Closing the client gracefully closes the connection and cleans up resources.
client.Close();

When you run the sample, the operation requests and responses are displayed in the client console window. This demonstrates the use of the generated WCF service from a WCF client. Press ENTER in the client window to shut down the client.

Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25

Press <ENTER> to terminate client.

To set up and build the sample

  1. Ensure that you have performed the One-Time Setup Procedure for the Windows Communication Foundation Samples.

  2. To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building the Windows Communication Foundation Samples. The build process includes executing a script that creates the COM+ application and marks it "Leave running when idle" - this prevents the service endpoint from automatically being shut down due to inactivity.

  3. From a command prompt, navigate to the sample's service\bin folder.

  4. Enter gacutil.exe /i ESCalculatorHosted.dll to add the assembly to the Global Assembly Cache (GAC). Make sure Gacutil.exe is in your path.

  5. Enter regsvcs.exe ESCalculatorHosted.dll to register the assembly's component and the ServiceModelSample application with COM+. Make sure Regsvcs.exe is in your path.

  6. Enter ComSvcConfig.exe /install /application:ServiceModelHostedSample /contract:"ServiceModelHostedSample.ESCalculator,ICalculator" /hosting:complus /mex /verbose to expose the interface as an Internet Information Services (IIS)-hosted service. Make sure ComSvcConfig.exe is in your path.

  7. To replace the default configuration with this sample's custom configuration, copy the file Service/application.config to the directory %ProgramFiles%\ComPlus Applications\{4cdcdb2c-0b19-4534-95cd-fbbff4d67dd9}\.

To run the sample on the same machine

  1. To start the application and the endpoints, using the Component Services management console, right-click the ServiceModelHostedSample and select Start.

  2. Test that you can access the services using a browser by entering the following address: https://localhost:8082/ServiceModelHostedSample. A confirmation page should be displayed in response.

  3. Run Client.exe from \client\bin\, from under the language-specific folder. Client activity is displayed on the client console window.

  4. If the client and service are not able to communicate, see Troubleshooting Tips.

    NoteNote:

    The sample builds a console application client program. You must launch it using a command prompt to see its output.

To run the sample across machines

  1. Copy the file ESCalculatorHosted.dll from the service\bin directory and the file CreateAppLeaveRunning.vbs from the service directory to a directory on the service machine.

  2. From a command prompt, navigate to that destination directory on the service machine.

  3. Execute the script CreateAppLeaveRunning.vbs to create the COM+ application with the "Leave running when idle" setting.

  4. Enter gacutil.exe /i ESCalculatorHosted.dll to add the assembly to the Global Assembly Cache (GAC). Make sure Gacutil.exe is in your path.

  5. Enter regsvcs.exe ESCalculatorHosted.dll to register the assembly's component and the ServiceModelSample application with COM+. Make sure Regsvcs.exe is in your path.

  6. Enter ComSvcConfig.exe /install /application:ServiceModelHostedSample /contract:"ServiceModelHostedSample.ESCalculator,ICalculator" /hosting:complus /mex /verbose to expose the interface as an IIS-hosted service. Make sure ComSvcConfig.exe is in your path.

  7. To replace the default configuration with this sample's custom configuration, copy the file Service/application.config to the directory %ProgramFiles%\ComPlus Applications\{4cdcdb2c-0b19-4534-95cd-fbbff4d67dd9}\.

  8. In the service application configuration file, change the address value of the endpoint definition to match the new address of your service. Replace any references to "localhost" with a fully-qualified domain name in the address.

  9. To start the application and the endpoints, using the Component Services management console, right-click the ServiceModelHostedSample and select Start.

  10. Copy the client program files from the \client\bin\ folder, under the language-specific folder, to the client machine.

  11. If the service is not running under a domain account, open the client configuration file and change the address value of the endpoint definition to match the new address of your service. Replace any references to "localhost" with a fully-qualified domain name in the address. If the service is running under a domain account, regenerate the client configuration by running Svcutil.exe against the service. Use the generated file instead of the configuration file in the sample. The generated configuration file has additional identity information (and contains all settings necessary to connect to the service endpoint even though they are the default settings).

  12. Test that you can access the service from the client machine using a browser.

  13. On the client machine, launch Client.exe from a command prompt.

To clean up after the sample

  • For security purposes, remove the ESCalculatorHosted component from the Global Assembly Cache, delete the ServiceModelHostedSample COM+ application, and remove the application root directory %PROGRAMFILES%\ComPlus Applications\{4cdcdb2c-0b19-4534-95cd-fbbff4d67dd9}\ when you are finished with the sample.

Footer image

Send comments about this topic to Microsoft.
© Microsoft Corporation. All rights reserved.