2.2.2 注入会话
IAbpSession通常是以属性注入的方式存在于需要它的类中,不需要获取会话信息的类中则不需要它。如果我们使用属性注入方式,我们可以用NullAbpSession.Instance作为默认值来初始化它(IAbpSession),如下所示:
由于授权是应用层的任务,因此我们应该在应用层和应用层的上一层使用IAbpSession(我们不在领域层使用IAbpSession是很正常的)。
ApplicationService, AbpController 和 AbpApiController 这3个基类已经注入了AbpSession属性,因此在Application Service的实例方法中,能直接使用AbpSession属性。
AbpSession定义的一些关键属性:
UserId: 当前用户的标识ID,如果没有当前用户则为null。如果调用的代码是已授权,那么它不可能为空。
ImpersonatorTenantId: 模拟用户租户的标识ID,如果当前会话被其他用户模拟登录。如果不是一个模拟登录,那么该值为空。
MultiTenancySide: 可能是Host或Tenant。
UserId和TenantId是可空类型。当然也提供了不为空时获取数据的 GetUserId() 和 GetTenantId() 方法 。当你确定有当前用户时,你可以使用GetUserId()方法。
如果当前用户为空,使用该方法则会抛出一个异常。GetTenantId()的使用方式和GetUserId()类似。
在某种特别的情况下,你可能想在某个限定的作用域下改变/覆盖会话值。那么你可以使用 IAbpSession.Use 方法,如下所示:
{
private readonly IAbpSession _session;
public MyService(IAbpSession session)
{
public void Test()
{
using (_session.Use(42, null))
var tenantId = _session.TenantId; //42
var userId = _session.UserId; //null
}
}
Use 方法返回了一个 IDisposable 对象,并且该对象 必须是可释放的 。 一旦该对象被释放了,Session值会自动的还原为之前使用的值。
警告
你应该像上面一样使用它,在using语法糖中使用。否则,你会得到意想不到的session值。你可以嵌套使Use,它会按你预期的工作。
你可以使用 ToUserIdentifier() 扩展方法从IAbpSession创建一个UserIdentifier对象。因为UserIdentifier被大多数API使用,所以使用该方法可以很方便的为当前用户创建一个UserIdentifier。