Search code examples
c#asp.net-mvcdependency-injectiontempdata

TempData Dependency Injection


I'm creating a NotificationService to inject into my MVC controllers so I can display toastr messages in my views. I was initially going to store the messages in HttpContext.Current.Items but sometimes the controller redirects to another view on success.

I decided TempData was probably the next best. However, I'm unsure how I am supposed to inject TempData into my NotificationService using dependency injection?

Updated with code example:

public enum NotifyType
{
    Success,
    Error,
    Warn,
    Info
}
public class NotificationMessage
{
    public NotificationMessage(NotifyType notifyType, string message)
    {
        NotifyType = notifyType;
        Message = message;
    }
    public NotifyType NotifyType { get; set; }
    public string Message { get; set; }
}
public interface INotificationService
{
    void Success(string message);
    void Error(string message);
    void Warn(string message);
    void Info(string message);
    List<NotificationMessage> GetMessages();
}
public class HttpNotificationService : INotificationService
{
    private TempDataDictionary _tempData;
    public HttpNotificationService(TempDataDictionary tempData)
    {
        _tempData = tempData;
    }

    private void SetNotification(NotificationMessage notificationMessage)
    {
        List<NotificationMessage> messages = GetMessages();
        messages.Add(notificationMessage);
        _tempData["Notifications"] = messages;
    }
    public void Success(string message)
    {
        SetNotification(new NotificationMessage(NotifyType.Success, message));
    }
    public void Error(string message)
    {
        SetNotification(new NotificationMessage(NotifyType.Error, message));
    }
    public void Warn(string message)
    {
        SetNotification(new NotificationMessage(NotifyType.Warn, message));
    }
    public void Info(string message)
    {
        SetNotification(new NotificationMessage(NotifyType.Info, message));
    }
    public List<NotificationMessage> GetMessages()
    {
        return _tempData["Notifications"] as List<NotificationMessage> ?? new List<NotificationMessage>();
    }
}
public class HomeController : Controller
{
    private INotificationService _notificationService;
    public HomeController(INotificationService notificationService)
    {
        _notificationService = notificationService;
    }
    public ActionResult Action()
    {
        // Do something
        _notificationService.Success("Hooray, you succeeded!");
        return View();
    }
}

Solution

  • For basic requirements, I would override OnActionExecuting in your controller.. then put the notifications in TempData there:

    protected override void OnActionExecuting(ActionExecutingContext filterContext) {
        TempData["Notifications"] = _notificationService.GetNotifications(/* current user */);
        base.OnActionExecuting(filterContext);
    }
    

    In our current project, we use a PartialView that is rendered via an action that serves this purpose specifically. That is more convenient for complicated setups.. but this may be sufficient depending on your needs.