I have a Web Api 2 App, with two classes that both depend on another class, and i'm using ninject to resolve the dependancies.
public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
{
private IUserService _userService;
public AuthorizationServerProvider(IUserService userService)
{
_userService = userService;
}
}
public class RefreshTokenProvider : IAuthenticationTokenProvider
{
private IUserService _userService;
public RefreshTokenProvider(IUserService userService)
{
_userService = userService;
}
In the startup.cs class i need to use the above two classes, but of course i cannot use constructor injection in the startup class, as that is initialised before Ninject is.
What's a way around this so that the references to _tokenProvider and _authServerProvider in the ConfigureAuth method?
public class Startup
{
private AuthorizationServerProvider _authServerProvider;
private RefreshTokenProvider _tokenProvider;
public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
app.UseNinjectMiddleware(CreateKernel);
app.UseNinjectWebApi(config);
ConfigureOAuth(app);
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app)
{
var oAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true, //TODO: HTTPS
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = _authServerProvider,
RefreshTokenProvider = _tokenProvider
};
}
Here's the CreateKernel Method
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
And here's where I register my services
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<SimpleAuthorizationServerProvider>().ToSelf();
kernel.Bind<SimpleRefreshTokenProvider>().ToSelf();
}
I've followed the advice in the ninject docs, but to no avail.
You're going about this the wrong way. Well, partially the wrong way anyways. You can't get OWIN to inject dependencies into the Startup class. So, you'll have to use the kernel that gets configured with
app.UseNinjectMiddleware()
to resolve your options configuration class. We'll do this with a Lazy kernel.First, you should be configuring this in Startup.Auth.cs. Also, you've got some redundancy in there..
app.UseNinjectWebApi(config)
will callapp.UseWebApi(config)
(see the source). I also don't know why you're callingWebApiConfig.Register()
there because that's typically called in Global.asax.csIn any event, it should look like this (I haven't tested this, but it should be close):
First, we're going to move your kernel creation to a lazy method, and then have your
UseNinjectMiddleware()
call inStartup.Configuration()
method use the lazy kerel in the Startup class as a member. This works best I think as a simple lambda delegate, rather than creating a static CreateKernel method.Then in your ConfigureAuth()
Then create an interface:
Create your implementation:
EDIT (4/6/15):
Upon further thought on this, I think the
Lazy<T>
adds an addition reference that is really unnecessary. This can be modified to achieve the same results in a much cleaner way as such:Create a new Startup.Ninject.cs class, and put it in App_Start:
Then, in Startup do this:
Finally, Modify ConfigureAuth to take the second parameter and use that instead.