【问题标题】:Hangfire With Autofac in WebApi在 WebApi 中使用 Autofac 的 Hangfire
【发布时间】:2016-02-21 10:17:30
【问题描述】:

我在 startup.cs 中有以下配置,但我收到了错误,尽管我已经安装了 Hangifre.Autofac nuget 包并进行了配置。

标签匹配“AutofacWebRequest”的范围不可见 请求实例的范围。这通常表明 注册为每个 HTTP 请求的组件正在被请求 一个 SingleInstance() 组件(或类似的场景。)在 web 下 集成总是从 DependencyResolver.Current 或 ILifetimeScopeProvider.RequestLifetime, 永远不要来自容器本身。

Startup.cs

 public void Configuration(IAppBuilder app)
        {

            var builder = new ContainerBuilder();


            //if (AppConfigHelper.PlatformEnvironment == PlatformEnvironment.LocalHost)
            builder.RegisterType<NLogLogger>().As<ILogger>().InstancePerLifetimeScope();
            //else
            //builder.RegisterType<SentryLogger>().As<ILogger>().InstancePerLifetimeScope();

            //builder.RegisterWebApiFilterProvider(configuration);

            // REGISTER CONTROLLERS SO DEPENDENCIES ARE CONSTRUCTOR INJECTED
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
            builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();

            //These lines warm up dlls and load into memory for automatic regisration
            var r = new ReplyRepository(null);
            var s = new BankService();

            builder.RegisterModule(new SelfRegisterModule());
            builder.RegisterModule(new RepositoryModule());
            builder.RegisterModule(new ServiceModule());
            builder.RegisterModule(new EFModule());


            builder
                   .RegisterType<ApplicationOAuthProvider>()
                   .As<IOAuthAuthorizationServerProvider>()
                   .PropertiesAutowired() // to automatically resolve IUserService
                   .SingleInstance(); // you only need one instance of this provider

            builder.RegisterType<SellutionUserStore>().As<IUserStore<ApplicationUser, int>>().InstancePerBackgroundJob().InstancePerRequest();
            builder.RegisterType<SellutionUserManager>().AsSelf().InstancePerBackgroundJob().InstancePerRequest();
            builder.RegisterType<SellutionRoleManager>().AsSelf().InstancePerBackgroundJob().InstancePerRequest();
            builder.RegisterType<SellutionSignInManager>().AsSelf().InstancePerBackgroundJob().InstancePerRequest();
            builder.Register<IAuthenticationManager>(c => HttpContext.Current.GetOwinContext().Authentication).InstancePerBackgroundJob().InstancePerRequest();
            builder.Register<IDataProtectionProvider>(c => app.GetDataProtectionProvider()).InstancePerBackgroundJob().InstancePerRequest();

            builder.RegisterType<TicketDataFormat>().As<ISecureDataFormat<AuthenticationTicket>>();

            builder.RegisterType<TicketSerializer>().As<IDataSerializer<AuthenticationTicket>>();
            builder.Register(c => new DpapiDataProtectionProvider("Sellution360").Create("ASP.NET Identity")).As<IDataProtector>();

            builder.RegisterType<CurrencyRatesJob>().AsSelf().InstancePerBackgroundJob();

            // BUILD THE CONTAINER
            var container = builder.Build();

            Hangfire.GlobalConfiguration.Configuration.UseAutofacActivator(container);
            JobActivator.Current = new AutofacJobActivator(container);


            // REPLACE THE MVC DEPENDENCY RESOLVER WITH AUTOFAC
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

            // Set the dependency resolver for Web API.
            var webApiResolver = new AutofacWebApiDependencyResolver(container);
            GlobalConfiguration.Configuration.DependencyResolver = webApiResolver;

            // Set the dependency resolver for MVC.
            var mvcResolver = new AutofacDependencyResolver(container);
            DependencyResolver.SetResolver(mvcResolver);


            // Register the Autofac middleware FIRST, then the Autofac MVC middleware.
            app.UseAutofacMiddleware(container);
            app.UseAutofacMvc().UseCors(CorsOptions.AllowAll);
            app.UseAutofacWebApi(GlobalConfiguration.Configuration).UseCors(CorsOptions.AllowAll); ;

            IocManager.Instance.IocContainer = container;

            ConfigureAuth(app);
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();

            Hangfire.GlobalConfiguration.Configuration.UseSqlServerStorage("DefaultConnection");
            app.UseHangfireDashboard();
            app.UseHangfireServer();

            RecurringJob.AddOrUpdate<CurrencyRatesJob>(j => j.Execute(), Cron.Minutely);
        }

CurrencyRatesJob.cs

 public class CurrencyRatesJob
    {
        private readonly ILogger _logger;
        private readonly IBusinessTypeService _businessTypeService;

        public CurrencyRatesJob(ILogger logger, IBusinessTypeService businessTypeService)
        {
            _logger = logger;
            _businessTypeService = businessTypeService;
        }

        public void Execute()
        {
            var types = _businessTypeService.GetBusinessTypes();
            _logger.Log("waqar");

        }
    }

【问题讨论】:

  • 那个问题也没有回答

标签: c# asp.net-web-api autofac hangfire hangfire-autofac


【解决方案1】:

InstancePerBackgroundJob 创建带有BackgroundJobScope 标签的Per Macthing Life Time 范围。但是Per Request 实例在另一个使用Request 标记的生命周期范围内解析。因此,当您尝试在 BackgroundJobScope 生命周期中解析 Per Request 对象时,它会出错。它说,你只能在 Request 生命周期内解决我,而不是在 root 或其他。所以你应该使用Per Life Time Scope 而不是Per Request

所以这些Per Life Time Scope 注册的对象将获得父母的生命周期。如果是单例,它们将位于根目录中。如果他们的父生命周期是请求,他们将使用这个请求范围。 InstancePerBackgroundJob 也是如此,他们将生活在 BackgroundJobScope 生命周期范围内。

如果后台对象使用请求生命周期范围,则可以在请求完成时释放您的对象,这对具有另一个生命周期范围是有益的。此外,如果它们在根范围内,它们将永远不会释放。

【讨论】:

  • 那么你认为使用这个不是好的做法是什么? InstancePerBackgroundJobgithub.com/HangfireIO/Hangfire.Autofac/blob/…
  • 我没有检查所有代码,但我可以看到InstancePerBackgroundJob 使用BackgroundJobScope 创建InstancePerMatchingLifeTimeScope 并管理该范围内的对象。这很好,因为请求生命周期范围可以在后台作业仍在进行时完成。我将编辑我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-02
  • 2019-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多