TempDataDictionary
является неотъемлемой частью вашей MessageManager
реализации, поэтому вы должны реализовать его внутри этого класса напрямую, а не регистрировать в контейнере.
Что-то вроде:
public class MessageManager : IMessageManager
{
private TempDataDictionary _tempDataDictionary;
[...]
}
Однако, IMHO, я не считаю хорошей практикой использовать TempDataDictionary
вне контекста контроллера, поэтому вместо того, чтобы реализовывать его в своем классе, вы можете передавать его каждый раз, когда добавляете или извлекаете сообщение:
void AddSuccess(IDictionary<string, object> tempData, string message);
Вы также можете создать MessageManager
экземпляр для каждого запроса, используя PerThreadLifetimeManager
, и тогда вам вообще не нужно будет использовать TempDataDictionary
, вы можете просто реализовать это самостоятельно с помощью регулярных списков или словарей:
public class MessageManager : IMessageManager
{
private List<string> _successMessages = new List<string>();
private List<string> _errorMessages = new List<string>();
private List<string> _warningMessage = new List<string>();
private List<string> _infoMessage = new List<string>();
public void AddSuccess(string message)
{
_successMessages.Add(message);
}
public void AddError(string message)
{
_errorMessages.Add(message);
}
public void AddWarning(string message)
{
_warningMessages.Add(message);
}
public void AddInfo(string message)
{
_infoMessages.Add(message);
}
public List<string> SuccessMessages
{
get { return _successMessages; }
}
public List<string> ErrorMessages
{
get { return _errorMessages; }
}
public List<string> WarningMessages
{
get { return _warningMessages; }
}
public List<string> InfoMessages
{
get { return _infoMessages; }
}
}
Затем зарегистрируйте его для каждого потока, чтобы все очищалось при каждом запросе:
Container.RegisterType.RegisterType<IMessageManager, MessageManager>
(new PerThreadLifetimeManager());
Лучший подход?
Если вы хотите убедиться, что список хранится до тех пор, пока он не будет прочитан, даже если это происходит в другом запросе, или если вы используете асинхронные действия или запросы ajax, вы можете создать собственную реализацию LifetimeManager
, которая разрешает экземпляр вышеупомянутого класса за сеанс, например:
public class SessionLifetimeManager : LifetimeManager
{
private string _key = Guid.NewGuid().ToString();
public override void RemoveValue(ILifetimeContainer container = null)
{
HttpContext.Current.Session.Remove(_key);
}
public override void SetValue(object newValue, ILifetimeContainer container = null)
{
HttpContext.Current.Session[_key] = newValue;
}
public override object GetValue(ILifetimeContainer container = null)
{
return HttpContext.Current.Session[_key];
}
protected override LifetimeManager OnCreateLifetimeManager()
{
return new PerSessionLifetimeManager();
}
}
Затем замените PerThreadLifetimeManager
на SessionLifetimeManager
выше и просто очищайте список каждый раз, когда вы к нему обращаетесь, например:
public List<string> InfoMessages
{
get
{
// Some view has accessed the data, clear the list before returning
var tempInfoMessages = new List<string>(_infoMessages);
_infoMessages.Clear();
return tempInfoMessages;
}
}
Справка:
SessionLifetimeManager был заимствован отсюда: https://gist.github.com/CrestApps/a246530e386b95d0a05d36bb13805259