我想使用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
。在这种情况下,空主体很好,不应引发异常。
答案 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;
}
虽然这有效,但我对此解决方案并不满意。