I am having following application :
1) Mvc app : Hangfire client from where i will just enqueue jobs and host
dashboard.This app will contains reference of my class library.
2) Console App : Hangfire server will live in this console application.
3) Class library : Shared library between hangfire server(Console app) and hangfire client(asp.net mvc) where my long running code will reside.Hangfire server
will execute code of this library.
I am having structure like below in Class library following strategy design pattern.
Code taken from following : Reference:
Interfaces:
public interface IOperation
{
Output Process(Input input);
bool AppliesTo(Type type);
}
public interface IOperationStrategy
{
Output Process(Type type,Input input);
}
Operations:
public class Add : IOperation
{
public bool AppliesTo(Type type)
{
return typeof(Add).Equals(type);
}
public Output Process(Input input)
{
// Implementation
return new Output();
}
}
public class Multiply : IOperation
{
public bool AppliesTo(Type type)
{
return typeof(Multiply).Equals(type);
}
public Output Process(Input input)
{
// Implementation
return new Output();
}
}
Strategy:
public class OperationStrategy : IOperationStrategy
{
private readonly IOperation[] operations;
public OperationStrategy(params IOperation[] operations)
{
if (operations == null)
throw new ArgumentNullException(nameof(operations));
this.operations = operations;
}
public Output Process(Type type, Input input)
{
var op = operations.FirstOrDefault(o => o.AppliesTo(type));
if (op == null)
throw new InvalidOperationException($"{operation} not registered.");
return op.Process(input);
}
}
Usage:
// Do this with your DI container in your composition
// root, and the instance would be created by injecting
// it somewhere.
var strategy = new OperationStrategy(
new Add(), // Inject any dependencies for operation here
new Multiply()); // Inject any dependencies for operation here
// And then once it is injected, you would simply do this.
var input = new Input { Value1 = 2, Value2 = 3 };
BackgroundJob.Enqueue(() => strategy.Process(typeof(Add), input));
But hangfire server is unable to pick job and when i check state table
,i get to see error like below :
"FailedAt": "2018-03-21T13:14:46.0172303Z", "ExceptionType":
"System.MissingMethodException", "ExceptionMessage": "No parameterless
constructor defined for this object.", "ExceptionDetails":
"System.MissingMethodException: No parameterless constructor defined
for this object.
at
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean
publicOnly, Boolean noCheck, Boolean& canBeCached,
RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at
System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean
skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at
System.Activator.CreateInstance(Type type, Boolean nonPublic)
at
System.Activator.CreateInstance(Type type)
at
Hangfire.JobActivator.SimpleJobActivatorScope.Resolve(Type type)
at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext
context)
at
Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_0.b__0()
at
Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter
filter, PerformingContext preContext, Func 1 continuation)
at
Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext
context, IEnumerable`1 filters)
at
Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext
context)
at
Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context,
IStorageConnection connection, String jobId)"
I am not getting what should be the hangfire set up for this structure as i dont have any IOC container involved here.
Can anybody please help me with this?
Demo project : https://www.dropbox.com/s/bfjr58y6azgmm3w/HFDemo.zip?dl=0
See Question&Answers more detail:
os