I use Autofac as my IoC container of choice. The rest of this question refers to SignalR in conjunction with SignalR, but no real SignalR knowledge is needed to answer; this is a problem rooted in Autofac.
As part of using Autofac as the dependency resolver for SignalR, I want to provide my own IJsonSerializer instance configured how I like it. I don't, however, want to have that IJsonSerializer instance shared throughout the rest of the software.
To accomplish this, I created a new lifetime scope with the additional registration, and provided that scope to the dependency resolver. This is when my problems started.
What I didn't realize is by doing this, instance-per-lifetime-scope dependencies requested from SignalR which had previously been retrieved from the root container are now being requested from a lifetime scope, and thus are shared across the entirety of SignalR. This is not good. For example, short-lived database sessions are now shared for the lifetime of my application.
How can I cause my instance-per-lifetime-scope dependencies to basically pretend that the lifetime scope I pass to SignalR should not be used to cause those dependencies to be reused? Alternatively how can I avoid creating the lifetime scope altogether?
Question is a few months old but I thought I would share with you the method I used (perhaps someone can improve on it).
I added an event to my hub, to fire once the hub was disposing. (Actually through a base hub as I had some common logic already in place anyway)
public event Action OnDisposing;
protected override void Dispose(bool disposing)
{
if (OnDisposing != null) OnDisposing.Invoke();
}
With this in place I then modified how autofac registers this hub. When resolving, a new lifetime scope is created and the scope's dispose method is set to fire when the hub is disposed.
builder.Register(x =>
{
ILifetimeScope scope = x.Resolve<ILifetimeScope>().BeginLifetimeScope();
MyHub hub = new MyHub(scope.Resolve<IMyDependency>());
hub.OnDisposing += scope.Dispose;
return hub;
})
.As<MyHub>().InstancePerDependency();