猿问

我该如何正确地将`TempDataDictionary`注入我的班级?

我有一个使用c#和ASP.NET MVC 5编写的应用程序。我还使用Unity.Mvc进行依赖项注入。

与许多其他类一起,该类MessageManagerIoC容器中注册。但是,MessageManager该类依赖于的实例TempDataDictionary来执行其工作。此类用于为视图写入临时数据。

为了解析的实例,MessageManager我还需要注册的实例TempDataDictionary。我将需要能够TempDataDictionaryMessageManager类中添加值,然后需要从视图访问临时数据。因此,我需要能够访问TempDataDictionary视图中的相同实例,以便可以将消息写给用户。

另外,如果控制器将用户重定向到其他地方,我也不想丢失消息,但我仍然希望能够在下一个视图中显示该消息。

我尝试了以下方法来注册TempDataDictionaryMessageManager

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();

}


海绵宝宝撒
浏览 146回答 2
2回答

吃鸡游戏

该TempDataDictionary是你的内在组成部分MessageManager执行情况,因此,你应该实现它是类里面,而不是直接在容器中对其进行注册的。就像是:public class MessageManager : IMessageManager{&nbsp; &nbsp; private TempDataDictionary _tempDataDictionary;&nbsp; &nbsp; [...]}但是,恕我直言,我认为TempDataDictionary在控制器上下文之外使用不是一个好习惯,因此,您可以在每次添加或检索消息时通过它,而不是在您的类中实现它:void AddSuccess(IDictionary<string, object> tempData, string message);您还可以MessageManager使用来为每个请求创建一个实例PerThreadLifetimeManager,然后根本不需要使用TempDataDictionary,只需使用常规列表或字典自己实现即可:public class MessageManager : IMessageManager{&nbsp; &nbsp; private List<string> _successMessages = new List<string>();&nbsp; &nbsp; private List<string> _errorMessages = new List<string>();&nbsp; &nbsp; private List<string> _warningMessage = new List<string>();&nbsp; &nbsp; private List<string> _infoMessage = new List<string>();&nbsp; &nbsp; public void AddSuccess(string message)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _successMessages.Add(message);&nbsp; &nbsp; }&nbsp; &nbsp; public void AddError(string message)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _errorMessages.Add(message);&nbsp; &nbsp; }&nbsp; &nbsp; public void AddWarning(string message)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _warningMessages.Add(message);&nbsp; &nbsp; }&nbsp; &nbsp; public void AddInfo(string message)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _infoMessages.Add(message);&nbsp; &nbsp; }&nbsp; &nbsp; public List<string> SuccessMessages&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get { return _successMessages; }&nbsp; &nbsp; }&nbsp; &nbsp; public List<string> ErrorMessages&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get { return _errorMessages; }&nbsp; &nbsp; }&nbsp; &nbsp; public List<string> WarningMessages&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get { return _warningMessages; }&nbsp; &nbsp; }&nbsp; &nbsp; public List<string> InfoMessages&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get { return _infoMessages; }&nbsp; &nbsp; }}然后,为每个线程注册它,以便在每个请求中清除所有内容:Container.RegisterType.RegisterType<IMessageManager, MessageManager>&nbsp; &nbsp; &nbsp; &nbsp; (new PerThreadLifetimeManager());更好的方法?如果要确保列表一直保留到读取为止,即使它在另一个请求中发生,或者如果您正在使用异步操作或ajax请求,则可以创建自己的LifetimeManager实现来解析上述类的实例。每个会话,例如:public class SessionLifetimeManager : LifetimeManager{&nbsp; &nbsp; private string _key = Guid.NewGuid().ToString();&nbsp; &nbsp; public override void RemoveValue(ILifetimeContainer container = null)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; HttpContext.Current.Session.Remove(_key);&nbsp; &nbsp; }&nbsp; &nbsp; public override void SetValue(object newValue, ILifetimeContainer container = null)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; HttpContext.Current.Session[_key] = newValue;&nbsp; &nbsp; }&nbsp; &nbsp; public override object GetValue(ILifetimeContainer container = null)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return HttpContext.Current.Session[_key];&nbsp; &nbsp; }&nbsp; &nbsp; protected override LifetimeManager OnCreateLifetimeManager()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return new PerSessionLifetimeManager();&nbsp; &nbsp; }}然后PerThreadLifetimeManager,SessionLifetimeManager在上方替换为,并在每次访问该列表时都将其清除,例如:public List<string> InfoMessages{&nbsp; &nbsp; get&nbsp;&nbsp; &nbsp; {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Some view has accessed the data, clear the list before returning&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var tempInfoMessages = new List<string>(_infoMessages);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_infoMessages.Clear();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return tempInfoMessages;&nbsp;&nbsp; &nbsp; }}

幕布斯6054654

严格来说,这不是答案,而是另一种建议:另外,如果控制器将用户重定向到其他地方,我也不想丢失消息,但我仍然希望能够在下一个视图中显示该消息。仅仅看一下上面的内容,对我来说,将您的消息存储在数据库中可能是一个更好的选择。这样,您甚至可以返回过去并根据需要查看旧消息。// persist in EF db contextclass Message {&nbsp; &nbsp; DateTime CreatedUtc { get; set; }&nbsp; &nbsp; DateTime SeenUtc { get; set; }&nbsp; &nbsp; string Text { get; set; }&nbsp; &nbsp; AspNetUser User { get; set; }&nbsp; &nbsp; // etc}然后,您可以在请求中保留该消息,管理何时将该消息标记为已看到,甚至让用户看到他的旧消息(如果您愿意的话)
随时随地看视频慕课网APP
我要回答