什么是IoC容器中的自我绑定?

我已经看到像Ninject这样的框架以及Stack上的post在使用dependency injection框架时会谈到自我绑定,如下面的代码所示。

Bind().To(); 

他们甚至达到了具有特殊语法的程度:

 Bind().ToSelf(); 

为什么要将类型绑定到自身? 我没有看到任何实际的应用程序,它可能有用,并有助于减少代码中的依赖性。 这不仅仅意味着对类型的引用会简单地解决它自己吗?

在应用dependency injection并遵循依赖性反转原则时 ,常见的建议是对接口进行编程,而不是实现 。 这就是为什么大多数时候你会看到从抽象到实现的绑定:

 Bind().To(); 

这意味着组件在编译时将依赖于IWarrior ,并且我们在运行时注入了Samurai

但是,在某些条件下,从具体组件到自身的映射是有意义的。 换句话说,如果’某人’要求Samurai ,我们就提供Samurai

最突出的情况是解析根类型。 根类型是依赖关系图的顶部; 根类型直接从容器中解析。 所有其他类型都是根类型的直接或间接依赖关系。

通常,您会看到这些根类型是通过其具体类型解决的,并且通常我们正在处理UI框架。 例如Web Forms Page ,MVC Controller ,Web API ApiController等。

大多数DI容器都可以解决具体的未注册类型。 这可能会让您相信自我约束是多余的,但情况并非总是如此。 明确添加此类绑定可让容器知道此类绑定的存在。 这具有使用容器的诊断能力(如果存在)来扫描对象图以查找错误的优点。 如果没有这样的function,通常可以迭代已知的注册并在unit testing中进行一些validation。 为了使这种validation在迭代容器的注册时有意义,所有根类型都需要在容器中注册。 否则,此validation过程将导致假阴性。

您想要告诉DI容器自我绑定的另一个原因是容器不允许解析未注册的类型,或者您需要使用与容器的默认生活方式不同的生活方式注册类型。 如果未注册类型,大多数容器将为您提供Transient实例。