如何在Autofac中从ILifetimeScope获取已初始化的实例?
在Autofac中获取已初始化的接口实例
Autofac本身没有直接提供获取所有已初始化实例的API,因为容器默认不会跟踪所有已解析的对象(除非主动开启实例跟踪)。要实现需求,可以通过以下几种可行方式:
1. 开启实例跟踪并解析枚举实例
如果IImageType的实现类已在容器中注册,可先开启实例跟踪,再通过解析枚举类型获取所有已初始化的实例:
首先在构建容器时开启实例跟踪:
var builder = new ContainerBuilder(); // 注册IImageType的实现类 builder.RegisterType<PngImageType>().As<IImageType>(); builder.RegisterType<JpegImageType>().As<IImageType>(); // 注册依赖IImageType的服务 builder.RegisterType<ImageResizer>(); builder.RegisterType<ImageScaler>(); // 开启实例跟踪选项 var container = builder.Build(ContainerBuildOptions.TrackInstances);
之后在需要获取实例的地方,先触发实例初始化(比如解析依赖服务),再获取所有已初始化的IImageType实例:
using var scope = container.BeginLifetimeScope(); // 触发实例初始化 scope.Resolve<ImageResizer>(); scope.Resolve<ImageScaler>(); // 获取所有已解析的IImageType实例 var initializedInstances = scope.Resolve<IEnumerable<IImageType>>();
2. 自定义实例跟踪器
如果需要更精准地跟踪IImageType实例的创建与销毁,可以自定义跟踪类,在实例激活时记录:
public class InstanceTracker<T> : IInstanceTrackingHandler { public List<T> TrackedInstances { get; } = new List<T>(); public void OnInstanceActivated(IComponentContext context, IEnumerable<InstanceActivatedEventArgs> args) { foreach (var arg in args) { if (arg.Instance is T instance) { TrackedInstances.Add(instance); } } } public void OnInstanceDeactivated(IComponentContext context, IEnumerable<InstanceDeactivatedEventArgs> args) { // 可选:实例销毁时从跟踪列表移除 foreach (var arg in args) { if (arg.Instance is T instance) { TrackedInstances.Remove(instance); } } } }
然后在容器构建时注册这个跟踪器:
var builder = new ContainerBuilder(); var imageTypeTracker = new InstanceTracker<IImageType>(); // 注册跟踪器为实例跟踪处理器 builder.RegisterInstance(imageTypeTracker).As<IInstanceTrackingHandler>(); // 注册相关服务 builder.RegisterType<PngImageType>().As<IImageType>(); builder.RegisterType<JpegImageType>().As<IImageType>(); builder.RegisterType<ImageResizer>(); builder.RegisterType<ImageScaler>(); var container = builder.Build(ContainerBuildOptions.TrackInstances);
当实例被初始化后,直接从跟踪器中获取:
using var scope = container.BeginLifetimeScope(); scope.Resolve<ImageResizer>(); scope.Resolve<ImageScaler>(); // 获取所有已初始化的IImageType实例 var allImageTypeInstances = imageTypeTracker.TrackedInstances;
注意事项
- 实例跟踪会产生一定性能开销,生产环境需根据实际场景评估使用必要性。
- 不同生命周期作用域的实例相互隔离,需确保跟踪器的作用域与目标实例的作用域匹配。
- 单例实例只会被容器初始化一次,瞬态实例每次解析都会创建新实例,跟踪器会记录所有生成的实例。
内容的提问来源于stack exchange,提问作者Saylent
相关产品推荐
相关产品推荐

