我有一个应用程序是用c和asp.net mvc 5编写的。我也在使用Unity.Mvc进行依赖注入。
与许多其他类一起,类MessageManager注册在IoC容器中。然而,MessageManager类依赖于TempDataDictionary的实例来执行其工作。此类用于为视图写入临时数据。
为了解析MessageManager的实例,我还需要注册TempDataDictionary的实例。我需要能够从TempDataDictionary类向MessageManager添加值,然后需要从视图访问临时数据。因此,我需要能够在视图中访问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();
}

最佳答案

TempDataDictionaryMessageManager实现的一个内在部分,因此,应该直接在该类中实现它,而不是在容器中注册它。
类似于:

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/

10-17 00:37