我有一个应用程序是用c和asp.net mvc 5编写的。我也在使用Unity.Mvc进行依赖注入。
与许多其他类一起,类MessageManager
注册在IoC
容器中。然而,MessageManager
类依赖于TempDataDictionary
的实例来执行其工作。此类用于为视图写入临时数据。
为了解析MessageManager
的实例,我还需要注册TempDataDictionary
的实例。我需要能够从TempDataDictionary
类向MessageManager
添加值,然后需要从视图访问临时数据。因此,我需要能够在视图中访问TempDataDictionary
的同一个实例,以便可以向用户写出消息。
另外,如果控制器将用户重定向到别处,我不想丢失消息,我仍然希望能够在下一个视图上显示消息。
我试着注册了TempDataDictionary
和MessageManager
:
Container.RegisterType<TempDataDictionary>(new PerThreadLifetimeManager())
.RegisterType<IMessageManager, MessageManager>();
然后,在我看来,我有以下内容可以解析为
IMessageManager
var manager = DependencyResolver.Current.GetService<IMessageManager>();
但是,由于某种原因,消息会丢失。也就是说,当我解析
manager
时,TempDataDictionary
不包含由MessageManager
从控制器添加的任何消息。如何正确注册
TempDataDictionary
的实例,以便数据在查看之前一直保持不变?更新
这是我的
IMessageManager
界面public interface IMessageManager
{
void AddSuccess(string message, int? dismissAfter = null);
void AddError(string message, int? dismissAfter = null);
void AddInfo(string message, int? dismissAfter = null);
void AddWarning(string message, int? dismissAfter = null);
Dictionary<string, IEnumerable<FlashMessage>> GetAlerts();
}
最佳答案
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
关于c# - 我如何正确地将`TempDataDictionary`注入(inject)我的类(class)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50107425/