AutoFac: Inject NULL values

本文关键字:values NULL Inject AutoFac | 更新日期: 2023-09-27 17:58:01

我想使用AutoFac将当前主体注入到需要它的对象中。假设我有一个正在执行安全检查的对象(AuthorizationValidator)。它看起来像这样:

public AuthorizationValidator : IAuthorizationValidator
{
  public AuthorizationValidator(IDataAccess dataAccess, IPrincipal principal)
  {
     // Save injected objects
     ...
  }
  public bool CheckPermission(Guid objectId, Action action)
  {
     // Check if we are authorized at all
     if (this.principal == null)
       return false;
     // Check the permission in the database
     ...
  }
}

对于我的web应用程序,AuthorizationValidator已注册,我使用以下注册来注入主体:

builder.Register<IPrincipal>((c, p) => HttpContext.Current?.User);

其他类型的应用程序使用线程的主体或类似的东西。所有需要主体的对象都会注入正确的主体。

如果未经授权进行调用,那么AutoFac会引发一个异常,告诉我它无法提供IPrincipal对象,因为工厂返回了null。在这种情况下,空的主体是可以的,不应该引发异常。

AutoFac: Inject NULL values

在Autofac文档中,他们建议在此类场景中使用Null对象模式。您可以创建一个从IPrincipal接口继承的NullPrincipal类,该类具有仅公开提供默认实例的readonly static字段的专用构造函数。然后你可以返回这个实例而不是null:

builder.Register<IPrincipal>((c, p) => HttpContext.Current?.User ?? NullPrincipal.Default);

当然,您必须更新代码中检查主体是否为null的所有位置,并检查它是否等于NullPrincipal.Default

为了解决这个问题,我创建了IPrincipalFactory接口,它可以在不经过AutoFac:的情况下获得当前主体

public AuthorizationValidator : IAuthorizationValidator
{
  public AuthorizationValidator(IDataAccess dataAccess, IPrincipalFactory principalFactory)
  {
     // Save injected objects
     _dataAccess = dataAccess;
     _principal = principalFactory.GetCurrentPrincipal();
  }
  public bool CheckPermission(Guid objectId, Action action)
  {
     // Same as previous example
     ...
  }
}
public interface IPrincipalFactory
{
  IPrincipal GetCurrentPrincipal();
}

对于ASP.NET应用程序,我会将以下对象注册为IPrincipalFactory:

public class IAspNetPrincipalFactory : IPrincipalFactory
{
  public IPrincipal GetCurrentPrincipal() => HttpContext.Current?.User;
}

尽管这是有效的,但我对这个解决方案并不完全满意。