AutoFac:注入 NULL 值
AutoFac: Inject NULL values
我想使用 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
。在这种情况下,一个空主体是可以的,不应引发异常。
为了解决这个问题,我创建了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;
}
虽然这可行,但我对这个解决方案并不完全满意。
在 Autofac documentation they recommend to use the Null Object pattern 中针对此类场景。您可以创建一个 NullPrincipal
class 继承自 IPrincipal
接口的私有构造函数,该构造函数仅公开提供默认实例的 readonly
static
字段。然后你可以 return 这个实例而不是 null:
builder.Register<IPrincipal>((c, p) => HttpContext.Current?.User ?? NullPrincipal.Default);
当然,您必须更新代码中检查主体是否为 null 的所有位置,并改为检查它是否等于 NullPrincipal.Default
。
我想使用 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
。在这种情况下,一个空主体是可以的,不应引发异常。
为了解决这个问题,我创建了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;
}
虽然这可行,但我对这个解决方案并不完全满意。
在 Autofac documentation they recommend to use the Null Object pattern 中针对此类场景。您可以创建一个 NullPrincipal
class 继承自 IPrincipal
接口的私有构造函数,该构造函数仅公开提供默认实例的 readonly
static
字段。然后你可以 return 这个实例而不是 null:
builder.Register<IPrincipal>((c, p) => HttpContext.Current?.User ?? NullPrincipal.Default);
当然,您必须更新代码中检查主体是否为 null 的所有位置,并改为检查它是否等于 NullPrincipal.Default
。