【问题标题】:Understanding Autofac middleware usage with ASP.NET Webforms, OWIN and ASP.NET Identity了解 Autofac 中间件与 ASP.NET Webforms、OWIN 和 ASP.NET Identity 的使用
【发布时间】:2017-03-07 03:18:57
【问题描述】:

我目前正在更新使用 MembershipProvider 和 RoleProvider 的旧 ASP.NET Webforms 应用程序,以使用较新的 ASP.NET Identity 类。此外,我使用 Autofac 进行依赖注入,并且为了保持一致性,我希望能够将它与新的 Identity 类一起使用。

ASP.NET Identity 现在依赖于 OWIN 中间件,通过添加以下 Startup.cs 类,我已经成功地将 OWIN 中间件设置合并到我的应用程序中:

internal partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var builder = new ContainerBuilder();

        AutofacConfig.RegisterTypes(builder);
        AutofacConfig.RegisterIdentityTypes(builder, app);

        var container = builder.Build();
        Global.SetContainer(container);

        app.UseAutofacMiddleware(container);

        ConfigureAuth(app);
    }
}

我像这样使用 Autofac 注册身份类:

internal static class AutofacConfig
{      
    public static void RegisterIdentityTypes(ContainerBuilder builder, IAppBuilder app)
    {
        builder.RegisterType<ApplicationUserStore>().As<IUserStore<ApplicationUser>>().InstancePerRequest();
        builder.RegisterType<ApplicationUserManager>().AsSelf().InstancePerRequest();
        builder.RegisterType<ApplicationSignInManager>().AsSelf().InstancePerRequest();
        builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).InstancePerRequest();
        builder.Register(c => app.GetDataProtectionProvider()).InstancePerRequest();
    }
}

当我导航到我的 WebForms 登录页面时,我可以看到以下 ApplicationSignInManager 类被实例化,并且它的构造函数参数也被解析,这表明 Autofac 工作正常。

public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
    public ApplicationSignInManager(
        ApplicationUserManager userManager,
        IAuthenticationManager authenticationManager)
        : base(userManager, authenticationManager)
    {
        // userManager is valid
        // authenticationManager is valid
    }
}

当我单击 WebForms 登录页面上的登录按钮时,将调用以下方法,并通过 Autofac 属性注入实例化 ApplicationSignInManager。然后调用正确的 Identity 类实现。

public partial class SignIn : BasePage
{
    // Autofac property injection 
    public ApplicationSignInManager ApplicationSignInManager { get; set; }

    ....

    protected void SignInClick(object sender, EventArgs e)
    {
        // Validate the user password
        var result = this.ApplicationSignInManager.PasswordSignIn(
            this.email.Text,
            this.password.Text,
            this.remember.Checked,
            true);

        ....
     }

所以一切似乎都很好,但我觉得有些不对劲,我看不到 OWIN 和 Autofac 的连接位置,甚至不需要。如果我从 Startup.cs 中删除以下行...

    app.UseAutofacMiddleware(container);

...一切仍然正常运行!哪一个不对,不是吗?

许多 MVC 示例似乎表明这是获取 Identity 对象的正确方法(通过 GetOwinContext() 调用):

    protected void SignInClick(object sender, EventArgs e)
    {
        var signInManager = this.Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();

        // Validate the user password
        var result = signInManager.PasswordSignIn(
            this.email.Text,
            this.password.Text,
            this.remember.Checked,
            true);

        ....
    }

但在执行该代码时,“signInManager”变量始终为 NULL。

我真的需要这行代码吗?

 app.UseAutofacMiddleware(container);

谁能指出我正确的方向?

【问题讨论】:

    标签: c# webforms owin autofac asp.net-identity-2


    【解决方案1】:

    我知道这对游戏来说已经很晚了,但我正在更新旧版应用程序并遇到 “IAppBuilder 不包含 'UseAutofacMiddleware' 的定义” 错误并通过添加 NuGet 包 Autofac.Owin 修复它。

    【讨论】:

      【解决方案2】:

      Documentation 声明

      对于一个简单的场景,app.UseAutofacMiddleware(container);将处理向 OWIN 请求范围添加 Autofac 生命周期以及将使用 Autofac 注册的中间件添加到管道中。

      请参阅source 进行确认。

      基本上,如果您将 Autofac 中的任何内容注入 OWIN 管道(即中间件),则需要此行。但是对于您的场景,看起来您并没有做任何类似的事情,因此删除该行不会改变您的任何事情。

      至于从 OWIN 管道解析对象,您实际上并不需要这样做 - 您已经从 Autofac 解析对象。但是,SecurityStampValidator 仍然从 OWIN 解析 ApplicationUserManager,因此您仍然需要向 OWIN 注册它:

      app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
      

      请参阅this question/answer 了解其背后的原因。

      【讨论】:

      • 好的,这对我来说有点道理。然后我应该做的是测试我的 OWIN 中间件语言模块是否有 app.UseAutofacMiddleware() 调用。它使用带有 Autofac 的 OWIN 中间件层根据站点所需的语言来切换线程文化。我应该看到没有那条线它会失败。今晚我会测试!谢谢你的澄清。
      • 只是我之前的评论。所以我注释掉了那行,我的中间件仍然可以正常工作。但是我现在明白了,因为我将 WebForms 与 Autofac 一起使用,并且我在 Global.asax.cs 文件中实现了 IContainerProviderAccessor,在我的中间件中,我访问了 Autofac 的 BeginLifetimeScope() 方法(通过我的 Global.asax.cs 类)来解决我的 DI 'd 对象。因此我不需要 app.UseAutofacMiddleware() 调用。
      • @Gareth 这很有意义。好东西,你已经深入了解了!
      猜你喜欢
      • 2023-03-07
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      • 2015-07-26
      • 2021-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多