Hangfire background task to create content - LightInject Activator
Hi All,
So I'm hitting a bit of a block and I'm wondering if anyone here can help.
Scenario
Webhook end point is triggered when ever files are updated on an Azure blob storage
This action adds items into a db queue
Scheduled task (plan is to use hangfire) runs every hour to process this queue. The reason for this is updates need to be batched together and not processed as and when they come in.
Current setup
Webhook is receiving requests and putting items in the queue
Hangfire is installed and the reoccurring job is set up - However it fails on execution
This is my test job class:
public class MyTestJobClass : IMyTestJobClass
{
private readonly IUmbracoContextFactory contextFactory;
private readonly IProfilingLogger logger;
public MyTestJobClass(IUmbracoContextFactory contextFactory, IProfilingLogger logger)
{
this.contextFactory = contextFactory ?? throw new ArgumentNullException(nameof(contextFactory));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public void ScheduleJob()
{
BackgroundJob.Enqueue(() => DoJob(null));
}
public void DoJob(PerformContext context)
{
try
{
using (var umbracoContext = contextFactory.EnsureUmbracoContext())
{
foreach (var node in umbracoContext.UmbracoContext.Content.GetAtRoot())
{
System.Diagnostics.Debug.WriteLine("{0} - {1}", node.Id, node.Name);
}
}
}
catch (Exception ex)
{
logger.Error(GetType(), ex);
}
}
}
[RuntimeLevel(MinLevel = RuntimeLevel.Boot)]
public class HangfireStartup : IComposer
{
public void Compose(Composition composition)
{
UmbracoDefaultOwinStartup.MiddlewareConfigured += UmbracoDefaultOwinStartup_MiddlewareConfigured;
}
private void UmbracoDefaultOwinStartup_MiddlewareConfigured(object sender, OwinMiddlewareConfiguredEventArgs e)
{
StartHanfgire(e.AppBuilder);
}
private void StartHanfgire(IAppBuilder app)
{
//Configure Hangfire
var options = new SqlServerStorageOptions { PrepareSchemaIfNecessary = true, QueuePollInterval = TimeSpan.FromSeconds(30) };
const string defaultUmbracoConnectionName = Umbraco.Core.Constants.System.UmbracoConnectionName;
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings[defaultUmbracoConnectionName].ConnectionString;
GlobalConfiguration.Configuration.UseSqlServerStorage(connectionString, options)
.UseLightInjectActivator(Current.Factory.Concrete as LightInject.ServiceContainer);
//Give hangfire a URL and start the server
app.UseHangfireDashboard("/umbraco/hangfire", new DashboardOptions { AppPath = null, Authorization = new[] { new UmbracoHangfireAuthorizationFilter() } });
app.UseHangfireServer();
}
}
However, when the job is trying to active a null reference is being thrown:
System.NullReferenceException Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
at LightInject.Web.PerWebRequestScopeManager.GetOrAddScope() in
C:\projects\lightinject-web\build\tmp\Net46\Binary\LightInject.Web\LightInject.Web.cs:line 148
at LightInject.ScopeManager.BeginScope() in
C:\projects\lightinject\src\LightInject\LightInject.cs:line 6325
at Hangfire.LightInject.LightInjecterScope..ctor(ServiceContainer container)
at Hangfire.LightInject.LightInjectJobActivator.BeginScope()
at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context)
at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass9_0.<PerformJobWithFilters>b__0()
at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func`1 continuation)
at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable`1 filters)
at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context) at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)
My job class requires the LightInject DI to work because I want to (eventually) be injecting all the services I need for content creation. However, I believe that my current error is related to getting the LightInject DI to work.
I'm hoping I don't have to go down the route of creating my own LightInject service composer instance and re-registering all of the Umbraco services in order to achieve this, so any help/pointers from people would greatly help me.
Does anyone know what the risks/implications of doing the following are:
var serviceContainer = new LightInject.ServiceContainer();
foreach (var t in (Current.Factory.Concrete as LightInject.ServiceContainer).AvailableServices)
serviceContainer.Register(t);
serviceContainer.ScopeManagerProvider = new PerLogicalCallContextScopeManagerProvider();
GlobalConfiguration.Configuration.UseSqlServerStorage(connectionString, options)
.UseLightInjectActivator(serviceContainer);
Hangfire background task to create content - LightInject Activator
Hi All,
So I'm hitting a bit of a block and I'm wondering if anyone here can help.
Scenario
Current setup
This is my test job class:
Hangfire is configured using an approach based on this: https://github.com/guru-digital/umbraco-hangfire
In addition to this setup, hangfire is set up to use the LightInjectJobActivator extension https://github.com/sbosell/Hangfire.LightInject by doing the following in a composer:
However, when the job is trying to active a null reference is being thrown:
My job class requires the LightInject DI to work because I want to (eventually) be injecting all the services I need for content creation. However, I believe that my current error is related to getting the LightInject DI to work.
For reference I've been reading the following existing threads in an attempt to get my head around this as well: https://our.umbraco.com/forum/umbraco-8/95966-umbraco-8-and-hangfire https://cultiv.nl/blog/using-hangfire-for-scheduled-tasks-in-umbraco/ https://our.umbraco.com/forum/using-umbraco-and-getting-started/100156-umbracocontext-issues-in-hangfireservice-job-possible-dependency-injection
I'm hoping I don't have to go down the route of creating my own LightInject service composer instance and re-registering all of the Umbraco services in order to achieve this, so any help/pointers from people would greatly help me.
Thanks
Nik
I feel that this might be something to do with it: https://github.com/seesharper/LightInject/issues/383
And also that various components in Umbraco are dependent on a HTTP context.
Does anyone know what the risks/implications of doing the following are:
Further follow on:
Finally found a thread on here that seemed very similar to the issues I was having:
https://our.umbraco.com/forum/umbraco-8/96445-hangfire-dependency-injection
is working on a reply...
This forum is in read-only mode while we transition to the new forum.
You can continue this topic on the new forum by tapping the "Continue discussion" link below.