Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在策略设计模式下,Hangfire服务器无法选择作业_C#_Asp.net Mvc_Strategy Pattern_Hangfire - Fatal编程技术网

C# 在策略设计模式下,Hangfire服务器无法选择作业

C# 在策略设计模式下,Hangfire服务器无法选择作业,c#,asp.net-mvc,strategy-pattern,hangfire,C#,Asp.net Mvc,Strategy Pattern,Hangfire,我有以下申请: 1) Mvc应用程序:Hangfire客户端,我将在那里将作业和主机排队 仪表板。此应用程序将包含对我的类库的引用 2) 控制台应用程序:Hangfire服务器将在此控制台应用程序中运行 3) 类库:hangfire服务器(控制台应用程序)和hangfire客户端(asp.net mvc)之间的共享库,我的长时间运行代码将驻留在这里。hangfire服务器 将执行此库的代码 我在类库中有如下结构: 代码取自以下内容: 接口: public interface IOperation

我有以下申请:

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

2) 控制台应用程序:Hangfire服务器将在此控制台应用程序中运行

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

我在类库中有如下结构:

代码取自以下内容:

接口:

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 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));
用法

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服务器无法选择作业,当我检查
状态表时,会看到如下错误:

“失败日期”:“2018-03-21T13:14:46.0172303Z”,“例外类型”: “System.MissingMethodException”、“ExceptionMessage”:“无参数” 为此对象定义的构造函数。“,“ExceptionDetails”: “System.MissingMethodException:未定义无参数构造函数 用于此对象。\r\n位于 System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔值 publicOnly、Boolean noCheck、Boolean&canBeCached、, RuntimeMethodHandleInternal&ctor,Boolean&bNeedSecurityCheck)\r\n位于 System.RuntimeType.CreateInstanceSlow(布尔publicOnly,布尔型 skipCheckThis,布尔填充缓存,堆栈爬网标记和堆栈标记)\r\n位于 System.Activator.CreateInstance(类型,布尔非公共)\r\n位于 System.Activator.CreateInstance(类型)\r\n位于 Hangfire.JobActivator.SimpleJobActivatorScope.Resolve(类型)\r\n 在Hangfire.Server.CoreBackgroundJobPerformer.Perform(PerformContext 上下文)\r\n位于 Hangfire.Server.BackgroundJobPerformer.c\u\u DisplayClass8\u 0.b\u 0()\r\n 在 Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(IServerFilter 筛选器,执行上下文预文本,函数1继续)\r\n位于 Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(PerformContext 上下文,IEnumerable`1筛选器)\r\n位于 Hangfire.Server.BackgroundJobPerformer.Perform(PerformContext 上下文)\r\n位于 Hangfire.Server.Worker.PerformJob(BackgroundProcessContext, IStorageConnection连接,字符串jobId)”

我没有得到什么应该是这个结构的壁炉设置,因为我没有任何国际奥委会集装箱涉及这里

有人能帮我吗


演示项目:

答案就在异常中

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

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

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

这将使您能够完全按照当前的方式使用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;}
}
公共类操作策略:IOperationStrategy
{
//无参数导体
公共运营战略()
{
操作=新列表();
}
公共操作策略(参数操作[]操作)
{
if(操作==null)
抛出新ArgumentNullException(nameof(operations));
操作=操作;
}
公共输出过程(类型、输入)
{
var op=Operations.FirstOrDefault(o=>o.AppliesTo(type));
if(op==null)
抛出新的InvalidOperationException($“{operation}未注册”);
返回操作流程(输入);
}
//属性-这可以由Hangfire反序列化
公共列表操作{get;set;}
}

此行抛出错误:var op=operations.FirstOrDefault(o=>o.AppliesTo(type));值不能为null。操作将作为null@User您是否尝试过
公共列表操作{get;set;}=new List()
?@jbl我没有按照你的建议尝试这个选项。让我试试,我会更新你。但是为什么要列出而不是数组?@用户请查看我在ctor中的编辑-init
Operations
,但重要的是使用正确的大小写(以前是
Operations
)当设置property@Alex现在我得到的操作计数为0,因此我得到异常:Type not registed