簡體   English   中英

在 autofac 中可視化依賴樹深度

[英]Visualizing dependency tree depth in autofac

我可能一直在尋找錯誤的東西,在錯誤的盒子里尋找。 但是我似乎找不到一種好方法來可視化我的依賴樹在 C# 中的深度。

我最初只是嘗試連接 Autofac 的准備事件和激活事件。 但我不知道這是否足夠好。 結果看起來有點時髦。 似乎准備活動啟動得太頻繁了。 並且似乎只有在實際創建新對象時才會激活激活事件。

我們的代碼是 .NET 4.7.2 我們使用 Autofac 作為我們的容器來處理依賴項注入。

有沒有人對我們如何可視化深度有好的想法? 也許有一些好的代碼或產品可以幫助我們?

前段時間,我對 Autofac 進行了類似的探索。 我最終得到的是以下內容:

public class DebugResolveModule : Module
{
    private readonly ThreadLocal<ResolveInfo> _current = new ThreadLocal<ResolveInfo>();

    protected override void AttachToComponentRegistration(
        IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        registration.Preparing += Registration_Preparing;
        registration.Activating += Registration_Activating;

        base.AttachToComponentRegistration(componentRegistry, registration);
    }

    private void Registration_Preparing(object sender, PreparingEventArgs e)
    {
        _current.Value = new ResolveInfo(e.Component.Activator.LimitType, _current.Value);
    }

    private void Registration_Activating(object sender, ActivatingEventArgs<object> e)
    {
        var current = _current.Value;
        current.MarkComponentAsResolved();
        _current.Value = current.Parent;

        if (current.Parent == null)
        {
            VisualizeGraph(current);
            Debug.WriteLine(
                $"total resolve time: {current.ResolveTime.TotalMilliseconds} ms.");
        }
    }

    private static void VisualizeGraph(ResolveInfo node, int depth = 0)
    {
        for (int i = 0; i < depth; i++)
        {
            Debug.Write("   ");
        }

        Debug.Write(node.ComponentType);
        Debug.Write(" (");
        Debug.Write(node.ResolveTime.TotalMilliseconds.ToString("F1"));
        Debug.Write(" ms. / ");
        Debug.Write(node.CreationTime.TotalMilliseconds.ToString("F1"));
        Debug.Write(" ms.)");


        Debug.WriteLine("");

        foreach (var dependency in node.Dependencies)
        {
            VisualizeGraph(dependency, depth + 1);
        }
    }

    private sealed class ResolveInfo
    {
        private Stopwatch _watch = Stopwatch.StartNew();

        public ResolveInfo(Type componentType, ResolveInfo parent)
        {
            ComponentType = componentType;
            Parent = parent;
            Dependencies = new List<ResolveInfo>(4);

            if (parent != null)
            {
                parent.Dependencies.Add(this);
            }
        }

        public Type ComponentType { get; }

        // Time it took to create the type including its dependencies
        public TimeSpan ResolveTime { get; private set; }

        // Time it took to create the type excluding its dependencies
        public TimeSpan CreationTime { get; private set; }
        public ResolveInfo Parent { get; }

        public List<ResolveInfo> Dependencies { get; }

        public void MarkComponentAsResolved()
        {
            ResolveTime = _watch.Elapsed;
            CreationTime = ResolveTime;

            foreach (var dependency in this.Dependencies)
            {
                CreationTime -= dependency.ResolveTime;
            }
                
            _watch = null;
        }
    }
}

請注意,這並不完全是您想要的,因為它是一個解析觸發器。 這意味着SingleInstance僅解析一次,這意味着下次您請求圖形時,您將丟失單例。 這對我來說不是問題,因為我使用此代碼來檢測對象圖的慢速解析部分。

但是,此代碼可能仍會為您提供有關如何執行此操作的一些想法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM