2016-10-25 21 views
1

我当前正在更新使用MembershipProvider和RoleProvider的旧ASP.NET ASP.NET Webforms应用程序,以使用更新的ASP.NET标识类。此外,我使用Autofac进行依赖注入,为了保持一致性,我希望能够将它与新的Identity类一起使用。了解使用ASP.NET Webforms,OWIN和ASP.NET标识的Autofac中间件使用情况

ASP.NET身份现在依靠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按键实拍在页面下面的方法被调用和ApplicationSignInManager通过Autofac财产注入实例化。然后调用正确的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许多例子似乎在暗示这是正确的方式来获得标识对象(通过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); 

任何人都可以指向正确的方向吗?

回答

3

Documentation指出

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

请参阅source来确认。

基本上,如果你是从Autofac注入任何东西到OWIN管道(即中间件),你需要这条线。但是对于你的情况,它看起来并不像你做的那样,所以删除该行并不会改变任何东西。

至于从OWIN管道中解析对象,你并不需要这么做 - 你已经从Autofac解析对象。然而,SecurityStampValidator仍然解决ApplicationUserManager从OWIN,所以你仍然需要OWIN注册它:

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

它背后的原因见this question/answer

+0

好的,这对我来说很有意义。然后我应该做些什么来测试,检查我的OWIN中间件语言模块是否带有app.UseAutofacMiddleware()调用。它使用带有Autofac的OWIN中间件层根据网站所需的语言切换线索文化。我应该看到没有这条线就会失败。我今晚会测试!谢谢你的澄清。 – Gareth

+1

更进一步,我以前的评论。所以我评论说,该行和我的中间件仍然可以正常工作。但是现在我明白了,因为我在Autofac中使用WebForms,并且在Global.asax.cs文件中实现了IContainerProviderAccessor,在我的中间件中,我访问Autofac的BeginLifetimeScope()方法(通过Global.asax.cs类)来解析我的DI '物体。 因此我不需要app.UseAutofacMiddleware()调用。 – Gareth

+0

@Gareth有道理。好的东西,你下到它的底部! – trailmax