3

这对大多数人来说似乎很明显,但我只是想确认依赖注入 (DI) 依赖于接口的使用。

更具体地说,对于在其构造函数中具有某个接口作为参数的类或将某个接口定义为属性(又名 Setter)的情况,DI 框架可以移交具体类的实例以满足需求那个类中的那个接口。(如果此描述不清楚,请道歉。我无法正确描述这一点,因为术语/概念对我来说仍然有些新。)

我问的原因是我目前有一个具有某种依赖关系的类。与其说是对象依赖,不如说是 URL。该类看起来像这样 [C#]:

using System.Web.Services.Protocols;
public partial class SomeLibraryService : SoapHttpClientProtocol 
{
        public SomeLibraryService() 
        {
            this.Url = "http://MyDomainName.com:8080/library-service/jse";
        }
}

SoapHttpClientProtocol 类有一个名为的公共属性Url(它是一个普通的旧“字符串”),这里的构造函数将它初始化为一个硬编码的值。

我可以使用 DI 框架在构建时注入不同的价值吗?我想不是,因为this.Url不是任何一种Interface;这是一个String

[顺便说一句,根据我正在使用的代码中的注释,上面的代码是“由 wsdl 自动生成的”。所以我并不特别想更改这段代码,尽管我也没有看到自己重新生成它。所以也许改变这个代码是好的。]

我可以看到自己制作了一个替代构造函数,它将字符串作为参数并this.Url以这种方式初始化,但我不确定这是保持松散耦合关注点分离的正确方法。(系统级芯片)

对这种情况有什么建议吗?

4

4 回答 4

8

DI 实际上只是意味着一个类不会构造它的外部依赖项,也不会管理这些依赖项的生命周期。可以通过构造函数或方法参数注入依赖项。接口或抽象类型通常用于阐明消费者对其依赖项的期望,但在某些情况下也可以注入简单类型。

例如,库中的类可能会在内部调用 HttpContext.Current,这会对托管代码的应用程序做出任意假设。库方法的 DI 版本将期望通过参数等注入 HttpContext 实例。

于 2010-07-15T15:24:53.077 回答
5

不需要使用接口——您可以使用具体类型或抽象基类。但是 DI 的许多优点(例如能够更改依赖项的实现)都是在使用接口时出现的。

Castle Windsor(我最了解的 DI 框架)允许您将 IoC 容器中的对象映射到接口,或仅映射到名称,这适用于您的情况。

于 2010-07-15T15:25:39.380 回答
3

依赖注入是一种组织代码的方式。也许您的一些困惑来自这样一个事实,即没有一种官方的方法可以做到这一点。它可以使用“常规”c# 代码或使用 Castle Windsor 之类的框架来实现。有时(经常?)这涉及使用接口。不管它是如何实现的,DI 的总体目标通常是让你的代码更容易测试和以后更容易修改。

如果您要通过构造函数在示例中注入 URL,则可以将其视为“手动”DI。关于 DI的 Wikipedia文章有更多手动与框架 DI 的示例。

于 2010-07-15T16:54:58.373 回答
0

我想重点回答在 .NET 应用程序中使用接口。.NET 中的多态性可以通过虚拟或抽象方法或接口来实现。

在所有情况下,都存在根本没有实现的方法签名或可以覆盖的实现。

定义了函数(甚至是属性)的“契约”,但是方法是如何实现的,方法的逻辑内容在运行时可能会有所不同,这取决于实例化哪个子类并将其传递给方法或构造函数,或在属性上设置(“注入”行为)。

官方的 .NET 类型设计指南提倡在接口上使用抽象基类,因为它们在交付后有更好的选择来改进它们,可以包括便利的重载,并且能够更好地自我记录并将正确的用法传达给实现者。

但是,必须注意不要添加任何逻辑。这样做的诱惑在过去已经烧毁了人们,所以很多人使用接口——许多其他人使用接口仅仅是因为坐在他们周围的程序员就是这样做的。

有趣的是,虽然 DI 本身很少被过度使用,但使用框架来执行注入却经常被过度使用而损害了复杂性的增加,在需要越来越多类型的地方可能会发生连锁反应在容器中,即使它们从未“切换”过。

应谨慎使用 IoC 框架,通常仅当您需要根据环境或配置在运行时换出对象时。这通常意味着在应用程序中切换主要组件“接缝”,例如用于抽象数据层的存储库对象。

对我来说,IoC 框架的真正威力是在您无法控制创建的地方切换实现。例如,在 ASP.NET MVC 中,控制器类的创建是由 ASP.NET 框架执行的,因此注入任何东西都是不可能的。ASP.NET 框架有一些钩子,IoC 框架可以使用这些钩子来“介入”创建过程并发挥它们的魔力。

卢克

于 2013-11-15T15:11:24.597 回答