【发布时间】:2017-04-04 08:14:21
【问题描述】:
我一直在阅读Session and application state 官方文档,偶然发现了以下段落:
异步加载会话
ASP.NET Core 中的默认会话提供程序加载会话记录 仅当从底层 IDistributedCache ISession.LoadAsync 方法在 TryGetValue 之前显式调用, Set 或 Remove 方法。如果没有首先调用 LoadAsync,则 底层会话记录是同步加载的,这可以 可能会影响应用的扩展能力。
要让应用程序强制执行此模式,请将 DistributedSessionStore 和 DistributedSession 实现 如果未调用 LoadAsync 方法则引发异常的版本 在 TryGetValue、Set 或 Remove 之前。 在 服务容器。
包装本身对我来说不是问题,但为了实现它,我需要:
- 参考原始实现
- 注册打包版本
目前,我创建了以下包装类:
public class WrappedDistributedSession : ISession
{
private DistributedSession _service;
private bool loaded = false;
public WrappedDistributedSession(DistributedSession service)
{
_service = service;
}
public bool IsAvailable => _service.IsAvailable;
public string Id => _service.Id;
public IEnumerable<string> Keys => _service.Keys;
public void Clear() => _service.Clear();
public Task CommitAsync() => _service.CommitAsync();
public Task LoadAsync()
{
loaded = true;
return _service.LoadAsync();
}
public void Remove(string key)
{
if(loaded)
{
_service.Remove(key);
} else
{
throw new Exception();
}
}
public void Set(string key, byte[] value)
{
if (loaded)
{
_service.Set(key, value);
}
else
{
throw new Exception();
}
}
public bool TryGetValue(string key, out byte[] value)
{
if (loaded)
{
return _service.TryGetValue(key, out value);
}
else
{
throw new Exception();
}
}
}
我已经在Startup.ConfigureServices注册了
services.AddScoped<ISession, WrappedDistributedSession>();
显然,由于我正在写这个问题,所以我的解决方案不起作用。我哪里出错了,如何“在服务容器中注册包装的版本”?
【问题讨论】:
-
您还有
AddSession电话吗?更重要的是:您是否在 AddSession 之前或之后注册了您的实现?这很重要,因为大多数AddXxx类使用TryAddcoped|Transient|Singleton而不是AddScoped|Transient|Singleton,所以必须先注册。 -
不要实现
ISession,而是定义您自己的特定于应用程序的抽象。这种抽象可以很小(最好是一个成员)并且可以根据您的应用程序的需求量身定制。如果您这样做,您将大大简化您的实现,您甚至不必“如果在 TryGetValue 之前未调用 LoadAsync 方法则引发异常”,因为您将防止这种情况发生在您自己的会话实现中。如果这样做,您将有效地遵循依赖倒置原则和接口隔离原则。 -
@Steven:所以我应该编写自己的层来为我调用
LoadAsync,而不是使用ISession?但是,如果我通过HttpContext.Session访问会话,我可以直接引用ISession呢?我不是这个项目的唯一开发人员,我真的更喜欢防弹解决方案。 -
@alesc:我不是在这里谈论层。我只是在谈论定义您自己的接口并将其放在您已经拥有的“适配器”实现上。此适配器可以放置在您的合成根中或附近,此时您可以访问特定于 ASP.NET 的所有内容,例如
HttpContext。所以你的适配器可以以适当的方式调用HttpContext.Session。 -
@Steven 给出答案很好,这通常会导致解决方案。您没有提供几乎足够的信息来显示如何执行所要求的操作,以注册包装的版本。您似乎在要求我们去学习如何以您认为正确的方式编码。我就像提问者一样。它不起作用,我不知道为什么。诚然,微软应该在他们的文档中提供示例,但可惜他们没有。所以我们在这里。如果您知道如何,请发布解决方案。
标签: c# asp.net dependency-injection asp.net-core asp.net-core-mvc