Should it throw an exception, pass resolution to its parent or something else?
My favorite container Autofac raises an exception – which is the only thing I don’t like about it.
I think that it should pass resolution to its parent which should resolve my issue with this code
class LazyClass
{
public void DoSomething() { }
}
class SomeClass
{
public event EventHandler WatchOut = (s, ea) => { };
public void Start()
{
WatchOut(this, EventArgs.Empty);
}
}
class LazyInterceptor
{
Lazy<LazyClass> lazy;
public LazyInterceptor(Lazy<LazyClass> lazy)
{
this.lazy = lazy;
}
public void Register(SomeClass some)
{
some.WatchOut += (s, ea) => lazy.Value.DoSomething();
}
}
[TestMethod]
public void LazyAndEvents()
{
var builder = new ContainerBuilder();
builder.RegisterType<LazyClass>().SingleInstance();
var container = builder.Build();
var someClass = new SomeClass();
using (var inner = container.BeginLifetimeScope(cb =>
cb.RegisterType().SingleInstance()))
{
var interceptor = inner.Resolve();
interceptor.Register(someClass);
}
someClass.Start();
}
I know of three workarounds around this, but they all seem just wrong
- not disposing container – this is what I currently do, but that’s just to make Autofac happy
- explicitly registering lazy – seems just wrong and I don’t even know what will be resolved
- taking ownership for dispose – it doesn’t seem as bad, but I don’t use object in that way, so again it looks like a workaround. Also, in Autofac it introduces dependency which is not nice
The whole point of lifetime scopes is that to control the lifetime of the contained instances. Building on the Disposable pattern, disposing the container is a clean and well-established way of releasing the resources governed by that container. Thus, when a lifetime scope is disposed you should no longer depend on instances resolved from that lifetime scope.
So I would say that you are definitively using Autofac the wrong way here. Perhaps if you explained why you want to use the scope like that, we could figure out the proper usage.