W poprzednim w poście było dość teoretycznie, ale o to mi chodziło. Nie chciałem tworzyć wszystkich wpisów wyłącznie o API. Dzisiaj z kolei będzie już prosty przykład, na którym później będziemy testować to co zostało opisane w pierwszym poście.
Zacznijmy od zdefiniowania wiadomości, którą chcemy wysyłać. Zwykle tworzy się osobny projekt dla nich. Stwórzmy więc projekt Contracts i zainstalujmy nServicebBus:
Nasza wiadomość będzie nazywać się AddPerson:
public class AddPerson:IMessage { public string FirstName { get; set; } public string LastName { get; set; } }
Proszę zauważyć, że implementujemy IMessage. W praktyce korzysta się jeszcze z ICommand oraz IEvent, ale o tym kiedy indziej – w tym poście chce pokazać najprostszy przykład.
Powyższą klasę dodaliśmy do osobnego projektu Contracts, który będzie współdzielony zarówno przez serwer jak i klient.
Następnie możemy dodać projekt dla backend oraz zainstalować nServiceBus.Host:
Pakiet stworzy automatycznie klasę do konfiguracji hosta:
using NServiceBus; /* This class configures this endpoint as a Server. More information about how to configure the NServiceBus host can be found here: http://particular.net/articles/the-nservicebus-host */ public class EndpointConfig : IConfigureThisEndpoint, AsA_Server { public void Customize(BusConfiguration configuration) { configuration.UsePersistence<PLEASE_SELECT_ONE>(); } }
Jak widać musimy wybrać persistance model. Dla tego wpisu nie ma to większego znaczenia, ale będziemy posługiwać się bazą RavenDB. Oznacza to, że musimy zainstalować kolejny pakiet:
Konfiguracja zatem powinna wyglądać tak:
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server { public void Customize(BusConfiguration configuration) { configuration.UsePersistence<RavenDBPersistence>(); } }
Oczywiście sami musimy zainstalować sobie bazę RavenDB. Na razie proszę nie martwić się o to, co będzie tam przechowywane (o tym innym razem).
Jeśli będzie nam brakować jakiś komponentów warto zainstalować skrypty PowerShell (z konsoli NuGet):
PM> Install-Package NServiceBus.PowerShell PM> Import-Module .\packages\NServiceBus.PowerShell.4.3.0\lib\net40\NServiceBus.PowerShell.dll
Na przykład, aby skonfigurować performance counter, wystarczy:
PM> Install-NServiceBusPerformanceCounters
Pozostało nam dodać handler, który obsłuży wiadomość AddPerson:
class AddPersonHandler:IHandleMessages<AddPerson> { public void Handle(AddPerson message) { Console.WriteLine("Dodawanie osoby: {0} {1}",message.FirstName,message.LastName); } }
Kolejnym projektem będzie klient. Dla uproszczenia może być to aplikacja konsolowa.
Najpierw musimy stworzyć szynę danych po której będziemy wysyłać komendy i zdarzenia:
var busConfiguration = new BusConfiguration(); busConfiguration.UsePersistence<RavenDBPersistence>(); ISendOnlyBus bus = Bus.CreateSendOnly(busConfiguration);
Wysłanie wiadomości wygląda następująco:
while (true) { string firstName = Console.ReadLine(); string lastName = Console.ReadLine(); bus.Send(new AddPerson() {FirstName = firstName, LastName = lastName}); }
Powyższa próba wysłania wiadomości zostanie zakończona wyjątkiem:
Additional information: No destination could be found for message type Example.Contracts.AddPerson. Check the <MessageEndpointMappings> section of the configuration of this endpoint for an entry either for this specific message type or for its assembly.
Po prostu musimy zdefiniować, gdzie chcemy wysłać wiadomość. Domyślnie nazwa serwera to assembly name. Jeśli zatem, stworzyliśmy handler i serwer w Example.Backend to wystarczy:
bus.Send("Example.Backend@localhost",new AddPerson() {FirstName = firstName, LastName = lastName});
Oczywiście jest to mało eleganckie podejście. Lepiej jakbyśmy użyli pliku konfiguracyjnego. NuGet wygenerował już nam trochę wskazówek w config:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" /> </configSections> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <UnicastBusConfig> <MessageEndpointMappings> <add Assembly="Example.Contracts" Endpoint="Example.Backend@localhost" /> </MessageEndpointMappings> </UnicastBusConfig> </configuration>
Plik konfiguracyjny daje nam dużą swobodę. Możemy określić cały assembly, namespace, albo wyłącznie konkretny typ. Jak widać stanowi to po prostu mapowanie między typem wiadomości a endpoint’em. W przykładzie zaprezentowanym wszystkie wiadomości zdefiniowane w Example.Contracts będą wysyłane do Example.Backend.
Po uruchomieniu przykładu i wpisaniu imienia oraz nazwiska, wiadomość zostanie wysłana do serwera z uwzględnieniem systemu kolejek, o których pisałem parę dni temu.
W kolejnym wpisie przejrzymy dokładnie się, jak wiadomość wędruje między klientem a serwerem oraz co stanie się, gdy w międzyczasie padnie serwer.
Czy mógłbyć podzielić się kodem? Dodać paczkę albo githuba?
Konfiguracja klienta niezgodna z wersja 7 nServiceBus
na 5 działa