web-dev-qa-db-ja.com

OwinStartupでDIコンテナーを使用する方法

これはWeb API 2プロジェクトです。

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はnullになります

OWINでDIコンテナーを使用する方法は?

[〜#〜] update [〜#〜]

IDependencyResolverを実装し、以下のようにWebAPI Dependency Resolverを使用します

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

63
E-Cheng Liu

このブログ投稿 をご覧ください。

Unityを使用していますが、最終的には同じになるはずです。

基本的に、WebAPI Dependency Resolverを使用します。すべてが適切にマッピングされ、問題ないことを確認してください。

DIをセットアップした後でもOAuthトークンに問題がある場合は、お知らせください。

乾杯

34
Maxime Rouiller

更新

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

3つのホスティングオプションすべて。

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

17
mesel

Nugetと共にインストールされた標準のninject.MVC5パッケージを使用します

PM> install-package 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メソッドでこれを見つけることができましたが、これはもう必要ありません。また、ninjectが解決を処理するため、owin get context呼び出しを取り除くことができます。

2
jps