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 方法,如下所示:

    1. {
    2. private readonly IAbpSession _session;
    3. public MyService(IAbpSession session)
    4. {
    5. public void Test()
    6. {
    7. using (_session.Use(42, null))
    8. var tenantId = _session.TenantId; //42
    9. var userId = _session.UserId; //null
    10. }
    11. }

    Use 方法返回了一个 IDisposable 对象,并且该对象 必须是可释放的 。 一旦该对象被释放了,Session值会自动的还原为之前使用的值。

    警告

    你应该像上面一样使用它,在using语法糖中使用。否则,你会得到意想不到的session值。你可以嵌套使Use,它会按你预期的工作。

    你可以使用 ToUserIdentifier() 扩展方法从IAbpSession创建一个UserIdentifier对象。因为UserIdentifier被大多数API使用,所以使用该方法可以很方便的为当前用户创建一个UserIdentifier。