【问题标题】:Using Ninject to inject IJob from external assembly into Quartz.net scheduler使用 Ninject 将 IJob 从外部程序集注入 Quartz.net 调度程序
【发布时间】:2014-09-03 14:19:42
【问题描述】:

我正在尝试创建一个可以使用 Ninject 加载外部程序集并使用 Quartz.net 按计划运行它们的应用程序。

我已经成功地实现了 Quartz.net 来注入自身,并在同一个程序集中运行基于 IJob 实现的类的作业。这很好用。

我想更进一步,创建一个插件架构。

我创建了一个所有插件都会使用的通用接口IPlugin,这个接口也实现了IJob。这是在主应用程序中编译和引用的,每个插件都会实现它。

using Quartz;

namespace PluginFramework
{
    public interface IPlugin : IJob
    { }
}


然后我有一个实现 IPlugin 的测试插件。非常简单,它只是输出一个绿色的时间戳。

using System;
using PluginFramework;
using Quartz;

namespace TestPlugin
{
    public class Plugin : IPlugin
    {
        public void Execute(IJobExecutionContext context)
        {
            Start();
        }

        private void Start()
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(DateTime.Now + " - PLUGIN 1");
        }
    }
}


在我添加 Quartz.net 框架之前,我会像这样加载和执行插件。插件将加载、运行一次,然后应用程序将按预期结束。

var kernel = new StandardKernel();

var assemblies = Directory.GetFiles(@"E:\Plugins\", "*.dll");

foreach (var assembley in assemblies)
{
    kernel.Load(assembley);
}

var plugins = kernel.GetAll<IPlugin>();

foreach (var plugin in plugins)
{
    plugin.Execute();
}


现在我需要插件按计划运行,但它必须仍然通过 Ninject 加载,并且主应用程序应该保持与类型无关,它应该只知道它是一个 IJob 并能够运行它在某些配置中定义的时间表上。这是我遇到的问题。

我有我的 NinjectJobFactory

public class NinjectJobFactory : IJobFactory
{
    private IKernel Kernel { get; set; }

    public NinjectJobFactory(IKernel kernel)
    {
        Kernel = kernel;
    }

    public IJob NewJob(TriggerFiredBundle bundle)
    {
        return (IJob)Kernel.Get(bundle.JobDetail.JobType);
    }

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        return (IJob) Kernel.Get(bundle.JobDetail.JobType);
    }

    public void ReturnJob(IJob job)
    {

    }
}


我的工厂提供商和调度程序提供商。

public class QuartzSchedulerFactoryProvider : Provider<ISchedulerFactory>
{
    protected override ISchedulerFactory CreateInstance(IContext context)
    {
        var properties = new NameValueCollection();
        var section = (NameValueCollection)ConfigurationManager.GetSection("quartz");

        properties["quartz.scheduler.instanceName"] = section["quartz.scheduler.instanceName"];
        properties["quartz.threadPool.type"] = section["quartz.threadPool.type"];
        properties["quartz.threadPool.threadCount"] = section["quartz.threadPool.threadCount"];
        properties["quartz.threadPool.threadPriority"] = section["quartz.threadPool.threadPriority"];
        properties["quartz.jobStore.type"] = section["quartz.jobStore.type"];
        properties["quartz.plugin.xml.type"] = section["quartz.plugin.xml.type"];
        properties["quartz.plugin.xml.fileNames"] = section["quartz.plugin.xml.fileNames"];

        return new StdSchedulerFactory(properties);
    }
}


public class QuartzSchedulerProvider : Provider<IScheduler>
{
    private readonly IJobFactory _jobFactory;
    private readonly IEnumerable<ISchedulerListener> _listeners;
    private readonly ISchedulerFactory _schedulerFactory;

    public QuartzSchedulerProvider(
        ISchedulerFactory schedulerFactory,
        IJobFactory jobFactory,
        IEnumerable<ISchedulerListener> listeners)
    {
        _jobFactory = jobFactory;
        _listeners = listeners;
        _schedulerFactory = schedulerFactory;
    }

    protected override IScheduler CreateInstance(IContext context)
    {
        var scheduler = _schedulerFactory.GetScheduler();
        scheduler.JobFactory = _jobFactory;

        foreach (var listener in _listeners)
        {
            scheduler.ListenerManager.AddSchedulerListener(listener);
        }

        return scheduler;
    }
}

以及外部 XML 文件中的一些配置。

<schedule>
    <job>
        <name>Plugin1</name>
        <group>Plugins</group>
        <description></description>
        <job-type>TestPlugin.Plugin, TestPlugin</job-type>
        <durable>true</durable>
        <recover>false</recover>
    </job>

    <trigger>
        <simple>
            <name>Plugin1</name>
            <group>Plugins</group>
            <job-name>Plugin1</job-name>
            <job-group>Plugins</job-group>
            <misfire-instruction>SmartPolicy</misfire-instruction>
            <repeat-count>-1</repeat-count>
            <repeat-interval>1000</repeat-interval>
        </simple>
    </trigger>
</schedule>


基本上我不知道该怎么做。我已经根据我在谷歌/这里找到的东西尝试了一些东西,但没有任何帮助。任何建议将不胜感激。

【问题讨论】:

    标签: c# ninject quartz.net plugin-architecture external-assemblies


    【解决方案1】:

    如果您要通过 Ninject Look at bottom of the page 使用动态模块加载并在这些自定义插件程序集中设置您的模块(ninject 模块)以设置您的实现,它应该会自动执行您想要的操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多