我在 startup.cs 中有以下配置,但我收到错误,尽管我已经安装了 Hangifre.Autofac
nuget 包并进行了配置。
No scope with a Tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.
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");
}
}
最佳答案
InstancePerBackgroundJob
使用 BackgroundJobScope
标签创建 Per Macthing Life Time
作用域。但是 Per Request
实例在另一个带有 Request
标签的生命周期范围内被解析。因此,当您尝试在 BackgroundJobScope
生命周期中解析 Per Request
对象时,它会出错。它说,你只能在 Request
生命周期内解决我,而不是在 root 或其他。因此,您应该使用 Per Life Time Scope
而不是 Per Request
。
所以这些 Per Life Time Scope
注册的对象将获得 parent 的生命周期。如果它是单例,他们将成为根。如果他们的父生命周期是请求的,他们将生活在这个请求范围内。 InstancePerBackgroundJob
也是一样,它们将存在于 BackgroundJobScope
生命周期范围内。
如果背景对象使用请求生命周期范围,那么背景对象有另一个生命周期范围是有好处的,您的对象可以在请求完成时被释放。此外,如果它们在根范围内,它们将永远不会被释放。
关于c# - 在 WebApi 中使用 Autofac 进行 Hangfire,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35534860/