Environment: ASP.NET WebAPI 2, NInject Web API (3.3.0.0)
Use Case: I am setting up custom Owin authentication using OwinStartup class. The class uses ASP.NET Identity.IUserStore to setup users. My challenge is getting the configured resolver to query for this reference. However, the resolver retrieval like in MVC, doesn't works in WebAPI
var userStore = DependencyResolver.Current.GetService(typeof(IUserStore<ExtendedUser, string>)) as IUserStore<ExtendedUser, string>;
My startup config as below:-
public partial class Startup
{
System.Web.Http.Dependencies.IDependencyResolver resolver;
public void Configuration(IAppBuilder app)
{
HttpConfiguration httpConfig = new HttpConfiguration();
// Due to "new" config, the underlying resolver gets empty
this.resolver = httpConfig.DependencyResolver;
this.ConfigureOAuthTokenGeneration(app);
// ... other code removed
}
private void ConfigureOAuthTokenGeneration(IAppBuilder app)
{
// Fails due to resolver being empty
var userStore = this.resolver.GetService(typeof(IUserStore<ExtendedUser, string>)) as IUserStore<ExtendedUser, string>;
UserService.UserStore = userStore;
app.CreatePerOwinContext<UserService>(UserService.Create);
// Other code removed
}
}
UserService class:-
public class UserService : UserManager<ExtendedUser, string>
{
public UserService(IUserStore<ExtendedUser, string> store)
: base(store)
{
}
//[Ninject.Inject]
public static IUserStore<ExtendedUser, string> UserStore { get; set; }
public static UserService Create(IdentityFactoryOptions<UserService> options, IOwinContext context)
{
// var userStore = DependencyResolver.Current.GetService(typeof(IUserStore<ExtendedUser, string>)) as IUserStore<ExtendedUser, string>;
var manager = new UserService(UserStore);
....
}
}
The interface is configured in the NInject configuration properly. NInject otherwise is setup correctly as without Owin integration, I can resolve my services.
kernel.Bind<Microsoft.AspNet.Identity.IUserStore<ExtendedUser, string>>().To<UserStore<ExtendedUser, string>>();
Attempts already made
- Property injection using "Inject" parameter
- Separating the requesting UserManager from the service (that also takes a constructor which requires initialization explictly
Update 1: Another use case of similar situation: I am trying to setup a custom logger on ExceptionFilter as follows:-
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Exception handling
config.Filters.Add(new ExceptionFilters());
}
}
public class ExceptionFilters : ExceptionFilterAttribute
{
public ExceptionFilters(ZLogging.ILogger logger)
{
this.logger = logger;
}
public override void OnException(HttpActionExecutedContext context)
{
this.logger.Log(....)
}
}
Here again the call to ExceptionFilters constructor gets blocked out in the Register method of WebApiConfig.
Within the WebApiConfig, we can get the DependencyResolver using the HttpConfiguration instance passed and then get the logger service. Hence here its not a problem. But wherever the HttpConfiguration is not accessible there facing issues getting the resolver out
Update 2 Using DI setup within Startup class as follows:-
public void Configuration(IAppBuilder app)
{
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.DependencyResolver = new NinjectDependencyResolver(new Ninject.StandardKernel() );
this.resolver = httpConfig.DependencyResolver;
.... }
Although this clears out the issue with Owin reference resolution, it breaks the exception filters in WebAPI (see update 1) due to Global.asax being resolved first before Startup in the execution cycle :(
Need help in getting the resolver to get the service out. Any necessary insights can be provided.