Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C#, Autofac, Quartz.net] Controle over lifetime bij quartz

Pagina: 1
Acties:

  • defiant
  • Registratie: Juli 2000
  • Laatst online: 23:08

defiant

Moderator General Chat
Topicstarter
Ik ben bezig met een hobby projectje met quartz.net en ik gebruik hierbij Autofac als IoC framework. Autofac heeft een mooie feature lifetimescope waarmee je controle kan krijgen over levensduur van objecten waarmee je bijvoorbeeld makkelijk een unit-of-work kan afbakenen. Echter loop ik tegen een probleem aan als ik die mogelijkheid wil integreren in quartz.net

Zonder controle over de levensduur is de oplossing makkelijk, de jobfactory van quartz resolved hier via autofac het type van de job:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    public class AutofacJobFactory : IJobFactory
    {
        private readonly ILifetimeScope _container;

        public AutofacJobFactory(ILifetimeScope container)
        {
            _container = container;
        }

        public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
        {
             Type jobtype = bundle.JobDetail.JobType;
             var job = (IJob)_container.Resolve(jobtype);
             return job;
        }

        public void ReturnJob(IJob job)
        {
 
        }
    }

(Misschien handig voor een mogelijke oplossing later is te weten dat als de job klaar is, hij via ReturnJob(IJob job) terugkomt).

Echter ontstaat een probleem als ik de job in een nieuwe lifetimescope wil afhandelen:
C#:
1
2
3
4
5
6
7
 public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
 {
      Type jobtype = bundle.JobDetail.JobType;
      ILifetimeScope newJobLifetimeSope = _container.BeginLifetimeScope();
      var job = (IJob)newJobLifetimeSope.Resolve(jobtype);
      return job;
 }

Ik krijg nu wel een nieuwe lifetimescope, maar de referentie er naar toe ben ik kwijt zodra de job wordt gereturned. Een autofac lifetimescope moet namelijk altijd disposed worden (het staat meestal in een using block).

Op stackoverflow stond opzich een slimme oplossing, zie:
Autofac and Quartz.Net Integration

Er wordt daar een wrapper om de quartz.net IJob heengezet, met een Autofac Owned<T> construct, die afdwingt dat de levensduur van objecten zich beperkt tot de executie van de quartz job.

Echter werkt die oplossing alleen als je van te voren al weet welke type quartz job er wordt opgevraagd, aangezien de jobwrapper dat afdwingt:
C#:
1
public class JobWrapper<T>: IJob where T:IJob

De functie NewJob in de jobfactory van quartz geeft echter alleen het Type terug..

Een andere oplossing is om de in de Job het volgende te doen:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    public class SampleJob : IJob
    {
        private readonly ILifetimeScope _container;

        public SampleJob(ILifetimeScope container)
        {
            _container = container;
        }

        public void Execute(IJobExecutionContext context)
        {
            using (var scope = _container.BeginLifetimeScope())
            {
                var implementation = scope.Resolve<MySampleJobImplementation>();
                implementation.Execute();
            }
        }
    }

Maar dat vind ik toch geen mooie oplossing, aangezien je dit toch het liefst in de jobfactory wilt afhandelen.
Een andere oplossing is de scope zelf ergens bewaren in een dictionary oid of toe te voegen aan de jobcontext, maar ook dat lijkt me meer een hack.

Samengevat: Ik wil een lifetimescope van autofac kunnen beëindigen terwijl ik de referentie naar die scope kwijt raak, is hier voor een elegante oplossing die ik misschien mis ?

"When I am weaker than you I ask you for freedom because that is according to your principles; when I am stronger than you I take away your freedom because that is according to my principles"- Frank Herbert


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je kan toch gewoon iets van een lijst/dictionary binnen je factory bijhouden. Bij de ReturnJob zoek je dan de lifetimescope er weer bij en dispose je die.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • defiant
  • Registratie: Juli 2000
  • Laatst online: 23:08

defiant

Moderator General Chat
Topicstarter
Klopt, alleen had ik gehoopt dat er misschien een betere oplossing was (bijv binnen Autofac, zoals de mogelijkheid om een instance van een lifetimescope op te vragen). Het lijkt er inderdaad op dat het zelf bijhouden het beste is onder de omstandigheden.

"When I am weaker than you I ask you for freedom because that is according to your principles; when I am stronger than you I take away your freedom because that is according to my principles"- Frank Herbert