AutoFac:注入NULL值

时间:2016-07-20 09:01:09

标签: c# null autofac

我想使用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。在这种情况下,空主体很好,不应引发异常。

2 个答案:

答案 0 :(得分:8)

在Autofac documentation中,他们建议将Null Object pattern用于此类方案。您可以使用私有构造函数创建一个<?php if (isset($_POST['registration-submission'])) { $base_url = 'https://api.citrixonline.com/G2W/rest'; $org_key = $_POST['organizer_key']; $web_key = $_POST['webinar_key']; $access_token = 'xxxxx'; $gtwPost = (object) array( 'firstName' => $POST['fname'], 'lastName' => $POST['lname'], 'email'=> $POST['email'], ); $newRegistrantFields = json_encode($gtwPost); $headers = array( 'HTTP/1.1', 'Accept: application/vnd.citrix.g2wapi-v1.1+json', 'Content-Type: application/json', 'Authorization: OAuth oauth_token=xxxxx', 'Content-Length:' . strlen( $newRegistrantFields ) ); //Set POST URL for GoToWebinar $gtw_url = $base_url.'/organizers/'.$org_key.'/webinars/'.$web_key.'/registrants?resendConfirmation=false'; //Start GoToWebinar submission $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $gtw_url); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt( $curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 ); curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt( $curl, CURLOPT_POST, 1); curl_setopt( $curl, CURLOPT_POSTFIELDS,$newRegistrantFields ); $newRegistrants = curl_exec($curl); curl_close($curl); $newRegistrantsArray = json_decode($newRegistrants,true); if( array_key_exists( 'registrantKey', $newRegistrantsArray ) && array_key_exists( 'joinUrl', $newRegistrantsArray ) ) { $form_data[ 'status' ] = true; $form_data[ 'code' ] = $_POST[ 'Email' ] . ' successfully registered with webinar'; $form_data[ 'error' ] = 'E300'; //echo json_encode( $form_data ); //exit; } } ?> the code is not working. Please help me with this. 类,该类继承自NullPrincipal接口,该私有构造函数仅公开提供默认实例的IPrincipal readonly字段。然后您可以返回此实例而不是null:

static

当然,您必须更新代码中检查主体是否为空的所有位置,并检查它是否等于builder.Register<IPrincipal>((c, p) => HttpContext.Current?.User ?? NullPrincipal.Default);

答案 1 :(得分:3)

为了解决这个问题,我创建了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;
}

虽然这有效,但我对此解决方案并不满意。