枚举Autofac生命周期跟踪的一次性用品

时间:2016-09-08 01:32:35

标签: c# inversion-of-control autofac

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

是否有办法监控Lifetime Scope在任何时间点跟踪的Disposable对象的数量。我有兴趣编写工具来帮助我找到与未正确分配一次性工作单元相关的问题。目前我使用内存分析器工具来查找泄漏,但这是非常繁重的工作。

我查看了ILifetimeScope的公共界面,但没有看到任何有用的东西。

2 个答案:

答案 0 :(得分:1)

不幸的是,分析是目前Autofac的弱点之一。 There is a repository where some work was started on an analytics package但肯定存在一些差距 - 例如,您可以跟踪某个对象何时被激活并且您可以看到何时处置了生命周期范围,但您可以跟踪个别对象何时作为范围的一部分进行处理。它没有任何事件。

一个非常简单的激活跟踪模块如下所示:

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中的分析,我们很乐意take PRs or specific design ideas for how to improve

答案 1 :(得分:1)

Whitebox是一个有效但未完成的Autofac GUI诊断工具,可以完成您正在寻找的功能。它可能需要更新最新版本的Autofac - 欢迎任何帮助恢复和运行项目。一些docs on the old Google Code page