gpt4 book ai didi

c# - 在策略设计模式的情况下,Hangfire 服务器无法选择工作

转载 作者:行者123 更新时间:2023-11-30 17:30:33 27 4
gpt4 key购买 nike

我有以下申请:

1) Mvc app : Hangfire 客户端,我将从那里排队作业和主机 仪表板。此应用程序将包含我的类库的引用。

2) Console App : Hangfire 服务器将存在于这个控制台应用程序中。

3) 类库:hangfire 服务器(控制台应用程序)和 hangfire 客户端(asp.net mvc)之间的共享库,我的长期运行代码将驻留在其中。Hangfire 服务器 将执行该库的代码。

我在类库中的结构如下 strategy design pattern.

代码取自:Reference:

接口(interface):

public interface IOperation
{
Output Process(Input input);
bool AppliesTo(Type type);
}

public interface IOperationStrategy
{
Output Process(Type type,Input input);
}

操作:

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();
}
}

策略:

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);
}
}

用法:

// 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));

但是 hangfire 服务器无法选择作业,当我检查 state table 时,我看到如下错误:

"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.\r\n at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)\r\n at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)\r\n at System.Activator.CreateInstance(Type type, Boolean nonPublic)\r\n at System.Activator.CreateInstance(Type type)\r\n at Hangfire.JobActivator.SimpleJobActivatorScope.Resolve(Type type)\r\n at Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext context)\r\n at Hangfire.Server.BackgroundJobPerformer.<>c__DisplayClass8_0.b__0()\r\n at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter filter, PerformingContext preContext, Func 1 continuation)\r\n at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext context, IEnumerable`1 filters)\r\n at Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext context)\r\n at Hangfire.Server.Worker.PerformJob(BackgroundProcessContext context, IStorageConnection connection, String jobId)"

我不知道应该为这个结构设置什么 hangfire,因为我这里没有涉及任何 IOC 容器。

有人可以帮我解决这个问题吗?

演示项目:https://www.dropbox.com/s/bfjr58y6azgmm3w/HFDemo.zip?dl=0

最佳答案

答案就在异常中

没有为此对象定义无参数构造函数。

您的 OperationStrategy 没有无参数构造函数,因此当 Hangfire 尝试创建此对象时,它不能 - 它通过反射来创建。Hangfire 无法访问您在安排作业时使用的实例,它会尝试重新创建它。这是它做不到的。

您可以添加一个无参数的构造函数,并使 Operations 成为一个公共(public)集合。

这将使您能够像当前一样使用您的 ctor,但也允许对象被序列化,由 Hangfire 存储,然后在它尝试运行时反序列化和创建。

public class OperationStrategy : IOperationStrategy
{
// paramaterless ctor
public OperationStrategy()
{
Operations = new List<Operation>();
}

public OperationStrategy(params IOperation[] operations)
{
if (operations == null)
throw new ArgumentNullException(nameof(operations));

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);
}

//property - this can be deserialized by Hangfire
public List<IOperation> Operations {get; set;}
}

关于c# - 在策略设计模式的情况下,Hangfire 服务器无法选择工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49514099/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com