Reputation: 3677
I am trying to hook up a primitive TestService
endpoint to a primitive WCF service, where the WCF service instance sends a primitive TestCommand
to the TestService
endpoint, using latest NSB 5.2.9/Host6.0:
[ServiceBehavior(
InstanceContextMode = InstanceContextMode.PerCall,
ConcurrencyMode = ConcurrencyMode.Single )]
public class MyService : IMyService
{
private readonly IBus bus;
public MyService( IBus bus )
{
this.bus = bus;
}
public void Test( string value )
{
bus.Send( new TestCommand( value ) );
}
}
I am unable to configure this correctly. Error message:
Exception thrown: 'System.InvalidOperationException' in System.ServiceModel.dll
Additional information: No destination could be found for message type Company.App.Commands.TestCommand. Check the <**MessageEndpointMappings**> section of the configuration of this endpoint for an entry either for this specific message type or for its assembly.
I am able to do this without using the "unobtrusive node", but not with conventions. I am very confused as to how to configure this after I tried everything. The WCF Host is self hosted, while the Test endpoint is hosted by NServiceBus.Host.
Right now I have this in the web.config, which is seemignly useless and ignored:
<MessageEndpointMappings>
<add Assembly="Company.App.Messages" Type="Company.App.Commands.TestCommand" Endpoint="testservice" />
</MessageEndpointMappings>
"Unobtrusive mode": I have created a separate project for conventions, which is referenced by the WCF host endpoint and the TestService endpoint.
public class MessageConventions : INeedInitialization
{
public void Customize( BusConfiguration configuration )
{
var conventions = configuration.Conventions();
conventions.DefiningCommandsAs( t => t.Namespace != null && t.Namespace.StartsWith( "Company.App" ) && t.Namespace.EndsWith( "Commands" ) );
conventions.DefiningEventsAs( t => t.Namespace != null && t.Namespace.StartsWith( "Company.App" ) && t.Namespace.EndsWith( "Events" ) );
conventions.DefiningMessagesAs( t => t.Namespace != null && t.Namespace.StartsWith( "Company.App" ) );
//conventions.DefiningTimeToBeReceivedAs( t => GetTimeToBeReceived( t ) )
//conventions.DefiningDataBusPropertiesAs( pi => IsDataBusProperty( pi ) );
}
}
These conventions are seemingly picked up by TestService
.
My understanding is that the IIS WCF Host must declare the mappings in its web.config, so that the WCF service knows where to send the messages with bus.Send(new TestCommand("test"));
but this does not work.
Then I tried defining these mappings in both endpoints, but no luck.
This method will output all message types that where found using the conventions above:
public class Startup : IWantToRunWhenBusStartsAndStops
{
public MessageMetadataRegistry Messages { get; set; }
public Conventions Conventions { get; set; }
public void Start()
{
var getAllMessagesMethod = typeof( MessageMetadataRegistry ).GetMethod( "GetAllMessages",
BindingFlags.NonPublic | BindingFlags.Instance );
var allMessages = getAllMessagesMethod.Invoke( Messages, new object[ 0 ] ) as IEnumerable<MessageMetadata>;
foreach ( var metadata in allMessages )
{
Type type = metadata.MessageType;
string name = type.FullName;
if ( this.Conventions.IsInSystemConventionList( type ) )
Console.WriteLine( "System Msg: {0}", name );
else if ( this.Conventions.IsCommandType( type ) )
Console.WriteLine( " Command: {0}", name );
else if ( this.Conventions.IsEventType( type ) )
Console.WriteLine( " Event: {0}", name );
else if ( this.Conventions.IsMessageType( type ) )
Console.WriteLine( " Message: {0}", name );
if ( metadata.TimeToBeReceived != TimeSpan.MaxValue )
Console.WriteLine( " TimeToBeReceived={0}", metadata.TimeToBeReceived );
}
}
public void Stop()
{
}
}
Above method outputs the message type "TestCommand", so it knows about the conventions made.
I already checked 1000x for typos, casing, everyhting. I cleaned the solution. My question is: why can't NServiceBus find the endpoint?
Please help.
Upvotes: 3
Views: 2219
Reputation: 16393
Unobtrusive means that you tell NServiceBus which classes are command and events by conventions rather than implementing the marker interfaces, you still need to add a message mapping in the app/web config so that NServiceBus knows which queue to send the message to.
The exception is suggesting that is your problem
Check the <**MessageEndpointMappings**> section of the configuration of this endpoint for an entry either for this specific message type or for its assembly.
Make sure you still have something like this in your web.config:
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="Company.App.Commands.TestCommand, Company.App.Commands" Endpoint="test.server" />
</MessageEndpointMappings>
</UnicastBusConfig>
EDIT
Now that you have posted your web.config, the problem looks like you have the wrong type name in the web.config:
<add Assembly="Company.App.Messages" Type="Company.App.Commands.RunTestCommand"
but you're doing this bus.Send(new TestCommand(value));
So the web.config is wrong, it should be
<add Assembly="Company.App.Messages" Type="Company.App.Commands.TestCommand"
Upvotes: 1