Ответ 1
Вы идете по этому неправильно. Ну, частично, так или иначе. Вы не можете заставить OWIN вводить зависимости в класс Startup. Таким образом, вам нужно будет использовать ядро, которое настроено с помощью app.UseNinjectMiddleware()
, чтобы разрешить ваш класс конфигурации параметров. Мы сделаем это с ленивым ядром.
Сначала вы должны настроить это в Startup.Auth.cs. Кроме того, у вас есть избыточность там. app.UseNinjectWebApi(config)
вызовет app.UseWebApi(config)
(см. источник). Я также не знаю, почему вы вызываете WebApiConfig.Register()
там, потому что обычно вызывается в Global.asax.cs
В любом случае, это должно выглядеть так (я не тестировал это, но должен быть близок):
Во-первых, мы собираемся перенести создание ядра на ленивый метод, а затем ваш вызов UseNinjectMiddleware()
в методе Startup.Configuration()
использует ленивый керел в классе Startup в качестве члена. Это лучше всего работает как простой делегат лямбды, а не создает статический метод CreateKernel.
public partial class Startup
{
private readonly Lazy<IKernel> _kernel = new Lazy<IKernel>(() =>
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
// here for brevity, move this to a RegisterServices or similar method,
//
kernel.Bind<IOAuthAuthorizationServerOptions>()
.To<MyOAuthAuthorizationServerOptions>();
kernel.Bind<IOAuthAuthorizationServerProvider>()
.To<AuthorizationServerProvider>();
kernel.Bind<IAuthenticationTokenProvider>().To<RefreshTokenProvider>();
kernel.Bind<IUserService>().To<MyUserService>();
return kernel;
});
public void Configuration(IAppBuilder app)
{
app.UseNinjectMiddleware(() => _kernel.Value);
var config = new HttpConfiguration();
app.UseNinjectWebApi(config);
ConfigureAuth(app);
}
}
Затем в вашем ConfigureAuth()
public void ConfigureAuth(IAppBuilder app)
{
// .... other auth code
// Yes, boo hiss, service location, not much choice...
// Setup Authorization Server
app.UseOAuthAuthorizationServer(_kernel.Value
.Get<MyOAuthAuthorizationServerOptions>().GetOptions());
}
Забастовкa >
Затем создайте интерфейс:
public interface IOAuthAuthorizationServerOptions
{
OAuthAuthorizationServerOptions GetOptions();
};
Создайте свою реализацию:
public class MyOAuthAuthorizationServerOptions : IOAuthAuthorizationServerOptions
{
private IOAuthAuthorizationServerProvider _provider;
private IAuthenticationTokenProvider _tokenProvider;
public MyOAuthAuthorizationServerOptions(IAuthenticationTokenProvider tProvider,
IOAuthAuthorizationServerProvider provider)
{
_provider = provider;
_tokenProvider = tProvider;
}
public OAuthAuthorizationServerOptions GetOptions()
{
return new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true, //TODO: HTTPS
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = _provider,
RefreshTokenProvider = _tokenProvider
};
}
}
EDIT (4/6/15):
Подумав об этом, я думаю, что Lazy<T>
добавляет ссылку на добавление, которая действительно не нужна. Это может быть изменено для достижения тех же результатов в гораздо более чистом виде:
Создайте новый класс Startup.Ninject.cs и поместите его в App_Start:
public partial class Startup
{
public IKernel ConfigureNinject(IAppBuilder app)
{
var config = new HttpConfiguration();
var kernel = CreateKernel();
app.UseNinjectMiddleware(() => kernel)
.UseNinjectWebApi(config);
return kernel;
}
public IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
return kernel;
}
}
public class NinjectConfig : NinjectModule
{
public override void Load()
{
RegisterServices();
}
private void RegisterServices()
{
kernel.Bind<IOAuthAuthorizationServerOptions>()
.To<MyOAuthAuthorizationServerOptions>();
kernel.Bind<IOAuthAuthorizationServerProvider>()
.To<AuthorizationServerProvider>();
kernel.Bind<IAuthenticationTokenProvider>().To<RefreshTokenProvider>();
kernel.Bind<IUserService>().To<MyUserService>();
}
}
Затем в Startup выполните следующее:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var kernel = ConfigureNinject(app);
ConfigureAuth(app, kernel);
}
}
Наконец, измените ConfigureAuth, чтобы взять второй параметр и использовать его.
public void ConfigureAuth(IAppBuilder app, IKernel kernel)
{
// .... other auth code
// Yes, boo hiss, service location, not much choice...
// Setup Authorization Server
app.UseOAuthAuthorizationServer(
kernel.Get<MyOAuthAuthorizationServerOptions>().GetOptions());
}