Oracle¶
To use Oracle
database integration, the NuGet package CrystalSharp.Oracle
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:
- Inject the
IOracleEntityFrameworkCoreContext
interface into theDbContext
constructor. - Override the method
public virtual Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
of theDbContext
class. - Call the
SaveChanges
method of theIOracleEntityFrameworkCoreContext
interface. - Register the implementation of
DbContext
.
Following is the code that illustrates how to perform the above steps:
public class AppDbContext : DbContext
{
private readonly IOracleEntityFrameworkCoreContext _oracleEfContext;
public DbSet<Order> Order { get; set; }
public AppDbContext()
{
//
}
public AppDbContext(DbContextOptions<AppDbContext> options, IOracleEntityFrameworkCoreContext oracleEfContext)
: base(options)
{
_oracleEfContext = oracleEfContext;
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
return await _oracleEfContext.SaveChanges(this, cancellationToken).ConfigureAwait(false);
}
}
In the above code snippet, the AppDbContext
class overrides the SaveChangesAsync
method of the DbContext
class. Overriding the SaveChangesAsync
method is a mandatory requirement. The constructor injects the IOracleEntityFrameworkCoreContext
interface, which is necessary for saving changes in the database. Within the overridden SaveChangesAsync
method, pay attention to the utilization of the await _oracleEfContext.SaveChanges(this, cancellationToken)
method. This method executes all the essential operations prior to saving and ultimately persists the data in the database.
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 DbContext
implementation is required. Following is the code that illustrates how to register AppDbContext
in the Program.cs
file:
OracleSettings oracleSettings = new("CONNECTION-STRING", "VERSION");
CrystalSharpAdapter.New(builder.Services)
.AddCqrs(typeof(PlaceOrderCommandHandler))
.AddOracle<AppDbContext>(oracleSettings)
.CreateResolver();
In the above code snippet, when initializing the Crystal Sharp framework, the OracleSettings
class is instantiated with a connection string and then a call to an extension method AddOracle<AppDbContext>(oracleSettings)
for the DbContext
registration.
In order to save the data, call the overridden method SaveChangesAsync
. Following is the code that illustrates the saving of data:
public class PlaceOrderCommandHandler : CommandHandler<PlaceOrderCommand, PlaceOrderResponse>
{
private readonly AppDbContext _dbContext;
public PlaceOrderCommandHandler(AppDbContext dbContext)
{
_dbContext = dbContext;
}
public override async Task<CommandExecutionResult<PlaceOrderResponse>> Handle(PlaceOrderCommand request, CancellationToken cancellationToken = default)
{
Order order = Order.PlaceOrder(request.OrderCode, request.TotalPrice);
await _dbContext.Order.AddAsync(order, cancellationToken).ConfigureAwait(false);
await _dbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
PlaceOrderResponse response = new() { OrderId = order.GlobalUId };
return await Ok(response);
}
}
In the above code snippet, AppDbContext
is injected into the command handler constructor, and then in the Handle
method of the command handler, a new order is created and saved. Here, notice the await _dbContext.SaveChangesAsync(cancellationToken)
method; it is the same SaveChangesAsync
of the DbContext
class, which is overridden in the AppDbContext
class.