Autofac:仅使用已解析的实例处理对象实例及其依赖项?
Autofac: Dispose off object instance and its dependencies with just the resolved instance?
假设我有一个对象的实例,由 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.
注意几点:
- 我当然不能
myService.Dispose()
自己做,因为那样不会处理 Autofac 注入的子依赖项(因为 Autofac 正在控制它们的生命周期)。
- 我只有
myService
。这是我正在处理的图书馆的特殊性质。我当然可以自己存储 scope
变量并对其进行管理。那将是我最后的选择。只是想知道 Autofac 是否有内置的东西。
服务关联到它被解析的范围。当您解析范围时,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
它不会在需要它的生命周期结束时处理它。
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();
}
}
}
假设我有一个对象的实例,由 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.
注意几点:
- 我当然不能
myService.Dispose()
自己做,因为那样不会处理 Autofac 注入的子依赖项(因为 Autofac 正在控制它们的生命周期)。 - 我只有
myService
。这是我正在处理的图书馆的特殊性质。我当然可以自己存储scope
变量并对其进行管理。那将是我最后的选择。只是想知道 Autofac 是否有内置的东西。
服务关联到它被解析的范围。当您解析范围时,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
它不会在需要它的生命周期结束时处理它。
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();
}
}
}