1

Say I have an instance of an object, resolved by Autofac like this:

ILifetimeScope scope = rootContainer....
var myService = scope.Resolve(myServiceType);

Now all I have with me is myService. Is there any Autofac API which takes in my variable myService and disposes it off (along with all its dependencies that Autofac resolved) ?

For e.g.

// later at some point, something like this
rootContainer.DisposeOff(myService) // <-- this should dispose the lifetime scope of myService, i.e. dispose myService, along with its other dependencies.

Few points to note:

  1. I cant of course just do myService.Dispose() myself because that won't dispose its child dependencies that Autofac injected (because Autofac is controlling their lifetimes).
  2. I only have myService with me. It's the peculiar nature of the library I am dealing with. I can of course store the scope variable myself and manage it. That would be my last resort. Just wondering if Autofac has something built into itself.
nawfal
  • 70,104
  • 56
  • 326
  • 368

2 Answers2

4

The service is associated to the scope from where it has been resolved. when you resolve the scope, Autofac will take care of disposing service that need to be disposed.

Instead of resolving straight from the container, you should create life time scope and dispose of them

using(var scope = rootContainer.BeginLifetimeScope())
{
    IService service = scope.Resolve<IService>(); 

    // do whatever you want 
} // service will be disposed here, at the end of the lifetime scope 

You can also use Owned<T> which will work as a very light scope and can be resolve easily.

using(Owned<IService> ownedService = scope.Resolve<Owned<Iservice>>())
{
    IService service = ownedService.Value; 
    // do whatever you want
}

Of course, Autofac will take care of disposing only the needed ressource. If a service is registered as SingleInstance it won't dispose it at the end of the lifetime that need it.

Cyril Durand
  • 15,834
  • 5
  • 54
  • 62
  • Cyril, I can't enclose in `using` because that will immediately dispose the IService. In my case it will be longer lived. I get an event raised from external library when they are done with the IService instance. – nawfal Dec 23 '19 at 06:16
3

Autofac doesn't have a built-in method that will dispose of a tree of dependencies from some root service; it can only dispose of everything resolved within the lifetime scope.

You'll need to store the scope somewhere so you can dispose of it later. If you aren't able to pass around anything except your service, and your scope only contains the dependencies of your service, then you could conceivably inject ILifetimeScope in your service constructor, so the service can hold a reference to the scope.

Then, dispose of the injected scope itself in the service's Dispose method. To prevent your service being disposed by Autofac as well when you do that, you should register it as ExternallyOwned:

containerBuilder.RegisterType<MyService>().ExternallyOwned();

I don't love it, but if you can't track the scope outside the service, I'm not sure of another way.

class MyService : IDisposable
{
   private ILifetimeScope _scope;
   public MyService(ILifetimeScope scope)
   { 
      _scope = scope;
   }

   public void Dispose()
   {
     if(_scope is object)
     { 
        var localScope = _scope;
        _scope = null;
        localScope.Dispose();
     }
   }
}
Alistair Evans
  • 36,057
  • 7
  • 42
  • 54