使用Owin和Simple Injector进行UserManager依赖项注入 [英] UserManager dependency injection with Owin and Simple Injector

查看:107
本文介绍了使用Owin和Simple Injector进行UserManager依赖项注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将Simple Injector添加到我的项目中以创建UserAppManager的实例之后,该实例将在会话的整个生命周期中都存在,我开始收到错误消息:

After adding Simple Injector to my project to create an instance of my UserAppManager that will exist through the whole lifetime of a session I started to recieve errors:

没有无参数构造函数的错误:

Error with no parameterless constructor:

尝试创建类型为'AuthController'的控制器时发生错误.确保控制器具有无参数的公共构造函数.

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

无参数构造函数出错:

要使容器能够创建AuthController,它应该只有一个公共构造函数:它必须有2个.

For the container to be able to create AuthController it should have only one public constructor: it has 2.

我遵循了指南( https://simpleinjector.codeplex.com/discussions/564822 ),以避免从Request.GetOwinContext()获取UserManager并使用构造函数来执行此操作,但是没有运气.我在做什么错了?

I followed a guide (https://simpleinjector.codeplex.com/discussions/564822) to avoid getting the UserManager from the Request.GetOwinContext() and doing it using the constructor but without luck. What am I doing wrong?

启动:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ...
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(httpConfig);

        DependencyConfig.InjectDependencies(app);
    }
 }

AuthController:

AuthController:

[RoutePrefix("api/auth")]
public class AuthController : ApiController
{
    readonly private AppUserManager _appUserManager;

    public AuthController(AppUserManager appUserManager)
    {
        _appUserManager = appUserManager;
    }
}

DependencyConfig:

DependencyConfig:

public class DependencyConfig
{
    public static void InjectDependencies(IAppBuilder app)
    {
        var container = new Container();
        container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

        container.Register<AppDbContext>(Lifestyle.Scoped);
        container.Register<IUserStore<AppUser>>(() => new UserStore<AppUser>(container.GetInstance<AppDbContext>()), Lifestyle.Scoped);
        container.Register<AppUserManager>(Lifestyle.Scoped);

        // other service injections

        container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
        container.Verify();
        GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);

        app.CreatePerOwinContext(() => container.GetInstance<AppUserManager>());
    }
}

推荐答案

查看您的代码:

Startup.cs

app.UseWebApi(httpConfig);

DependencyConfig

container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
container.Verify();
GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);

对我来说似乎很清楚,您在Web Api配置和SimpleInjector注册上都没有使用相同的HttpConfiguration实例.

Seems clear to me that you are not using the same HttpConfiguration instance for both the Web Api configuration and SimpleInjector registration.

请注意,GlobalConfiguration.Configuration!= httpConfig(除非您已手动分配var httpConfig = GlobalConfiguration.Configuration).

Please note that GlobalConfiguration.Configuration != httpConfig (except if you have manually assigned var httpConfig = GlobalConfiguration.Configuration).

这样,您的Web API中间件将不了解SimpleInjector,并将使用其默认实现.因此,创建控制器将失败.

This way your Web API middleware has no knowledge of SimpleInjector, and will use its default implementation. Because of this the creation of your controller will fail.

对于Web Api和SimpleInjector注册,请使用相同的HttpConfiguration:

Please use the same HttpConfiguration for both Web Api and SimpleInjector registration:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        //...
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(httpConfig);

        DependencyConfig.InjectDependencies(app, httpConfig);
    }
 }

public class DependencyConfig
{
    public static void InjectDependencies(IAppBuilder app, HttpConfiguration config)
    {
        // ...
        container.RegisterWebApiControllers(config);
        container.Verify();
        config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
        // ...
    }
}

此外,您只需要为控制器提供一个单一的构造函数,就可以将要注入的每个参数都放入其中(删除无参数构造函数).

Also, you need to provide just a single constructor for your controller, with every parameter you want to be injected inside it (remove the parameterless constructor).

在使用此行时,我会非常小心:

I would be very careful in using this line:

app.CreatePerOwinContext(() => container.GetInstance<AppUserManager>());

您正在Owin中请求一个LifeStyle.Scoped类型的实例,但是您将默认范围声明为WebApiRequestLifestyle.这种生活方式继承自 ExecutionContextScopeLifestyle 但是作用域本身仅在Web Api请求开始时才开始,因此我相信它不会出现在Web API外部执行的任何中间件中(也许Steven可以帮助我们阐明这一点).

You are requesting an instance of a LifeStyle.Scoped type inside Owin, but you declared the default scope as WebApiRequestLifestyle. This life-style inherits from ExecutionContextScopeLifestyle but the scope itself begins only on the start of a Web Api request, and thus I believe it will not be present in any middleware executed outside of Web API (maybe Steven could help us clarify this matter).

您可以考虑使用WebRequestLifestyle,但请注意async/await可能存在的问题.

这篇关于使用Owin和Simple Injector进行UserManager依赖项注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆