RavenDB¶
To use RavenDB
database integration, the NuGet package CrystalSharp.RavenDb
must be installed.
IMPORTANT
Kindly keep in mind that this particular configuration is intended for the purpose of storing data in the database and reading the data from the database. However, the configuration procedures for the Event Store, Read Model Store, and Sagas will be approached differently.
In order to integrate a database effectively, it is necessary to adhere to the following mandatory steps:
- An aggregate must be inherited from
AggregateRoot<string>
. It is mandatory that the<string>
type be passed to the base class. - Register the implementation of
RavenDB
. - Use
IRavenDbContext
for database operations.
Following is the code that illustrates how to perform the above steps:
public class Order : AggregateRoot<string>
{
public string OrderCode { get; private set; }
public decimal TotalPrice { get; private set; }
// Rest of the code and logic
}
In the above code snippet, Order
aggregate is inherited to AggregateRoot<string>
. Here, the Id
is of type string, which is why <string>
is passed to the base class. It is mandatory to use string
for the Id
, as the Crystal Sharp framework specifically uses the string
type for the Id
in RavenDB
.
NOTE
If there are any domain event handlers, then those domain event handlers will be triggered only after the data has been successfully stored in the database.
Registration for the RavenDB
is required. Following is the code that illustrates how to register RavenDB
in the Program.cs
file:
RavenDbSettings ravenDbSettings = new("CONNECTION-STRING", "DATABASE-NAME");
CrystalSharpAdapter.New(builder.Services)
.AddCqrs(typeof(PlaceOrderCommandHandler))
.AddRavenDb(ravenDbSettings)
.CreateResolver();
In the above code snippet, when initializing the Crystal Sharp framework, the RavenDbSettings
class is instantiated with a connection string and the database name, and then a call to an extension method is made AddRavenDb(ravenDbSettings)
.
IMPORTANT
It is mandatory to use “IRavenDbContext” for performing database operations.
IRavenDbContext
provides the following methods and properties:
IDocumentStore DocumentStore { get; } |
IDocumentSession Session { get; } |
Task SaveChanges(CancellationToken cancellationToken = default) |
IDocumentStore
and IDocumentSession
are the interfaces of the RavenDB.Client
, which is the official NuGet package from RavenDB
. The Crystal Sharp framework internally uses the RavenDB.Client
package. For loading and querying an entity, the Session
property of IRavenDbContext
must be utilized.
IMPORTANT
It is important to note that when saving the data in the database, the “SaveChanges” method of “IRavenDbContext” must be used.
Following is the code that illustrates the saving of data:
public class PlaceOrderCommandHandler : CommandHandler<PlaceOrderCommand, PlaceOrderResponse>
{
private readonly IRavenDbContext _dbContext;
public PlaceOrderCommandHandler(IRavenDbContext dbContext)
{
_dbContext = dbContext;
}
public override async Task<CommandExecutionResult<PlaceOrderResponse>> Handle(PlaceOrderCommand request, CancellationToken cancellationToken = default)
{
Order order = Order.PlaceOrder(request.OrderCode, request.TotalPrice);
_dbContext.Session.Store(order);
await _dbContext.SaveChanges(cancellationToken).ConfigureAwait(false);
PlaceOrderResponse response = new() { OrderId = order.GlobalUId };
return await Ok(response);
}
}
In the above code snippet, IRavenDbContext
is injected into the command handler constructor, and then in the Handle
method of the command handler, a new order is created and saved.