Hi Paul,
ISharingLifetimeScope has ParentLifetimeScope and RootLifetimeScope properties - it is the interface used internally when searching for an appropriate scope up the "tree".
To make it slightly more palatable you might add:
builder.Register(c => (ISharingLifetimeScope)c.Resolve<ILifetimeScope>())
.As<ISharingLifetimeScope>()
.ExternallyOwned();
...so that the container provides it (we don't by default, because it encourages hacks like the above, keep reading... :))
A better and cleaner way to do this is to create a SingleInstance() component that acts as a factory for your background tasks:
class BackgroundTaskFactory
{
public BackgroundTaskFactory(/* ILifetimeScope or a relationship type */) { }
public void StartTask(/* Action, or a task spec.. */) {
// Create a new lifetime to run the task in
}
}
Because you register BackgroundTaskFactory as single instance, the injected ILifetimeScope will be the root one, and you can create direct children off of it. If you take something more like Func<Owned<ITask>> then the owned instances will be in child scopes of the root automatically.
Request-level components that take a dependency on BackgroundTaskFactory will naturally get the same shared instance up at the root level.
I think the second option is better, first is included just in case you need to whack something together in a hurry :)
Hope this helps,
Nick