-
Notifications
You must be signed in to change notification settings - Fork 0
Thread Scoping
Autofac can enforce that objects bound to one thread will not satisfy the dependencies of a component bound to another thread. This is done using lifetime scopes:
var builder = new ContainerBuilder();
builder.RegisterType<MyThreadScopedComponent>()
.InstancePerLifetimeScope();
var container = builder.Build();
Then, each thread gets its own inner context:
void ThreadStart()
{
using (var threadLifetime = container.BeginLifetimeScope())
{
var thisThreadsInstance = threadLifetime.Resolve<MyThreadScopedComponent>();
}
}
Important: Given the multithreaded scenario, you must be very careful that the parent scope doesn't get disposed out from under the spawned thread. You can get into a bad situation where components can't be resolved if you spawn the thread and then dispose the parent scope.
Each thread executing through ThreadStart()
will then get its own instance of MyThreadScopedComponent
- which is essentially a "singleton" in the lifetime scope. Because scoped instances are never provided to outer scopes, it is easier to keep thread components separated.
You can inject a parent lifetime scope into the code that spawns the thread by taking an ILifetimeScope
parameter. Autofac knows to automatically inject the current lifetime scope and you can create a nested scope from that.
public class ThreadCreator
{
private ILifetimeScope _parentScope;
public ThreadCreator(ILifetimeScope parentScope)
{
this._parentScope = parentScope;
}
public void ThreadStart()
{
using (var threadLifetime = this._parentScope.BeginLifetimeScope())
{
var thisThreadsInstance = threadLifetime.Resolve<MyThreadScopedComponent>();
}
}
}
If you would like to enforce this even more heavily, use Tagged Contexts to associate the thread-scoped components with the inner lifetime (they'll still have dependencies from the factory/singleton components in the outer container injected.) The result of this approach looks something like:
http://autofac.googlecode.com/svn/site/threadedcontainers.png
The 'contexts' in the diagram are the containers created with BeginLifetimeScope()
.