2017-02-03 43 views
2

我剛開始使用Autofac並試圖連接Asp.Net Identity,但我失敗了。我以爲我有一切工作,但我卡住了,需要一隻手。Autofac,解析操作已結束

UserManager通過構造函數注入。

private readonly ApplicationUserManager UserManager; 
     private readonly ApplicationSignInManager SignInManager; 
     public UserController(IDocumentSession documentSession, ApplicationUserManager userManager, ApplicationSignInManager signInManager) : base(documentSession) { 
      UserManager = userManager; 
      SignInManager = signInManager; 
     } 

當我到達這個異步調用時,我的UserController.cs出現問題。

var user = await UserManager.FindAsync(model.Email, model.Password); 

這解析操作已經結束。當使用lambdas註冊組件 時,無法存儲到lambda 的IComponentContext'c'參數。相反,要麼從 'c'再次解析IComponentContext,要麼解析基於工廠的Func <>以創建後續組件 。

問題是我得到一個非常明確的消息,但我不知道如何繼續它;我應該以不同的方式註冊我的ApplicationUserManager嗎?

我已經設置好我的容器。我希望有人可以看看。

public static void RegisterContainer(IAppBuilder app) 
     { 
      // Autofac container .. 
      var builder = new ContainerBuilder(); 

      // Register all MVC Controllers 
      builder.RegisterControllers(Assembly.GetExecutingAssembly()); 

      // Register all services that implement the Module interface 
      builder.RegisterAssemblyModules(BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray()); 

      // Register the DocumentStore instance 
      builder.Register(context => new RavenDocumentStoreFactory() 
       .FindOrCreate()) 
       .As<IDocumentStore>() 
       .SingleInstance(); 

      // Multi tenancy part  
      var tenantIdStrategy = new TenantIdStrategy(); 
      var multitenantContainer = new MultitenantContainer(tenantIdStrategy, builder.Build()); 
      var tenantIds = new[] 
      { 
       "subdomain1.tickets", 
       "localhost" 
      }; 

      foreach (var tenantId in tenantIds) 
      { 
       var databaseName = $"ticketTenant-{tenantId.Replace('.', '_')}"; 



       multitenantContainer.ConfigureTenant(tenantId, b => 
       { 
        // Init RavenDB 
        b.Register(context => new RavenDocumentSessionFactory(databaseName)) 
         .InstancePerTenant() 
         .AsSelf(); 

        // Session per request 
        b.Register(context => context.Resolve<RavenDocumentSessionFactory>() 
         .FindOrCreate(context.Resolve<IDocumentStore>())) 
         .As<IDocumentSession>() 
         .InstancePerRequest() 
         .OnRelease(x => 
         { 
          x.SaveChanges(); 
          x.Dispose(); 
         }); 

        // ASP.Net Identity Registrations 
        b.Register(context => new UserStore<User>(context.Resolve<IDocumentSession>)) 
         .AsImplemented‌​Interfaces() 
         .Instanc‌​ePerRequest() 
         .OnRelease(x => 
         { 
          x.Dispose(); 
         }); 

        b.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => 
         new IdentityFactoryOptions<ApplicationUserManager>() { 
          DataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionPr‌​ovider("ApplicationName") 
        }); 

        b.RegisterType<ApplicationUserManager>().AsSelf().Inst‌​ancePerRequest(); 
        b.RegisterType<ApplicationSignInManager>().AsSelf().InstancePerRequest(); 
        b.Register<IAuthenticationManager>(c => HttpContext.Current.GetOwinContext().Authentication).InstancePerRequest(); 
        b.Register<IDataProtectionProvider>(c => app.GetDataProtectionProvider()).InstancePerRequest(); 


       }); 
      } 

      // Register in Owin 
      app.UseAutofacMiddleware(multitenantContainer); 
      app.UseAutofacMvc(); 

      // Dependency Resolver to Autofac 
      DependencyResolver.SetResolver(new AutofacDependencyResolver(multitenantContainer)); 
     } 
    } 

回答

2

我解決了我自己的問題,但老實說...我沒有得知我是如何解決這個問題的。這只是試驗和錯誤。這是新的配置;舊的部分被評論。

它甚至不需要在歐文部分的最後一個註冊...甚至評論它現在似乎工作得很好。

// ASP.Net Identity Registrations 
        /* 
        b.Register(context => new UserStore<User>(context.Resolve<IDocumentSession>)) 
         .AsImplemented‌​Interfaces() 
         .Instanc‌​ePerRequest() 
         .OnRelease(x => 
         { 
          x.Dispose(); 
         }); 

        b.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => 
         new IdentityFactoryOptions<ApplicationUserManager>() { 
          DataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionPr‌​ovider("ApplicationName") 
        }); 

        b.RegisterType<ApplicationUserManager>().AsSelf().Inst‌​ancePerRequest(); 
        b.RegisterType<ApplicationSignInManager>().AsSelf().InstancePerRequest(); 
        b.Register<IAuthenticationManager>(c => HttpContext.Current.GetOwinContext().Authentication).InstancePerRequest(); 
        b.Register<IDataProtectionProvider>(c => app.GetDataProtectionProvider()).InstancePerRequest(); 
        */ 

        b.Register(c => new UserStore<User>(c.Resolve<IDocumentSession>())).As<IUserStore<User>>().InstancePerRequest() 
         .OnRelease(x => 
         { 
          x.Dispose(); 
         }); 
        b.RegisterType<ApplicationUserManager>().InstancePerRequest(); 
        b.RegisterType<ApplicationSignInManager>().InstancePerRequest(); 
        b.Register<IAuthenticationManager>(c => HttpContext.Current.GetOwinContext().Authentication).InstancePerRequest(); 
        b.Register<IDataProtectionProvider>(c => app.GetDataProtectionProvider()).InstancePerRequest(); 
+0

我可以提出一個建議。將'InstancePerRequest'交換到'InstancePerLifetimeScope'時,當您開始處理請求之外的作用域時,這將爲您節省大量麻煩。 [文檔](http://docs.autofac.org/en/latest/lifetime/instance-scope.html#instance-per-lifetime-scope) – Nico

+1

@Nico,謝謝,非常好的建議。我剛剛閱讀了關於它的信息,並且預計註冊可能會過期給孩子。 –