我一直在阅读以下关于Unity和依赖注入的指南: https://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx
我遇到了让我困惑的事情:
使用Unity容器,您可以注册一组映射 确定构造函数时所需的具体类型(或 属性或方法)标识接口注入的类型 类型或基类类型。提醒一下,这里有一份副本 ManagementController类中的构造函数,显示它需要 注入实现ITenantStore接口的对象。
public ManagementController(ITenantStore tenantStore) { this.tenantStore = tenantStore; }
以下代码示例显示了如何创建新的Unity 容器然后注册要使用的具体类型 ManagementController实例需要ITenantStore实例。
var container = new UnityContainer(); container.RegisterType<ITenantStore, TenantStore>();
此处显示的RegisterType方法告诉容器在实例化需要通过构造函数,方法或属性注入ITenantStore实例的对象时实例化TenantStore对象。
最后:
var controller = container.Resolve<ManagementController>();
要实例化ManagementController和TenantStore对象,请执行此操作 必须调用Resolve方法。
这是他们给出的一个例子。然而,在他们给出另一个与这个看起来完全不同的例子之后不久,
container.RegisterType<ISurveyStore, SurveyStore>();
这里,寄存器类型方法告诉容器在实例化一个需要通过构造函数,方法或属性注入ISurveyStore实例的对象时实例化SurveyStore对象。
Resolve()方法让我困惑:
var surveyStore = container.Resolve<ISurveyStore>();
在第一个示例中,解析意味着将实例化对象(ManagementController类),并且实现ITenantStore接口的TentantStore实例将传递给ManagementController。但是,在这里,ISurveyStore正在被解决,而不是具体的“被解决”的类。这是什么意思? ISurveyStore实例无法实例化,因为它是一个接口,所以传递给具体的SurveyStore对象是什么?这看起来是某种错误吗?这两个例子在RegisterType()和Resolve()方面看起来都差不多,但是在第二个例子中,正在解决的实际情况似乎完全不同,在将它与第一个例子进行比较时没有任何意义。
答案 0 :(得分:1)
该示例不是错误。 Resolve
方法通常用于解析容器中注册的实例。所以第一个例子实际上是以下的短期版本(利用Unity的一些功能):
container.RegisterType<ISurveyStore, SurveyStore>();
container.RegisterType<ManagementController, ManagementController>();
container.Resolve<ManagementController>();
所以我们在这里注册两种类型,即ServeyStore
和ManagementController
。 ServeyStore
映射到IServeStore
接口,而ManagementController
映射到自身。这意味着,如果您要求ManagementController
,您将获得ManagementController
。
所以通常你会注册容器要为你创建的所有内容,而依赖注入背后的想法是你只解析根类型,并让容器为你构建底层对象的完整图形。
然而,Unity允许解析具体类型,即使它们未注册。无论如何,注册这些类型通常是一个好主意,但这是一个不同的讨论。因此,该示例展示了Unity的几个不同方面:在类型之间进行映射的可能性以及解析具体类的可能性,即使它们可能尚未注册。
与ManagementController
不同,统一能够解析ISurveyStory
的唯一方法是它实际上知道如何将其映射到具体类型,因为很明显它无法创建接口
答案 1 :(得分:0)
你很清楚第一个例子中发生了什么:
在第一个示例中,解析意味着将实例化对象(ManagementController类),并且实现ITenantStore接口的TentantStore实例将传递给ManagementController。
如果要解析接口类型,则第二个示例中的唯一区别。但Unity 知道如何解决它 - 因为你明确地告诉它如何。它将返回ISurveyStore
类型,基础对象将为SurveyStore
,就像您已完成:
ISurveyStore store = new SurveyStore();
传递给具体的SurveyStore对象是什么?
你正在直接解决它,它没有传递给任何东西。 Unity很聪明,你可以解决嵌套类型,无论它有多深(只要它知道如何)。在这里,你恰好直接请求一个没有依赖关系的类型。以同样的方式,给出第一个例子,你可以这样做:
var tenantStore = container.Resolve<ITenantStore>();