how to connect the dots?

Please, observe the following trivial program using MEF as the Dependency Injection framework:

using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

namespace ConsoleApplication2
{
    [InheritedExport]
    public interface ITest
    {
        void DoSomething();
    }

    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class Test : ITest
    {
        #region Implementation of ITest

        public void DoSomething()
        {
            Program.BackToProgram();
        }

        #endregion
    }

    [Export]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class TestClient
    {
        private readonly ITest m_test;

        [ImportingConstructor]
        public TestClient(ITest test)
        {
            m_test = test;
        }

        public void DoSomethingFromTestClient()
        {
            m_test.DoSomething();
        }
    }

    class Program
    {
        private static CompositionContainer m_container;

        static void Main()
        {
            m_container = new CompositionContainer(new TypeCatalog(typeof(Test), typeof(TestClient)), true);
            var testClient = m_container.GetExportedValue<TestClient>();
            testClient.DoSomethingFromTestClient();
        }

        public static void BackToProgram()
        {
        }
    }
}

Now let us analyse it with NDepend 6.3. Suppose I wish to know all the direct and indirect callers of Program.BackToProgram : 在这里输入图像描述

However, the class TestClient consumes a Test instance through the ITest interface using Dependency Injection, so looking for the direct and indirect callers of ITest.DoSomething gives me this: 在这里输入图像描述

So, this gives me the complete picture - Program.BackToProgram is ultimately called from Program.Main .

Unfortunately, I had to resort to manual code inspection in order to connect the dots. Dependency Injection seems to break NDepend's ability to track what calls what across the DI boundaries.

While this can be explained by the fact that DI heavily relies on reflection and that reflection does not really lend itself to static code analysis, this poses, nevertheless, a big problem, because our code uses DI quite a lot.

So, is there any solution to this problem? Is there a way to configure NDepend to recognise the Dependency Injection as implemented by MEF? At the end of the day, when asked for all the direct and indirect callers of Program.BackToProgram I wish to see Program.Main on the graph without human intervention.

Maybe there is another tool that does it?

EDIT 1

The answer provided by Patrick from NDepend team is interesting, but it is not good enough. Indeed, it returns the involved methods, but the caller graph is disconnected: 在这里输入图像描述

So for this contrived example one can deduce the missing connection. But this luxury is unavailable in a production code that uses DI extensively. We will end up with many disconnected subgraphs. This would not be any helpful to trace the callers.


链接地址: http://www.djcxy.com/p/37726.html

上一篇: 使用NDepend继承的方法依赖关系

下一篇: 如何连接点?