【问题标题】:Where do these constructor parameters come from in this inversion of control instantiation?在这种控制实例化的反转中,这些构造函数参数从何而来?
【发布时间】:2018-07-17 19:59:20
【问题描述】:

我正在 WPF/C# 中处理一个不完整的应用程序。其中大部分代码都很好,尽管我事先并不知道控制反转,这让我困惑了一段时间。现在我想我已经弄清楚了一些,但有些事情仍然困扰着我。

举个例子:我们有一个名为CoreApplication 的大类,它管理所有通用的东西。除此之外,它还有一系列RegisterType指令,其中

SharedObjects.InversionOfControl.RegisterType<IGoodClass, GoodClass>();

SharedObjects 是一个静态类,其中定义了一个名为InversionOfControl 的静态IUnityContainer 对象,在声明时用新的UnityContainer() 初始化。)

CoreApplication 的其他地方,有一个包含代码的ICommand

var goodClassForNavigation = (SharedObjects.InversionOfControl.Resolve<IGoodClass>()); 

据我所知,它调用了GoodClass 的构造函数,因为Register() 链接了IGoodClassGoodClass,并且Resolve() 是用IGoodClass 调用的。

很好。现在,转到GoodClass 了解它的作用,我看到它的构造函数如下所示:

public GoodClass(CoreApplication coreApplication)
{
    this.coreApplication = coreApplication;
    // Other stuff happens
}

我已确保参数已正确实例化;它的各种属性和字段具有我期望的值。

我无法理解的是,这个CoreApplication 参数是从哪里来的?

我试图在GoodClass 的基类中查找构造函数,但它们没有明确的构造函数。

感谢至今仍在我身边的人。怎么了?构造函数从哪里获取参数?是来自调用构造函数的类吗?来自SharedObjects.InversionOfControl 中的内容?

【问题讨论】:

  • CoreApplication 由您的 DI 框架自动解析,然后将实例传递给构造函数。这在很大程度上取决于您使用的 DI 框架。
  • 构造函数需要被...调用。什么东西可以是任何东西......我建议你在构造函数中放置一个断点,并在它命中时检查堆栈跟踪。您应该能够了解它的来源
  • @ViRuSTriNiTy:应用程序使用 UnityContainer。这有帮助还是我误解了您的评论?
  • @musefan:你说的很对,当然。当我这样做时,我看到调用是上面引用的 Resolve&lt;IGoodClass&gt;() 行。
  • @Jean-DavidLanz:我想如果您使用的是 Microsoft 框架,它并不像我建议的那样简单......我认为这都是您自己的类

标签: c# constructor inversion-of-control resolve


【解决方案1】:

只需让您的 DI 框架完成繁重的工作:

  1. 您调用 Resolve(),这是您的 DI 框架的一个方法
  2. DI 框架现在将IGoodClass 解析为GoodClass
  3. DI 框架分析构造函数,发现需要一个参数
  4. DI 框架现在尝试根据参数类型解析参数实例,在您的情况下为 CoreApplication
  5. DI 框架创建CoreApplication 的实例
  6. DI 框架现在可以通过将解析后的 CoreApplication 实例传递给构造函数来创建 GoodClass 实例

可以配置解析过程,例如按惯例注册

我建议你阅读文章Dependency Injection with Unity

【讨论】:

  • 非常有趣,谢谢!现在,正如我所提到的,CoreApplication 的实例具有实际的非默认值,这些值不能来自单纯的实例化(例如包含我在启动时输入的登录名的 UserName)。因此,我怀疑传递给构造函数的 CoreApplication 是解析 IGoodClass 接口的那个。但为什么以及如何? DI 框架是否真的环顾四周?我觉得这些步骤 4 到 6 代表框架非常聪明 - 或者说很有机会,但这会进一步推动它。
  • @Jean-DavidLanz 您可以配置 Unity,使特定参数填充特定实例。例如,RegisterType() 有各种重载。您需要找到配置 Unity 的位置以获取所需信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多