NDepend and Dependency Injection - how to connect dots?

Please pay attention to the following trivial program that uses MEF as an attachment framework for dependencies:

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's analyze this with NDepend 6.3. Suppose I want to know all direct and indirect callers Program.BackToProgram: enter image description here

However, the class TestClientconsumes the instance Testthrough the interface ITestusing Dependency Injection, so finding direct and indirect callers ITest.DoSomethinggives me the following: enter image description here

So that gives me the big picture. Program.BackToProgrameventually called from Program.Main.

, , . , -, NDepend , , DI.

, DI , , , , DI .

, ? NDepend , MEF? , Program.BackToProgram, Program.Main .

, , ?

1

, NDepend, , . , , : enter image description here

, . , DI. . .

+4
1

.

// Retrieve the target method by name
let methodTarget = Methods.WithFullName("ConsoleApplication2.Program.BackToProgram()").Single()

// Build a ICodeMetric<IMethod,ushort> representing the depth of indirect
// call of the target method.
let indirectCallDepth = 
   methodTarget.ToEnumerable()
   .FillIterative(
       methods => methods.SelectMany(
          m => m.MethodsCallingMe.Union(m.OverriddensBase)))

from m in indirectCallDepth.DefinitionDomain
select new { m, callDepth = indirectCallDepth[m]  }

et voilΓ :)

NDepend method call of an indirect method

+2

Source: https://habr.com/ru/post/1648092/


All Articles