I've been added to an project under development. It's an ASP.Net MVC 5 application using Mediatr and the CQRS pattern(with a read-only database and a write only database - eventually consistent). The application has an admin piece that has a lot of CRUD operations and we're running into problems. For example, let's say there's a Widget Controller:
public class WidgetController : Controller
{
private readonly IMediator _mediator;
public WidgetController(IMediator mediator)
{
_mediator = mediator;
}
// GET: Widget
public ActionResult Index()
{
// Reads from the read-only database and may not have synced
// This call is not guaranteed to have the newly added or edited widget (and usually doesn't)
var allWidgets = _mediator.Send(new GetAllWidgets());
return View(allWidgets);
}
[HttpPost]
public ActionResult Create(Widget widget)
{
try
{
// This call contains the database logic to write into the write only database
_mediator.Send(new CreateWidget(widget));
return RedirectToAction("Index");
}
catch
{
return View();
}
}
[HttpPost]
public ActionResult Edit(Widget updatedWidget)
{
try
{
// Writes to the write-only database
_mediator.Send(new UpdateWidget(updatedWidget));
return RedirectToAction("Index");
}
catch
{
return View();
}
}
}
In the Create and Edit actions, a Widget is either created or edited and those changes are made to the write-only database. This is followed by an immediate redirect to the Index Action, which reads from the read-only database. The changes are generally not synced from the write-only database by the time this call completes and the view is rendered. To work around this issue, we've used Redis to cache the newly created or updated object and then if the list retrieved in the Index action doesn't contain the new or edited object, we retrieve it from the cache. This feels really, really wrong.
Since none of us on the project have ever been involved in a CQRS project, we don't know how to rectify this issue. It feels like we're really missing something with this pattern.
So, I guess what I'm asking is this...is there a best practice to handle this type of scenario? Is there a better way to do this?