StructureMap support for Hangfire. Provides an implementation of the JobActivator
class and plugin family expression extensions, allowing you to use StructureMap IoC container to resolve job type instances as well as control the lifetime of the related dependencies.
Hangfire.StructureMap is available as a NuGet Package. Type the following command into NuGet Package Manager Console window to install it:
Install-Package Hangfire.StructureMap4
The package provides an extension method for the IGlobalConfiguration
interface, so you can enable StructureMap integration using the GlobalConfiguration
class.
var container = new Container();
// container.Configure...
GlobalConfiguration.Configuration.UseStructureMapActivator(container);
After invoking the methods above, StructureMap-based implementation of the JobActivator
class will be used to resolve job type instances and all their dependencies during the background processing.
Sometimes it is necessary to re-use instances that are already created, such as database connection, unit of work, etc. Thanks to the ContainerLifecycle of StructureMap, you can simply use that lifecycle to identify objects managed by the nested container.
Hangfire.StructureMap does not rely on any specific lifecycle, but objects registered with ContainerLifecycle
will have a scope limited to the current background job processing. The simples way to register an object with the ContainerLifecycle
is to call the ContainerScoped
extension method in your create plugin family expression logic:
container.For<IDatabase>().ContainerScoped().Use<Database>();
Or on your expression instance:
container.For<IDatabase>().Use<Database>().ContainerScoped();
These are simply shortcuts to writing:
container.For<IDatabase>().LifecycleIs<ContainerLifecycle>().Use<Database>();
All the dependencies that implement the IDisposable
interface are disposed as soon as current background job is performed, but only when they were registered with the ContainerLifecycle
lifecycle. For other cases, please read about the object lifecycles.
For most typical cases, you can call the ContainerScoped
method on a job plugin family expression and implement the Dispose
method that will dispose all the dependencies manually:
public class JobClass : IDisposable
{
private readonly Dependency _dependency;
public JobClass(Dependency dependency) { /* ... */ }
public Dispose()
{
_dependency.Dispose();
}
}
container.For<JobClass>().ContainerScoped();
Services registered with HttpContextScoped()
directive or the HttpContextLifecycle
lifecycle will be unavailable during job activation, you should re-register these services without this hint.
HttpContext.Current
is also not available during the job performance. Don't use it!
This package takes advantage of nested containers. The StructureMapJobActivator
creates a nested container for the StructureMapDependencyScope
which is based on Hangfire's JobActivatorScope