- One publisher, 1+ Subscribers
- One separate queue for each sub
- Each sub gets same message
We are going to use the publisher/ subscriber pattern. install RabbitMQ.Client
Some terms:
- Connection
- Channel
- Message
- BasicPublish
- Exchanges
- Bindings
Prepare
- Create two queues
- Bind the queues to the fanout exchange
Create the publisher app
- Add connection
- Create channel
- Create a fanout exchange
- Create queues
- Create message
- Publish message
- Close channel and connection (use using)
Create the subscriber app
- Add connection
- Create channel
- Bind queues to the exchange
- Create consumer
- Receive message
- Subscribe to the queue
- Close channel and connection (use using)
Programming RabbitMQ in C# RabbitMQ Exchanges in C# Publish/Subscribe Fanout Exchange in AMQP – RabbitMQ (Publish/Subscribe)
Promote separation of concern and maintanability.
- At the centre of the diagram
- Orchestrates interactions between the different layers of the application
- Agnostic about delivery mechanism, DB, external components
- Focuses on business logic
- Command/ Queries
- App specific use-cases
- Bridge between presentation layer and domain layer (outer and inner)
- Includes tasks such as validation, authentication and authorisation
- Defines entities, value objects, business rules that represent core concepts and logic of the app
- Isolated from database or UI
- Data Repositories, Database access, data storage
- Interaction with external services such as DBs
In our case the user interacts with API directly.
To map our DTO to our domain objects we are going to use AutoMapper What is AutoMapper? Create Data Transfer Objects (DTOs)
- Dependency Injection AutoMappper DotNet 6 API Project
#1 Use the IMapper mapper in the constructor #2 Install AutoMapper Dependency Injection package #3 Create Mapping Profile #4 in Program add builder.Services.AddAutoMapper(typeof(MappingProfile));
Error: System.InvalidOperationException: Unable to resolve service for type 'AutoMapper.IMapper' while attempting to activate 'ControllerBanking.Controllers.BankingController'.
Solution: Make sure the dto is well mapped to the domain object by doing
public ProductDto MapProductToDto(Product product)
{
return _mapper.Map<ProductDto>(product);
}
Our app will be using the CQRS pattern where commands and queries are split CQRS pattern
Error: System.InvalidOperationException: No service for type 'MediatR.IRequestHandler`1[Application.Commands.MoneyTransferCommand]' has been registered.
Solution:
- MediatR Dependency Injection
Errors System.InvalidOperationException: No service for type 'MediatR.IRequestHandler`1[ControllerBanking.DTOs.MoneyTransferCommandDto]' has been registered.
Solution
Errors
No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.). For detailed output, run func with --verbose flag.
Solution
We are using Data transfer object DTOs (Data transfer objects) to safely separate data from client to data layer. Our controllers will therefore return contracts (here DTOs by lack of presentation layer). Domain objects will be used to interact with RabbitMQ
Create Data Transfer Objects (DTOs)
- runs on port 15672: http://localhost:15672/
- Connection tab: appears when app running, can see connection created
- PW: guest, UserName: guest