gpt4 book ai didi

ninject - 使用 Ninject BindHttpFilter 时的范围问题

转载 作者:行者123 更新时间:2023-12-03 17:49:07 26 4
gpt4 key购买 nike

我有一个 WebApi 服务,我正在尝试使用 Ninject BindHttpFilter 添加身份验证。

使用 BindHttpFilter 允许我将身份验证过滤器绑定(bind)到特定属性。 AuthenticationFilter 接受一个构造函数参数(IAuthenticationService),它本身是由 Ninject 创建的。

kernel.BindHttpFilter<AuthenticationHttpFilter>(System.Web.Http.Filters.FilterScope.Action)
.WhenActionMethodHas<AuthenticationFilterAttribute>()
.WithConstructorArgument("service", x => x.Kernel.Get<IAuthenticationService>());

AuthenticationService 的具体实现采用了一个构造函数参数 INonceRepository,它通过 Ninject 注入(inject):
public AuthenticationService(INonceRepository nonceRepository, ...)

NonceRepository 的具体实现采用了一个通过 Ninject 注入(inject)的构造函数 ISession:
public NonceRepository(ISession session)

这是 Ninject 绑定(bind)的样子:
kernel.Bind<INonceRepository>().To<NonceRepository>();
kernel.Bind<IAuthenticationService>().To<AuthenticationService>()

var session = sessionFactory.OpenSession();

Bind<ISession>().ToMethod(c => session).InRequestScope();

当代码运行时,AuthenticationService 的具体实现只被实例化一次,因此 NonceRepositiory 只被实例化一次。这意味着 ISession 有效并打开第一个请求,但 ISession 在第二次调用时关闭,并且第二次调用 AuthenticationService 的构造函数。似乎这是一个范围问题,但我无法弄清楚什么没有正确的范围来使 AuthenticationService 根据请求重新创建。

我试图将 BindHttpScope 请求从 FilterScope.Controller 更改为 FilterScope.Action (认为这会导致 AuthenticationService 的范围是它是每个 Action 调用创建的),但这并没有解决它。

以下是代码的有趣点:
public class AuthenticationHttpFilter : IAuthenticationFilter
{
private readonly IAuthenticationService authenticationService;

public AuthenticationHttpFilter(IAuthenticationService service)
{
this.authenticationService = service;
}

public bool AllowMultiple { get; private set; }

public Task AuthenticateAsync(HttpAuthenticationContext authenticationContext, CancellationToken cancellationToken)
{
authenticationService.DoAuth();
return Task.FromResult(0);
}

public Task ChallengeAsync(HttpAuthenticationChallengeContext authenticationChallengeContext, CancellationToken cancellationToken)
{
...
}
}

public class AuthenticationService : IAuthenticationService
{
private readonly INonceRepository nonceRepo;

public AuthenticationService(INonceRepository nonceRepo){...}

public void DoAuth()
{
this.nonceRepo.Add(...);
}
}

public class NonceRepository : INonceRepository
{
private readonly ISession _session;

public NonceRepository(ISession session)
{
this._session = session;
}

public void Add(Nonce nonce)
{
this._session.Save(nonce);
}
}

最佳答案

我发现当我使用 WebApi 2 时,一切正常。它在 RequestScope 中的行为与我预期的一样。但是,当使用 MVC 5 时,过滤器保持缓存在管道中,这将构造函数参数保持在“单例”范围内。

我通过进入 actionContext 的配置解决了这个问题。像这样:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class EventGridFilterAttribute : ActionFilterAttribute
{
private readonly Type serviceType = typeof(IEventGridService);

public EventGridFilterAttribute()
{
}

public override async Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
{
var service = actionExecutedContext?.ActionContext?.ControllerContext?.Configuration?.DependencyResolver?.GetService(serviceType) as IEventGridService;

if (service != null && actionExecutedContext.Exception == null)
{
await service.PublishEventsAsync();
}

await base.OnActionExecutedAsync(actionExecutedContext, cancellationToken);
}
}

我的依赖注入(inject)器保存在这里。
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);

我也不用 BindHttpFilter ,但像普通过滤器一样注册我的过滤器。
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new EventGridFilterAttribute());
}

关于ninject - 使用 Ninject BindHttpFilter 时的范围问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25675071/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com