C# OwinStartup时如何使用DI容器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19781970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:52:23  来源:igfitidea点击:

How to use DI container when OwinStartup

c#asp.net-web-apidependency-injectionninjectowin

提问by E-Cheng Liu

It's a Web API 2 project.

这是一个 Web API 2 项目。

When I implement DI using Ninject, I got an error message

当我使用 Ninject 实现 DI 时,我收到一条错误消息

An error occurred when trying to create a controller of type 'TokenController'. Make sure that the controller has a parameterless public constructor.

尝试创建类型为“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);
    }
}

When I add <add key="owin:AutomaticAppStartup" value="false" />to web.config

当我添加<add key="owin:AutomaticAppStartup" value="false" />到 web.config

Ninject works fine, but Startup.OAuthBearerOptions.AccessTokenFormatbecomes to null

Ninject 工作正常,但Startup.OAuthBearerOptions.AccessTokenFormat变为 null

How to use DI container with OWIN?

如何在 OWIN 中使用 DI 容器?

UPDATE

更新

Implement IDependencyResolver and use the WebAPI Dependency Resolver as below

实现 IDependencyResolver 并使用 WebAPI Dependency Resolver 如下

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

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

    app.UseWebApi(config);
}

NinjectDependencyResolver

NinjectDependencyResolver



In Simple Injector case

在简单注射器情况下

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

SimpleInjectorWebApiDependencyResolver

采纳答案by Maxime Rouiller

You might want to take a look at this blog post.

您可能想看看这篇博文

It's using Unity but it should end-up being the same.

它使用 Unity,但最终应该是一样的。

Basically, use the WebAPI Dependency Resolver. Make sure that everything is mapped properly and it should be fine.

基本上,使用 WebAPI Dependency Resolver。确保所有内容都正确映射并且应该没问题。

If after setting up your DI you still have problem with your OAuth token, let me know.

如果在设置 DI 后您的 OAuth 令牌仍有问题,请告诉我。

Cheers

干杯

回答by jps

We use the standard ninject.MVC5 package installed with nuget

我们使用与 nuget 一起安装的标准 ninject.MVC5 包

PM> install-package ninject.MVC5

PM> 安装包 ninject.MVC5

Then we configure our bindings like so.

然后我们像这样配置我们的绑定。

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

You may need to adjust dependent on how much you have customized your user model. For instance the user store binding may be something like.

您可能需要根据自定义用户模型的程度进行调整。例如,用户存储绑定可能类似于。

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

Also any setting up of the user manger you require i.e. password policies can be set in your user manager constructor.

此外,您需要的用户管理器的任何设置,即密码策略都可以在您的用户管理器构造函数中设置。

Previously this could be found in the create method in the sample, you will no longer require this. also you can now get rid of the owin get context calls as ninject will handle resolution for you.

以前这可以在示例的 create 方法中找到,您将不再需要它。您现在也可以摆脱 owin get 上下文调用,因为 ninject 将为您处理解析。

回答by mesel

Update

更新

This is now more straight forward thanks to the Nuget package Ninject.Web.WebApi.OwinHost:

由于 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;
    }
}

I have updated the wiki accordingly.

我已经相应地更新了维基。

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

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

All three hosting options.

所有三个托管选项。

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

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