2014-10-10 90 views
2

在嘗試將Ninject與使用ASP.NET Identity的新Web API 2項目結合使用時,我遇到了一些奇怪的現象。我無法獲得傳遞給CreatePerOwinContext()的回調以請求Web API控制器。對於MVC控制器,它們工作正常。Ninject OWIN擴展爲Web API打破CreatePerOwinContext

步驟重新創建:

  1. 文件 - >新建VS 2013 ASP.NET Web應用程序
  2. 檢查MVC &的WebAPI
  3. 在身份驗證選擇個人
  4. 添加的NuGet包Ninject,Ninject。 Web.Common.OwinHost,Ninject.Web.WebApi.OwinHost &相關軟件包
  5. 按照guidance配置ninject for你的Owin支持的應用程序
  6. 在你的ApplicationUserManager.Create()中放置一個斷點,然後F5調試
  7. 看到一個請求到你的主控制器工作正常 - 斷點被擊中。做一個小提琴手請求到API控制器 - 比如,API /帳號/註冊和回調根本就不曾叫

我不是一個ninject愛好者,所以我不能確定,如果這件事情我做錯了或Ninject OWIN擴展中的錯誤。我傾向於留下OwinContext,並簡單地使用Ninject perHttpRequest範圍,但我不確定ASP.NET Identity系統是否會中斷。我聽說可能會對OwinContext.Get()進行內部調用,如果我沒有將事情保留在OWIN上下文中,就會中斷。

非常感謝任何人的想法。

回答

3

我最終通過使用Ninject來實現所有終身管理。很明顯,.CreatePerOwinContext()是一個stop gap solution,如果使用完整的DI工具,則不需要。

我所看到的唯一一件事就是基於cookie的身份驗證,ASP.NET Identity將在OwinContext中查找其UserManager。我使用基於令牌的身份驗證,但我已經看到一些人繼續前進,並將一個UserManager添加到OwinContext中。

我Ninject綁定:

private static readonly Lazy<IKernel> _lazyKernel = new Lazy<IKernel>(CreateKernel); 

    // Access the singleton kernel via this property 
    public static IKernel Kernel { get { return _lazyKernel.Value; } } 

private void ConfigureNinject(IAppBuilder app) 
{ 
    app.UseNinjectMiddleware(() => Kernel); 
    Kernel.Bind<IAppBuilder>().ToConstant(app); 
} 

private static void RegisterServices(IKernel kernel) 
{ 
    kernel.Bind<AuthDbContext>().ToSelf().InRequestScope().WithConstructorArgument("connectionString", "MyConnectionString"); 
    kernel.Bind<IUserStore<MyApplicationUser, int>>().To<MyUserStore>().InRequestScope(); 
    kernel.Bind<IRoleStore<MyRole, int>>().To<MyRoleStore>().InRequestScope(); 
    kernel.Bind<MyUserManager>().ToSelf().InRequestScope(); 
    kernel.Bind<ISecureDataFormat<AuthenticationTicket>>().To<SecureDataFormat<AuthenticationTicket>>(); 
    kernel.Bind<IDataSerializer<AuthenticationTicket>>().To<TicketSerializer>(); 
    kernel.Bind<IDataProtector>().ToMethod(x => x.Kernel.Get<IAppBuilder>().GetDataProtectionProvider().Create("ASP.NET Identity")); 
    kernel.Bind<ITextEncoder>().To<Base64UrlTextEncoder>(); 
}