2013-11-05 28 views
58

這是一個Web API 2項目。OwinStartup如何使用DI容器

當我使用Ninject DI實現,我得到一個錯誤信息

試圖創建類型的控制裝置「TokenController」時發生錯誤。確保控制器有一個無參數的公共構造函數。

[assembly: OwinStartup(typeof(Web.Startup))] 

namespace Web 
{ 
    public partial class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      ConfigureAuth(app); 
      ConfigureWebApi(app); 
     } 
    } 
} 

public class TokenController : ApiController 
{ 

    private IUserService _userService; 

    public TokenController(IUserService userService) 
    { 
     this._userService = userService; 
    } 

    [Route("api/Token")] 
    public HttpResponseMessage PostToken(UserViewModel model) 
    { 
     if (_userService.ValidateUser(model.Account, model.Password)) 
     { 
      ClaimsIdentity identity = new ClaimsIdentity(Startup.OAuthBearerOptions.AuthenticationType); 
      identity.AddClaim(new Claim(ClaimTypes.Name, model.Account)); 
      AuthenticationTicket ticket = new AuthenticationTicket(identity, new AuthenticationProperties()); 
      var currentUtc = new SystemClock().UtcNow; 
      ticket.Properties.IssuedUtc = currentUtc; 
      ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30)); 
      return new HttpResponseMessage(HttpStatusCode.OK) 
      { 
       Content = new ObjectContent<object>(new 
       { 
        UserName = model.Account, 
        AccessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket) 
       }, Configuration.Formatters.JsonFormatter) 
      }; 
     } 

     return new HttpResponseMessage(HttpStatusCode.BadRequest); 
    } 
} 

當我添加<add key="owin:AutomaticAppStartup" value="false" />到Web.config中

Ninject工作正常,但 Startup.OAuthBearerOptions.AccessTokenFormat變成空

如何使用DI容器OWIN?

UPDATE

實施的IDependencyResolver和使用的WebAPI依賴解析器如下

public void ConfigureWebApi(IAppBuilder app) 
{ 
    HttpConfiguration config = new HttpConfiguration(); 

    config.DependencyResolver = new NinjectDependencyResolver(NinjectWebCommon.CreateKernel()); 

    app.UseWebApi(config); 
} 

NinjectDependencyResolver


簡單的注射器情況下

public void ConfigureWebApi(IAppBuilder app) 
{ 
    HttpConfiguration config = new HttpConfiguration(); 

    var container = new Container(); 
    container.Register<IUserService, UserService>(); 
    config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container); 

    app.UseWebApi(config); 
} 

SimpleInjectorWebApiDependencyResolver

+0

是否有一個理由,爲什麼你不能一個空的構造函數添加到您的控制器? –

+0

@NikolaiSamteladze我已經在空構造函數中實現了依賴注入,我只想知道如何在這種情況下使用DI容器 –

+0

[有一個項目](https://github.com/DotNetDoodle/DotNetDoodle.Owin.Dependencies)它提供了這種支持,但是也許你必須自己編寫適配器,因爲它僅爲autofac提供了一個開箱即用的實現。 –

回答

32

你可能想看看this blog post

它使用的是Unity,但最終應該是一樣的。

基本上,使用WebAPI依賴關係解析器。確保一切都正確映射,它應該沒問題。

如果在設置DI之後,您的OAuth令牌仍然存在問題,請告訴我。

乾杯

+0

我使用WebAPI依賴關係解析器,它的工作原理,謝謝你的回答! –

2

我們利用的NuGet

PM>安裝包ninject.MVC5

然後我們配置我們的綁定,像這樣安裝標準ninject.MVC5包。

kernel.Bind<IDbContext, DbContext>() 
    .To<BlogContext>() 
    .InRequestScope(); 

kernel.Bind<IUserStore<User>>() 
    .To<UserStore<User>>() 
    .InRequestScope(); 

kernel.Bind<IDataProtectionProvider>() 
    .To<DpapiDataProtectionProvider>() 
    .InRequestScope() 
    .WithConstructorArgument("ApplicationName"); 

kernel.Bind<ApplicationUserManager>().ToSelf().InRequestScope() 
    .WithPropertyValue("UserTokenProvider", 
     new DataProtectorTokenProvider<User>(
      kernel.Get<IDataProtectionProvider>().Create("EmailConfirmation") 
      )); 

您可能需要根據您定製用戶模型的多少來調整。例如,用戶存儲綁定可能是類似的。

kernel.Bind<IUserStore<User, int>>() 
     .To<IntUserStore>().InRequestScope(); 

還可以在用戶管理器構造函數中設置所需的用戶管理器密碼策略。

此前可以在示例中的create方法中找到,您將不再需要此操作。 你現在也可以擺脫owin get上下文調用,因爲ninject會爲你處理解析。

+0

在內部有一些身份的東西依賴於OWIN(即它調用OwinContext.Get())。你有沒有看到與此有關的任何奇怪或問題? – JasonCoder

+0

@JasonCoder不能說我們已經遇到了任何問題,一段時間以來一直在生產項目中使用這種設置。 – jps

17

更新

現在這是更直接得益於NuGet包Ninject.Web.WebApi.OwinHost

Startup.cs

using Ninject; 
using Ninject.Web.Common.OwinHost; 
using Ninject.Web.WebApi.OwinHost; 
using Owin; 
using System.Web.Http; 

namespace Xxx 
{ 
    public class Startup 
    { 
     public void Configuration(IAppBuilder app) 
     { 
      var config = new HttpConfiguration(); 
      config.MapHttpAttributeRoutes(); 
      config.Routes.MapHttpRoute("DefaultApi", "myservice/{controller}/{id}", new { id = RouteParameter.Optional }); 

      app.UseNinjectMiddleware(CreateKernel); 
      app.UseNinjectWebApi(config); 
     } 
    } 
    public static IKernel CreateKernel() 
    { 
     var kernel = new StandardKernel(); 

     kernel.Bind<IMyService>().To<MyService>(); 
     return kernel; 
    } 
} 

我已經相應地更新維基。

https://github.com/ninject/Ninject.Web.Common/wiki/Setting-up-a-OWIN-WebApi-application

所有這三個主機的選擇。

https://github.com/ninject/Ninject.Web.WebApi/wiki/Setting-up-an-mvc-webapi-application

+1

我已經試過這個非常簡單的示例owin託管的應用程序,它僅適用於第一次調用。隨後的調用導致錯誤:「確保控制器有一個無參數的公共構造函數。」。任何想法爲什麼? –