Is it possible to have Hangfire instantiate objects with the configure JobActivator when they're scheduled to run as a RecurringJob?
The signature of the method seems to force static only usages:
public static void AddOrUpdate<T>(
string recurringJobId,
Expression<Action<T>> methodCall,
I have several ideas on how i could "abuse" statics to back channel things around, but i feel like i might be missing something. Was there a design decision that hangfire only supports statics in chron jobs?
答案 0 :(得分:12)
不确定它何时被添加,但我刚刚在我当前的项目中做了类似的事情并且它工作正常。 EmailBackgroundTask是一个非静态类,这是一个非静态方法。该类有4个依赖项通过Hangfire.Unity DI包注入。
RecurringJob.AddOrUpdate<EmailBackgroundTask>(x=>x.SendPeriodicEmail(),Cron.MinuteInterval(5));
答案 1 :(得分:0)
快速回答是否定的,默认作业激活器仅适用于无参数构造函数或静态方法。我做了一些(在VB.net中)快速而肮脏的东西,看看我是否可以使它工作并在下面显示它。
通过使用&#34; AddOrUpdate&#34;,您告诉Hangfire创建T的实例,然后访问T的方法,因此此签名适用于实例成员,而不是静态。如果您使用其中一个&#34; AddOrUpdate&#34;如果方法签名没有泛型参数,则需要静态。
现在有趣的部分:如果类型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
我知道这并没有回答关于如何滥用&#34;的问题。静态,但它确实展示了你如何为自己的自动滚动你的IoC容器,或者根据手册使用已经支持的IoC容器之一:http://hangfirechinese.readthedocs.org/en/latest/background-methods/using-ioc-containers.html
注意:我打算使用合适的IoC,上面的代码纯粹是学术性的,需要做很多工作!