Reputation: 1
I have an Angular app based on ASP.NET MVC application and there is a Dashboard where I display some of the Average and Total numbers that are changed in Create / Update / Delete events. Normally these events are implemented in the Controller as shown below:
Controller.cs:
[HttpPost]
public JsonResult Create(Record record)
{
// code omitted for brevity
return Json(new { Data = data, success = true }, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public JsonResult Update(Record record)
{
// code omitted for brevity
return Json(new { Data = data, success = true }, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public JsonResult Delete(int id)
{
// code omitted for brevity
return Json(new { Data = data, success = true }, JsonRequestBehavior.AllowGet);
}
However, after each of execution of these methods, I need to call the corresponding Hub methods in order to update the numbers on the Dashboard page.
Hub.cs:
public class NotificationHub : Hub
{
public void Update(Record record)
{
Clients.All.updateStatisticsToPage(record);
}
}
So, my questions are:
1) How can I combine these methods in order to update numbers on Dashboard page? Should I move the CRUD methods to the Hub and use only this methods like that? I added the last line in order to notify clients about the current statistics data.
[HttpPost]
public JsonResult Create(Record record)
{
// code omitted for brevity
return Json(new { Data = data, success = true }, JsonRequestBehavior.AllowGet);
// send update to all clients
Clients.All.updateStatisticsToPage(record);
}
Or should I keep the method in the Controller method and call hub method after the crud operation is executed?
2) As I update the statistics on the Dashboard page after a crud event, I think I build the structure different from chat app. Because I only send notification to the Dashboard component after crud event. Is that true?
Upvotes: 2
Views: 1850
Reputation: 162
On the other hand, is there another smart solution without using CQRS instead of moving the CRUD methods to the Hub? Because as the the Hub class does not contain some methods that Controller class has, it would be better to continue to use the same method (Create Update Delete) in the Controller by adding Clients.All.updateStatisticsToPage(record); line after the operation is executed. Is it possible and could you please post an example?
I didn't use it this in that way but I think it is possible. You could try to create StatisticsHub with IStatisticsHub interface:
public interface IStatisticsHub
{
Task Send(string message);
}
public class StatisticHub : Microsoft.AspNetCore.SignalR.Hub, IStatisticsHub
{
private readonly IHubContext<StatisticHub > _context;
public StatisticHub(IHubContext<EventTypeHub> context)
{
_context = context;
}
public async Task Send(string message)
{
await _context.Clients.All.SendAsync("Send", message);
}
}
Now you can add this hub to DI container as Singleton:
services.AddSingleton<IStatisticsHub, StatisticHub>();
The last step is to inject this hub into your controller:
public class Controller : ControllerBase
{
private readonly IStatisticsHub _statisticsHub;
public Controller(IStatisticsHub statisticsHub)
{
_statisticsHub = statisticsHub;
}
[HttpPost]
public JsonResult Update(Record record)
{
// code omitted for brevity
// send message to all clients
_statisticsHub.Send("Statistics");
return Json(new { Data = data, success = true }, JsonRequestBehavior.AllowGet);
}
}
It should be working in that way.
First of all, the frontend has to create a WebSocket connection with this hub to receives all messages, but I believe you already know it.
Upvotes: 1
Reputation: 162
If you want to use a SignalR I recommend to use the CQRS architecture pattern. It will resolve your problems. In vertically sliced architecture you will see where will be the best spot to send notifications to all clients.
1) If you want a simple but smelled solution then do it this way. But I recommend using CQRS. 2) yes :)
Upvotes: 1