Skip to content

Extension Registration

Mathew Charles edited this page Sep 10, 2015 · 17 revisions

Binding extensions register themselves with the JobHostConfiguration by getting the IExtensionRegistry service instance from the configuration (JobHostConfiguration is an IServiceProvider), and using that interface to register an IExtensionConfigProvider instance which is the entry point for allowing the extension to participate in the JobHost configuration process. The runtime will call the IExtensionConfigProvider at the right time during startup to allow it to register it's binding extensions.

Let's look at the TimerTrigger extension in this repository as an example to hopefully clarify things. This extension can be used by applications by pulling in the Extensions nuget package and adding a single line to their job host startup code:

    JobHostConfiguration config = new JobHostConfiguration();
    config.UseTimers();
    JobHost host = new JobHost(config);
    host.RunAndBlock();

Binding extensions register themselves using an extension method pattern. UseTimers is an extension method on JobHostConfiguration. You can see the implementation of that method here in the source. As described above, this method registers an IExtensionConfigProvider instance for the timers extension (TimersExtensionConfig).

Another common pattern with extensions is for them to define their own custom configuration type, to allow users to provide configuration settings the bindings will use at runtime. The extension method pattern lends itself well to this - the extension can define overrides that take the configuration object, and pass it through. The TimerTrigger and FileTrigger extensions in this repo both have an optional configuration that can be specified. Here's an example showing how the files extension allows it's root monitor path to be configured:

    JobHostConfiguration config = new JobHostConfiguration();
    FilesConfiguration filesConfig = new FilesConfiguration
    {
        RootPath = "c:\data\import"
    };
    config.UseFiles(filesConfig);

The configuration object can then be passed through to your IExtensionConfigProvider instance to be used at runtime.

The IExtensionConfigProvider instance that the configuration extension method registers is the next thing we should discuss. This is a simple interface to implement - there is a single Initialize method taking a context object. You can see the TimersExtensionConfig implementation here in the source:

    public void Initialize(ExtensionConfigContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        context.Config.RegisterBindingExtension(new TimerTriggerAttributeBindingProvider(_config));
    }

The extension method RegisterBindingExtension is being used, which facilitates interacting with the IExtensionRegistry. Using these extension methods, or the IExtensionRegistry interface directly, the extension config registers it's bindings (one or more). It will register ITriggerBindingProvider implementations for trigger bindings, and IBindingProvider implementations for non trigger bindings.

To understand binding providers and their responsibilities, see The Binding Process.