web-dev-qa-db-fra.com

Comment utiliser le conteneur DI quand OwinStartup

C'est un projet Web API 2.

Lorsque j'ai implémenté DI en utilisant Ninject, j'ai reçu un message d'erreur

Une erreur s'est produite lors de la tentative de création d'un contrôleur de type 'TokenController'. Assurez-vous que le contrôleur a un constructeur public sans paramètre.

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

Quand j'ajoute <add key="owin:AutomaticAppStartup" value="false" /> à web.config

Ninject fonctionne correctement, mais Startup.OAuthBearerOptions.AccessTokenFormat devient null

Comment utiliser le conteneur DI avec OWIN?

[~ # ~] met à jour [~ # ~]

Implémentez IDependencyResolver et utilisez le résolveur de dépendances WebAPI comme indiqué ci-dessous

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

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

    app.UseWebApi(config);
}

NinjectDependencyResolver


En cas d'injecteur 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

63
E-Cheng Liu

Vous voudrez peut-être jeter un oeil à cet article de blog .

Il utilise Unity, mais il devrait finir par être le même.

Fondamentalement, utilisez le résolveur de dépendances WebAPI. Assurez-vous que tout est correctement mappé et que tout se passera bien.

Si, après avoir configuré votre DI, vous rencontrez toujours des problèmes avec votre jeton OAuth, faites-le moi savoir.

À votre santé

34
Maxime Rouiller

Mise à jour

C’est maintenant plus simple grâce au paquet 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;
    }
}

J'ai mis à jour le wiki en conséquence.

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

Les trois options d'hébergement.

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

17
mesel

Nous utilisons le paquet standard ninject.MVC5 installé avec nuget

PM> install-package ninject.MVC5

Ensuite, nous configurons nos liaisons comme suit.

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

Vous devrez peut-être ajuster en fonction du degré de personnalisation de votre modèle utilisateur. Par exemple, la liaison de magasin utilisateur peut être quelque chose comme.

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

De plus, toute configuration du gestionnaire d’utilisateurs dont vous avez besoin, c’est-à-dire des stratégies de mot de passe, peut être définie dans le constructeur de votre gestionnaire d’utilisateurs.

Auparavant, cela pouvait être trouvé dans la méthode create de l'exemple, vous n'en aurez plus besoin. De plus, vous pouvez maintenant vous débarrasser des appels contextuels owin get, car ninject gérera la résolution pour vous.

2
jps