2

In our project we are using aspnetzero template. This template allows a simple but abstracted usage of hangfire. Now we would like to add Hangfire.Console to our project which would allow us to write logs to hangfires dashboard.

In order to write a log statement to the dashboard console we have to access the PerformContext of the current running job. Unfortunately because of the abstraction in aspnetzero we can't inject the PerformContext as it would be planned by hangfire. What we do have access to is the hangfire namespace and all it's static objects.

Therefore my question: Is there a way to get the PerformContext by another way than passing null to the execution method?

What I have tried so far:

  • By using the IServerFilter interface a method OnPerforming should be called. But unfortunately this is not the case within aspnetzero background jobs.
  • I tried to overwrite/extend the given base class BackgroundJob< T > of aspnetzero but with no luck. Perhaps someone can give me a hint in this direction.
marco birchler
  • 1,566
  • 2
  • 21
  • 45

3 Answers3

2

I used JobFilterAttribute with a IServerFilter.

Example:

[AttributeUsage(AttributeTargets.Class)]
 public class HangFirePerformContextAttribute : JobFilterAttribute, IServerFilter
{
         private static PerformContext _Context;

        public static PerformContext PerformContext
        {
            get
            {
                return new PerformContext(_Context);
            }
        }
        public void OnPerformed(PerformedContext filterContext)
        {
            Context = (PerformContext)filterContext;
            _Context = Context;
        }
        public void OnPerforming(PerformingContext filterContext)
        {
            Context = (PerformContext)filterContext;
            _Context = Context;
        }
}

And I create a new Class AsyncBackgroundJobHangFire<TArgs> : AsyncBackgroundJob<TArgs>

Exemple:

    [HangFirePerformContext]
    public abstract class AsyncBackgroundJobHangFire<TArgs> : AsyncBackgroundJob<TArgs>
    {
        public PerformContext Context { get; set; }

        protected async override Task ExecuteAsync(TArgs args)
        {
            Context = HangFirePerformContextAttribute.PerformContext;
            await ExecuteAsync(args, Context);
        }

        protected abstract Task ExecuteAsync(TArgs args, PerformContext context);
    }

It´s Work

In a Class of job i use a AsyncBackgroundJobHangFire

And de method is

        [UnitOfWork]
        protected override async Task ExecuteAsync(string args, PerformContext context)
        {
        }
  • 2
    Just to add to this, you can get it to run on every job by putting this somewhere near your hangfire startup/config (on .NET framework at least!) `GlobalConfiguration.Configuration.UseFilter(new HangFirePerformContextAttribute());` – tristankoffee Sep 10 '21 at 09:24
0

I have suffered using abp's implementation of hangfire jobs as well. I don't know how to answer your question precisely, but I was able to access a PerformingContext by implementing an attribute that extends JobFilterAttribute and implements IClientFilter, IServerFilter, IElectStateFilter, IApplyStateFilter. The interfaces will depend on your requirements, but I was capable of accessing PerformingContext this way.

Vitor Durante
  • 950
  • 8
  • 25
  • 1
    This was posted as an answer, but it does not attempt to answer the question. It should possibly be a comment. – aaron Sep 05 '19 at 00:58
  • 2
    without a sample, it is not easy to reason about what you say. This is likely to be a comment instead of a real answer. – Junior Mayhé Jun 08 '20 at 16:09
0

You should never use a static field for that, even if marked with a ThreadStaticAttribute , please refer to this link for more details

https://discuss.hangfire.io/t/use-hangfire-job-id-in-the-code/2621/2

Mtaraby
  • 167
  • 1
  • 13