2013-11-05 16 views
58

Đây là dự án API Web 2.Cách sử dụng vùng chứa DI khi OwinStartup

Khi tôi thực hiện DI sử dụng Ninject, tôi nhận được một thông báo lỗi

Có lỗi xảy ra khi cố gắng để tạo ra một bộ điều khiển của loại 'TokenController'. Đảm bảo rằng bộ điều khiển có một hàm tạo công khai không tham số.

[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); 
    } 
} 

Khi tôi thêm <add key="owin:AutomaticAppStartup" value="false" /> để web.config

Ninject hoạt động tốt, nhưng Startup.OAuthBearerOptions.AccessTokenFormat trở thành vô giá trị

Làm thế nào để sử dụng DI container với OWIN?

CẬP NHẬT

Thực hiện IDependencyResolver và sử dụng WebAPI phụ thuộc Resolver như sau

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

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

    app.UseWebApi(config); 
} 

NinjectDependencyResolver


Trong trường hợp Injector Simple

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

Có lý do nào khiến bạn không thể thêm một hàm tạo trống vào bộ điều khiển của mình không? –

+0

@NikolaiSamteladze Tôi đã thực hiện tiêm phụ thuộc vào hàm tạo rỗng, tôi chỉ muốn biết cách sử dụng vùng chứa DI trong trường hợp này là –

+0

[Có một dự án] (https://github.com/DotNetDoodle/DotNetDoodle.Owin.Dependencies) cung cấp hỗ trợ này, nhưng có thể bạn sẽ phải viết bộ điều hợp cho chính mình vì nó cung cấp khả năng thực hiện hộp chỉ cho autofac. –

Trả lời

32

Bạn có thể muốn xem this blog post.

Đó là sử dụng Unity nhưng nó sẽ kết thúc giống nhau.

Về cơ bản, hãy sử dụng Trình phân giải phụ thuộc vào WebAPI. Hãy chắc chắn rằng tất cả mọi thứ được ánh xạ đúng cách và nó sẽ được sử dụng tốt.

Nếu sau khi thiết lập DI, bạn vẫn gặp sự cố với mã thông báo OAuth, hãy cho tôi biết.

Cheers

+0

Tôi sử dụng Trình phân giải phụ thuộc vào WebAPI và nó hoạt động, cảm ơn câu trả lời của bạn! –

2

Chúng tôi sử dụng gói ninject.MVC5 tiêu chuẩn được cài đặt với NuGet

PM> cài đặt gói ninject.MVC5

Sau đó chúng ta cấu hình ràng buộc chúng tôi như vậy.

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") 
      )); 

Bạn có thể cần phải điều chỉnh phụ thuộc vào số lượng bạn đã tùy chỉnh mô hình người dùng của mình. Ví dụ, ràng buộc cửa hàng người dùng có thể là một cái gì đó như thế nào.

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

Ngoài ra, bất kỳ thiết lập nào của trình quản lý người dùng bạn yêu cầu có thể được đặt trong trình tạo người quản lý người dùng của bạn.

Trước đây điều này có thể được tìm thấy trong phương thức tạo trong mẫu, bạn sẽ không còn yêu cầu điều này nữa. cũng bây giờ bạn có thể thoát khỏi các cú nhận được các cuộc gọi bối cảnh như ninject sẽ xử lý độ phân giải cho bạn.

+0

Đã có cuộc trò chuyện nội bộ một số công cụ nhận dạng có phụ thuộc vào OWIN (nghĩa là nó thực hiện cuộc gọi tới OwinContext.Get()). Bạn có thấy bất kỳ sự kỳ quặc hoặc vấn đề nào liên quan đến điều này không? – JasonCoder

+0

@JasonCoder Không thể nói rằng chúng tôi đã gặp phải bất kỳ sự cố nào, đã sử dụng thiết lập này cho các dự án đang được sản xuất trong một thời gian. – jps

17

Cập nhật

này hiện thẳng hơn về phía trước nhờ gói 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; 
    } 
} 

Tôi đã cập nhật wiki phù hợp .

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

Tất cả ba tùy chọn lưu trữ.

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

+1

Tôi đã thử tính năng này cho một ứng dụng được lưu trữ trên máy chủ ví dụ rất đơn giản và nó chỉ hoạt động cho cuộc gọi đầu tiên. Các cuộc gọi tiếp theo dẫn đến lỗi: "Đảm bảo rằng bộ điều khiển có một hàm tạo công khai không tham số.". Bất kỳ ý tưởng tại sao? –

Các vấn đề liên quan