I have a WebApi service that I am trying to add to using Ninject BindHttpFilter.
Using BindHttpFilter allows you to associate an authentication filter with a specific attribute. AuthenticationFilter accepts a constructor parameter (IAuthenticationService), which Ninject itself creates.
kernel.BindHttpFilter<AuthenticationHttpFilter>(System.Web.Http.Filters.FilterScope.Action) .WhenActionMethodHas<AuthenticationFilterAttribute>() .WithConstructorArgument("service", x => x.Kernel.Get<IAuthenticationService>());
The specific AuthenticationService implementation accepts the constructor parameter INonceRepository, which is entered through Ninject:
public AuthenticationService(INonceRepository nonceRepository, ...)
The specific implementation of NonceRepository accepts the ISession constructor, which is introduced through Ninject:
public NonceRepository(ISession session)
Here's what the Ninject bindings look like:
kernel.Bind<INonceRepository>().To<NonceRepository>(); kernel.Bind<IAuthenticationService>().To<AuthenticationService>() var session = sessionFactory.OpenSession(); Bind<ISession>().ToMethod(c => session).InRequestScope();
When a specific AuthenticationService implementation is executed in the code, only one instance is created, and therefore NonceRepositiory is created only once. This means that ISession is valid and open the first request, but ISession is closed in the second call, and the AuthenticationService constructor is never called a second time. It seems like this is a problem with the scope definition, but I can’t understand that it doesn’t have the correct scope definition to force the AuthenticationService to be recreated on request.
I tried changing the BindHttpScope request from FilterScope.Controller to FilterScope.Action (thinking that this would cause the AuthenticationService scope to be what it was created to invoke the Action Action), but that didn't solve it.
Here's what the interesting code points look like:
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); } }