繁体   English   中英

使用Owin和Simple Injector进行UserManager依赖项注入

[英]UserManager dependency injection with Owin and Simple Injector

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

没有无参数构造函数时出错:

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

无参数构造函数出错:

为了使容器能够创建AuthController,它应该只有一个公共构造函数:它有2个。

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

启动:

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

        DependencyConfig.InjectDependencies(app);
    }
 }

AuthController:

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

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

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实例。

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

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

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

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);
        // ...
    }
}

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


关于app.CreatePerOwinContext

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM