2015-10-30 78 views
1

当它们计划作为RecurringJob运行时,可以让Hangfire实例化具有配置JobActivator的对象吗?具有依赖注入的Hangfire RecurringJob

方法的签名似乎迫使仅限静态用法:

public static void AddOrUpdate<T>(
    string recurringJobId, 
    Expression<Action<T>> methodCall, 

我对如何我可以“滥用”静左右后置声道的事情了一些想法,但我觉得我可能失去了一些东西。有没有一个设计决定,hangfire只支持chron作业中的静态?

回答

1

快速回答为否,默认作业激活器仅适用于无参数构造函数或静态方法。我做了一些(在VB.net中)快速和肮脏,看看我能否得到它的工作,并显示在下面。

通过使用“AddOrUpdate”,您告诉Hangfire创建T的一个实例,然后访问T的方法,因此此签名对实例成员有效,而不是静态。如果使用没有泛型参数的其他“AddOrUpdate”方法签名之一,则需要静态方法。

现在有趣的部分:如果类型T没有无参数的默认构造函数,那么它会使用默认的jobactivator失败,如你所说。

这是您现在可以使用自定义jobactivator为您的任务的构造函数提供依赖关系的地方。如果您创建自己的继承自JobActivator的类,那么您可以为作业提供依赖关系。

这里是我的VB代码:

Imports Hangfire 
Imports System.Reflection 

Public Class JobActivationContainer 
    Inherits JobActivator 

    Private Property ParameterMap As Dictionary(Of Type, [Delegate]) 

    Private Function CompareParameterToMap(p As ParameterInfo) As Boolean 
     Dim result = ParameterMap.ContainsKey(p.ParameterType) 
     Return result 
    End Function 

    Public Overrides Function ActivateJob(jobType As Type) As Object 
     Dim candidateCtor As Reflection.ConstructorInfo = Nothing 
     'Loop through ctor's and find the most specific ctor where map has all types. 
     jobType. 
      GetConstructors. 
      ToList. 
      ForEach(
       Sub(i) 
        If i.GetParameters.ToList. 
         TrueForAll(AddressOf CompareParameterToMap) Then 
          If candidateCtor Is Nothing Then candidateCtor = i 
          If i IsNot candidateCtor AndAlso i.GetParameters.Count > candidateCtor.GetParameters.Count Then candidateCtor = i 
        End If 
       End Sub 
      ) 

      If candidateCtor Is Nothing Then 
       'If the ctor is null, use default activator. 
       Return MyBase.ActivateJob(jobType) 
      Else 
       'Create a list of the parameters in order and activate 
       Dim ctorParameters As New List(Of Object) 
       candidateCtor.GetParameters.ToList.ForEach(Sub(i)  ctorParameters.Add(ParameterMap(i.ParameterType).DynamicInvoke())) 
      Return Activator.CreateInstance(jobType, ctorParameters.ToArray) 
     End If 
    End Function 

    Public Sub RegisterDependency(Of T)(factory As Func(Of T)) 
     If Not ParameterMap.ContainsKey(GetType(T)) Then ParameterMap.Add(GetType(T), factory) 
    End Sub 

    Public Sub New() 
     ParameterMap = New Dictionary(Of Type, [Delegate]) 
    End Sub 
End Class 

我知道这并不回答关于如何“虐待”静力学的问题,但它确实表明你怎么可以滚你自己的迟发型IoC容器,或者按照手册使用已经支持的IoC之一:http://hangfirechinese.readthedocs.org/en/latest/background-methods/using-ioc-containers.html

注意:我打算使用合适的IoC,我上面的代码纯粹是学术的,需要很多工作!

6

不知道它何时被添加,但我只是在我当前的项目中做了类似的事情,它工作正常。 EmailBackgroundTask是一个非静态类,它是一种非静态方法。该类有4个依赖通过Hangfire.Unity DI包注入。

RecurringJob.AddOrUpdate<EmailBackgroundTask>(x=>x.SendPeriodicEmail(),Cron.MinuteInterval(5)); 
+0

我不确定接受的答案是否是这个问题的答案,但这应该是现在接受的答案。 – MasterN8