【发布时间】:2016-11-19 13:55:46
【问题描述】:
请注意以下使用 MEF 作为依赖注入框架的简单程序:
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()
{
}
}
}
现在让我们用 NDepend 6.3 来分析它。假设我想知道Program.BackToProgram 的所有直接和间接调用者:
但是,TestClient 类使用依赖注入通过ITest 接口使用Test 实例,因此寻找ITest.DoSomething 的直接和间接调用者会给我这个:
所以,这给了我完整的画面 - Program.BackToProgram 最终是从 Program.Main 调用的。
不幸的是,我不得不求助于人工代码检查来连接这些点。依赖注入似乎破坏了 NDepend 跟踪跨 DI 边界调用什么的能力。
虽然这可以通过 DI 严重依赖反射并且反射并不真正适合静态代码分析这一事实来解释,但这带来了一个大问题,因为我们的代码大量使用 DI。
那么,有什么办法可以解决这个问题吗?有没有办法配置 NDepend 以识别 MEF 实现的依赖注入?归根结底,当被问及Program.BackToProgram 的所有直接和间接调用者时,我希望在没有人工干预的情况下在图表上看到Program.Main。
也许还有其他工具可以做到这一点?
编辑 1
Patrick from NDepend team 提供的答案很有趣,但还不够好。实际上,它返回了涉及的方法,但是调用者图是断开的:
因此,对于这个人为的示例,可以推断出丢失的连接。但是这种奢侈在广泛使用 DI 的生产代码中是不可用的。我们最终会得到许多不连贯的子图。这对追踪调用者没有任何帮助。
【问题讨论】:
-
结束拥护者 - 有什么理由吗?如果您对另一个论坛提出我的问题的建议 - 请畅所欲言。
标签: c# dependency-injection ndepend