1

假设我有一个对象的实例,由 Autofac 解析,如下所示:

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

现在我只有myService. 是否有任何 Autofac API 接收我的变量myService并将其处理掉(连同 Autofac 解决的所有依赖项)?

例如

// 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.

需要注意的几点:

  1. 我当然不能自己做myService.Dispose(),因为这不会处理 Autofac 注入的子依赖项(因为 Autofac 正在控制它们的生命周期)。
  2. 我只有myService和我在一起。这是我正在处理的图书馆的特殊性质。我当然可以scope自己存储变量并管理它。那将是我最后的手段。只是想知道 Autofac 是否内置了一些东西。
4

2 回答 2

3

该服务与解析它的范围相关联。当您解析范围时,Autofac将负责处理需要处理的服务。

您应该创建生命周期范围并处理它们,而不是直接从容器中解析

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 

您也可以使用Owned<T>它作为一个非常轻的范围,并且可以轻松解决。

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

当然,Autofac 将只处理所需的资源。如果服务已注册,因为SingleInstance它不会在需要它的生命周期结束时处理它。

于 2019-12-21T17:51:13.580 回答
3

Autofac 没有内置方法来处理来自某些根服务的依赖树;它只能处理在生命周期范围内解决的所有内容。

您需要将示波器存储在某个地方,以便以后处理它。如果您无法传递除服务之外的任何内容,并且您的范围仅包含服务的依赖项,那么您可以想象注入ILifetimeScope您的服务构造函数,以便服务可以持有对范围的引用。

Dispose然后,在服务的方法中处理注入的作用域本身。为了防止您的服务在您这样做时也被 Autofac 处理,您应该将其注册为ExternallyOwned

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

我不喜欢它,但是如果您无法跟踪服务之外的范围,我不确定另一种方式。

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();
     }
   }
}
于 2019-12-21T17:57:10.797 回答