枚举由autofacc生命周期跟踪的一次性物品

本文关键字:一次性 跟踪 周期 autofacc 生命 枚举 | 更新日期: 2023-09-27 18:06:11

Autofac使用生命周期作用域作为处理工作单元期间创建的所有组件的一种方式。虽然这是一个强大的特性,但很容易编写出不能正确处置生命周期作用域的代码,从而导致跟踪的处置对象数量随着时间的推移而增长:实际上是内存泄漏。

是否有一种方法可以在任何时间点监视由生命周期作用域跟踪的一次性对象的数量?我感兴趣的写作工具,以帮助我找到相关的问题,不正确地分配一次性的工作单位。目前我使用内存分析器工具来查找泄漏,但这是相当繁重的工作。

我已经看过了ILifetimeScope的公共接口,但是没有看到任何有用的东西

枚举由autofacc生命周期跟踪的一次性物品

不幸的是,分析目前是Autofac的薄弱环节之一。有一个存储库,其中一些工作是在分析包上开始的,但肯定有一些差距——例如,您可以跟踪对象何时激活,您可以看到生命周期范围何时被处置,但您无法跟踪单个对象何时作为范围的一部分被处置。没有合适的事件。

一个非常简单的激活跟踪模块看起来像这样:

using System;
using System.Collections.Generic;
using System.Linq;
using Autofac;
using Autofac.Core;
namespace DiagnosticDemo
{
  public class TrackingModule : Module
  {
    private readonly IDictionary<Type, int> _activations = new Dictionary<Type, int>();
    private readonly object _syncRoot = new object();
    public void WriteActivations()
    {
      foreach (var pair in this._activations.Where(p => p.Value > 0))
      {
        Console.WriteLine("* {0} = {1}", pair.Key, pair.Value);
      }
    }
    protected override void AttachToComponentRegistration(
      IComponentRegistry componentRegistry,
      IComponentRegistration registration)
    {
      if (registration.Ownership == InstanceOwnership.OwnedByLifetimeScope)
      {
        registration.Activated += this.OnRegistrationActivated;
      }
    }
    private void OnRegistrationActivated(
      object sender,
      ActivatedEventArgs<object> e)
    {
      if (e.Instance is IDisposable)
      {
        var type = e.Instance.GetType();
        Console.WriteLine("Activating {0}", type);
        lock (this._syncRoot)
        {
          if (this._activations.ContainsKey(type))
          {
            this._activations[type]++;
          }
          else
          {
            this._activations[type] = 1;
          }
        }
      }
    }
  }
}

你可以这样使用:

static void Main(string[] args)
{
  var trackingModule = new TrackingModule();
  var builder = new ContainerBuilder();
  // Register types, then register the module
  builder.RegisterType<Consumer>().As<IConsumer>();
  builder.RegisterType<DisposableDependency>().As<IDependency>();
  builder.RegisterType<NonDisposableDependency>().As<IDependency>();
  builder.RegisterModule(trackingModule);
  var container = builder.Build();
  // Do whatever it is you want to do...
  using (var scope = container.BeginLifetimeScope())
  {
    scope.Resolve<IConsumer>();
  }
  // Dump data
  Console.WriteLine("Activation totals:");
  trackingModule.WriteActivations();
}

然而,这不会告诉你哪些项没有被处理,我认为这是你想知道的。不过,它可能会给你一些想法,或者至少有一点帮助。

如果你有兴趣帮助改进Autofac的分析,我们很乐意接受pr或具体的设计想法来改进。

Whitebox是Autofac的一个可用但尚未完成的GUI诊断工具,它几乎可以满足您的需求。它可能需要更新到最新版本的Autofac -任何帮助让项目恢复和运行将是受欢迎的。旧Google Code页面的一些文档