03-Strange Ioc 扩展 注入扩展 00

Strange IoC 帮助文档下载
您可能听说过Strange是一个依赖注入框架。我对这种描述有点不舒服。当然,Strange提供了DI,而且它的用途很好,但是正如我所说,框架的核心是绑定。
安装附带了几个核心Binder的有用扩展,我将在本节详细介绍这些扩展。
但是请记住,没有什么可以阻止您扩展绑定器来创建自己的自定义实现。
注意:在接下来的小节中,我经常引用Strange的MVCSContext版本。MVCSContext是推荐的版本,它包含下面提到的所有扩展。这是最简单的Strange开始方式。

注入扩展
与控制反转(IoC)最密切相关的Binder扩展是注入器包。 我们暗示了 在前一节中注入一点,现在让我们进入细节。

您可能熟悉编写接口的概念。接口本身不包含实现,它只定义类的输入和输出。在c#中,这看起来像:

interface ISpaceship
{
void input(float angle, float velocity);
IWeapon weapon{get;set;}
}

实现接口的类如下:

class Spaceship : ISpaceship
{
public void input(float angle, float velocity)
{
//do stuff here
}
public IWeapon weapon{get;set;}
}

通过对接口进行编程,我们减轻了一些包含子对象的问题。我们的宇宙飞船不再需要一个键盘监听器,它只需要一个对输入做出反应的方法。它不再需要枪,只需要一些满足IWeapon接口的东西(我们称之为“具体”类)。这是向前迈出的一大步。

但我问题:谁来告诉飞船使用哪种类型的iweapons ?好吧,假设宇宙飞船将在一个GameField中,所以也许GameField可以告诉宇宙飞船它将使用什么武器?但这意味着GameField需要知道具体的类。所做的就是改变位置 依赖性,所以这没有好处。

GameField可以有一个接口,将其所有依赖项(包括飞船所需的所有内容)等等推到应用程序的顶部。

TopOfApp > GameModule > GameField > Spaceship
Phaser --------------------------------------------------->


这将删除具体的类,但也意味着依赖关系的长链贯穿整个类层次结构。这很脆弱,意味着任何地方的变化都可能破坏很多东西,而且很难定位。这也意味着GameField(以及链中的任何其他类)需要了解IWeapon。但是GameField可能并不关心IWeapon,那么为什么要在不需要IWeapon的地方创建一个依赖关系呢?
工厂模式怎么样?如果我创建一个宇宙飞船工厂,一个创建宇宙飞船的类IFactory接口,那么GameField只需要一个依赖项。现在我们有了进展。
GameField ---------> SpaceshipFactory : IFactory
ISpaceship <--------- (creates concrete Spaceship)


我们不需要知道IWeapon,虽然我需要知道ispacship,现在我也需要IFactory。嗯,也许是IEnemy,,想想看。是的,我需要把所有这些工厂连接起来,弄清楚它们是如何提供的。所以还不错(这是许多程序员所能做到的)。但是,您可以看到,即使是这种公认的模式也有明显的弱点。
因此,考虑一个完全不同的模型,其中没有类必须显式地满足另一个类的依赖关系。这个模型称为依赖注入(Dependency Injection, DI)。在DI中,一个类请求它需要的东西(理想情况下是以接口的形式),一个称为注入器的类提供了这种需要。传统上,这是通过一种称为反射的机制来实现的。
使用DI,如果GameField需要一艘ISpacship,它会建立一个如下所示的依赖关系:
ISpaceship <--------- (as if by magic)


不依赖依赖链或工厂。除了类实际需要的依赖项之外,没有其他依赖项。而且永远不需要显式地显示依赖关系(当然,您可以选择这样做)。
那么“魔法”是如何起作用的呢?

c#的系统中,反射包允许在运行时对类进行解构和分析。值得注意的是,这不是最快的过程,所以我们在Strange中很少使用它,您也应该这样做。在反映类时,我们可以检查它的方法和属性。我们可以看到它的构造方法是什么样子的,以及它们需要什么参数。通过检查所有这些线索,我们可以推断类的依赖项是什么样子的,然后提供它们。
在Strange中设置依赖项的代码通常是这样的:

[Inject]
public IInterface myInstance {get;set;}

Strange如何知道要为IInterface提供什么具体的类?您可以通过在名为Context的中心文件中绑定依赖项来告诉它。正如我所提到的,“标准”Context.是MVCSContext,您可以扩展这个类来获得Strange的所有Strange特性。当扩展MVCSContext时,你可以在扩展类中创建你的绑定,就像这样:

injectionBinder.Bind<IWeapon>().To<PhaserGun>();

现在,每当一个类需要IWeapon时,都会提供具体的PhaserGun类。 如果你决定改变 PhaserGun到SquirtCannon,你不会对Spaceship或任何其他类别做任何改动。 你只要重新映射:

injectionBinder.Bind<IWeapon>().To<SquirtCannon>();

您看!宇宙飞船现在使用喷枪。这一切都源于一个简单的字,承认这是一个依赖注入:

class Spaceship : ISpaceship
{
public void input(float angle, float velocity)
{
//do stuff here
}
[Inject] //<----- The magic word!
public IWeapon weapon{get;set;}
}

值得注意的是,如果不使用DI,这个[Inject]属性标记是完全无害的。所以您可以将它添加到您的类中,然后,如果有一天您发现这个DI lark完全是一个可怕的错误(这是最明显的错误),那么代码中的标记对您没有任何影响。没有那个[Inject]标签,“weapon”现在只是一个普通的getter/setter。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值