It is possible to expose the message send+receive action as a WCF service. In effect, this allows a WCF service call to be "proxied" through to a message being sent, and then wait for the response to return the WCF result.
Prerequisites for WCF functionality
The WCF functionality is part of the NServiceBus.Host NuGet package.
Expose a WCF service
To expose the endpoint as a WCF service, inherit from NServiceBus.
, as shown below. TRequest
is the message type of the request. TResponse
represents the result of processing the command and can be any type that is supported by the NServiceBus.
package.
Example:
public class CancelOrderService :
WcfService<CancelOrder, ErrorCodes>
{
}
public class CancelOrderHandler :
IHandleMessages<CancelOrder>
{
IBus bus;
public CancelOrderHandler(IBus bus)
{
this.bus = bus;
}
public void Handle(CancelOrder message)
{
// code to handle the message
// return a status so that the WCF service has a return value
bus.Return(ErrorCodes.Success);
}
}
public enum ErrorCodes
{
Success,
Fail
}
public class CancelOrder :
ICommand
{
public int OrderId { get; set; }
}
TResponse
must be an enumerated type. To reply with enumeration types, the replying endpoint needs to reference NServiceBus.Callback
and configure it accordingly.Configure binding and address of WCF service
To expose the WCF service, change the configuration as shown below:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Server.WebServices.CancelOrderService"
behaviorConfiguration="Default">
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:9009/services/cancelOrder" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
The service name in
must match the Type.
that derives from NServiceBus.
.
Queries and other return values
To allow clients to perform queries, it is best not to use NServiceBus. Messaging is designed for non-blocking operations and queries are operations for which the user usually must wait.
When performing operations that aren't as straightforward as a simple query to return a value, for example a long calculation, consider invoking the operation locally where possible by referencing the DLL on the client.
Calling Web/WCF services
When invoking a Web/WCF service as a part of message handling logic, where that logic also updates transactional resources like a database, the best practice is to split it into two endpoints.
If no response is required from the Web/WCF service then use publish-subscribe. Have the first endpoint publish an event, to which the second endpoint subscribes, and have the second endpoint call the Web/WCF service.
If a response is required from the Web/WCF service, turn the first endpoint into a saga that sends (not publishes) a message to the second endpoint, which calls the Web/WCF service and replies with a response that is handled by the saga in the first endpoint.