2017-02-03 7 views
2

Ich habe gerade mit Autofac begonnen und versucht, Asp.Net Identity zu verkabeln, und ich versage. Ich dachte, ich hätte alles in Ordnung, aber ich blieb stecken und brauche eine Hand.Autofac, Auflösungsvorgang beendet

Der UserManager wird über den Konstruktor injiziert.

Meine UserController.cs hat Probleme, sobald ich diesen Async-Anruf erreiche.

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

Diese Auflöseoperation bereits beendet. Beim Registrieren von Komponenten mit Lambdas kann der Parameter IComponentContext 'c' für Lambda nicht gespeichert werden. Stattdessen lösen Sie entweder IComponentContext erneut von 'c', oder auflösen Sie eine Func <> basierte Factory, um nachfolgende Komponenten aus erstellen.

Das Problem ist, dass ich eine ziemlich klare Nachricht bekomme, aber ich weiß nicht, wie ich damit weitermachen soll; soll ich meinen ApplicationUserManager anders registrieren?

Ich habe meinen Container so eingerichtet. Ich hoffe, dass jemand einen Blick darauf werfen kann.

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

Antwort

2

Ich habe mein eigenes Problem gelöst, aber ehrlich gesagt ... Ich habe keine Ahnung, wie ich das behoben habe. Es war nur Versuch und Irrtum. Dies ist die neue Konfiguration. Der alte Teil ist kommentiert.

Es braucht nicht einmal das letzte Register in Owin Teil ... sogar kommentiert es scheint jetzt gut zu funktionieren.

// 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

Kann ich einen Vorschlag machen. Tauschen Sie 'InstancePerRequest' gegen' InstancePerLifetimeScope' aus. So sparen Sie sich eine Menge Kopfzerbrechen, wenn Sie außerhalb von Anfragen mit Bereichen arbeiten. [Dokumentation] (http://docs.autofac.org/en/latest/lifetime/instance-scope.html#instance-per-lifetime-scope) – Nico

+1

@Nico, danke, sehr guter Vorschlag. Ich habe gerade die Informationen darüber gelesen und die erwarteten Anmeldungen könnten für Kinder ablaufen. –