【问题标题】:Autofac, resolve operation endedAutofac,解析操作结束
【发布时间】:2017-06-21 09:12:50
【问题描述】:

我刚开始使用 Autofac 并尝试连接 Asp.Net Identity,但我失败了。我以为我一切正常,但我卡住了,需要帮助。

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

此解析操作已结束。注册组件时 使用 lambda,将 IComponentContext 'c' 参数传递给 lambda 无法存储。相反,要么从 IComponentContext 再次解析 'c',或解析基于 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));
        }
    }

【问题讨论】:

    标签: c# model-view-controller asp.net-identity owin autofac


    【解决方案1】:

    我解决了自己的问题,但老实说......我不知道我是如何解决这个问题的。这只是反复试验。这是新配置;旧部分已注释。

    它甚至不需要 Owin 部分中的最后一个寄存器...甚至评论说它现在看起来工作得很好。

    //  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();
    

    【讨论】:

    • 我可以提一个建议吗?将 InstancePerRequest 交换为 InstancePerLifetimeScope 这将在您开始使用请求之外的范围时为您省去很多麻烦。 Documentation
    • @Nico,谢谢,非常好的建议。我刚刚阅读了有关它的信息,并且从未预料到儿童的注册可能会过期。
    猜你喜欢
    • 2019-04-02
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    相关资源
    最近更新 更多