2011-02-05 19 views
12

Czy ktoś ma doświadczenie w integracji autofac i Quartz.Net? Jeśli tak, to gdzie najlepiej kontrolować zarządzanie na całe życie - IJobFactory, w ramach egzaminu IJob, czy za pomocą detektorów zdarzeń?Autofac i Quartz.Net Integration


Teraz używam niestandardowego autofac IJobFactory do tworzenia IJob instancji, ale nie mam w łatwy sposób podłączyć się do ILifetimeScope w IJobFactory zapewnienia żadnych drogich zasobów, które są wstrzykiwane w IJob są oczyszczone. Fabryka zadań tworzy tylko egzemplarz zlecenia i zwraca go. Oto moje obecne pomysły (mam nadzieję, że są lepsze ...)

  • Wygląda jak większość integracje AutoFac jakoś owinąć ILifetimeScope wokół jednostki pracy tworzą. Oczywistym sposobem użycia metody brute force jest przekazanie ILifetimeScope do IJob i utworzenie metody ILifetimeScope dla dziecka i utworzenie tam zależności. Wydaje się to nieco zbyt bliskie wzorcowi lokalizatora usług, co z kolei wydaje się sprzeczne z duchem autofacu, ale może to być najbardziej oczywisty sposób zapewnienia właściwego obchodzenia się z zakresem.

  • Mogę podłączyć się do niektórych zdarzeń kwarcowych, aby obsłużyć różne fazy stosu wykonywania zadań i zarządzać tam zarządzaniem życiem. To prawdopodobnie byłaby o wiele więcej pracy, ale być może warta, gdyby uzyskać czystszy rozdział obaw.

  • Upewnić się, że IJob jest proste otoki wokół IServiceComponent typu, który będzie wykonać całą pracę, i poprosić go jako Owned<T> lub Func<Owned<T>>. Podoba mi się, jak to wydaje się bardziej wibrować z autofac, ale nie podoba mi się to, że nie jest to ściśle egzekwowalne dla wszystkich implementatorów IJob.

Odpowiedz

12

Nie wiedząc zbytnio Quartz.Net i IJob s, będę zaryzykować sugestię nadal.

Rozważmy następujące opakowania praca:

public class JobWrapper<T>: IJob where T:IJob 
{ 
    private Func<Owned<T>> _jobFactory; 

    public JobWrapper(Func<Owned<T>> jobFactory) 
    { 
     _jobFactory = jobFactory; 
    } 


    void IJob.Execute() 
    { 
     using (var ownedJob = _jobFactory()) 
     { 
      var theJob = ownedJob.Value; 
      theJob.Execute(); 
     } 
    } 
} 

otrzymuje następujące rejestracje:

builder.RegisterGeneric(typeof(JobWrapper<>)); 
builder.RegisterType<SomeJob>(); 

Fabryka praca mogła teraz rozwiązać ten Wrapper:

var job = _container.Resolve<JobWrapper<SomeJob>>(); 

Uwaga:lifetime scope będzie cre w ramach instancji ownedJob, która w tym przypadku jest typu Owned<SomeJob>. Wszelkie zależności wymagane przez SomeJob, czyli InstancePerLifetimeScope lub InstancePerDependency, zostaną utworzone i zniszczone wraz z instancją Owned.

+0

dzięki za poświęcenie czasu, aby odpowiedzieć. Podoba mi się ten pomysł, ponieważ jest to bardziej jednoznaczna wersja mojej trzeciej burzy mózgów w pierwotnym pytaniu.Ciągle mnie dręczy to to, że nie mam kontroli nad zasięgiem życia. Zasadniczo chciałbym uruchomić każdy IJob w swoim własnym "LifetimeScope", prawie jak odpowiednik wywołania usługi WCF. Kwarcowy "IJobFactory" niestety jest w dużym stopniu pożarem i zapomina o tym, co udało mi się powiedzieć, więc może być tak, że jeśli naprawdę chcę mieć wyraźne granice zasięgu, będę musiał zagłębić się w system słuchaczy kwarcu. –

+0

@dfaivre - poprawiłem błąd w moim kodzie, zapomniałem o części "ownedJob.Value". Być może moje intencje są teraz wyraźniejsze. –

+3

Nie wiedziałem, że Owned stworzył zakres; bardzo przydatne. Myślę, że jest to prawdopodobnie najprostsze podejście, bez głębokiego zanurzenia w stosie kwarcu. Prawdopodobnie zwiększę mój "IJobFactory", aby rzucić, jeśli zadanie nie jest typu 'JobWrapper <> (tak, żebym lepiej spał w nocy ...). Jeszcze raz dziękuję za wspaniały wgląd. –