Ninject学习(一) - Dependency Injection By Hand

大体上是把官网上的翻译下而已。

http://www.ninject.90iogjkdcrorg/wiki.html

Dependency Injection By Hand

So what’s Ninject all about? First, let’s examine the idea of dependency injection by walking through a simple example. Let’s say you’re writing the next blockbuster game, where noble warriors do battle for great glory. First, we’ll need a weapon suitable for arming our warriors.

所以Ninject到底是什么?首先,让我们来试验一个依赖注入实例。例如你正在写一个惊天地泣鬼神的游戏,忍者大大(鸣人)为了伟大的荣誉而战,我们需要为我们的武士(下忍们)装备武器。

1 class Sword
2 {
3     public void Hit(string target)
4     {
5         Console.WriteLine("Chopped {0} clean in half", target);
6     }
7 }

Then, let’s create a class to represent our warriors themselves. In order to attack its foes, the warrior will need an Attack() method. When this method is called, it should use its Sword to strike its opponent.

然后让我们新建一个类来代表武士。为了能够进攻敌人,武士类需要一个Attack()方法。当方法被调用的时候,方法应该调用Sword类攻击敌人。

 1 class Samurai
 2 {
 3     readonly Sword sword;
 4     public Samurai()
 5     {
 6         this.sword = new Sword();
 7     }
 8
 9     public void Attack(string target)
10     {
11         this.sword.Hit(target);
12     }
13 }

Now, we can create our Samurai and do battle!
现在,我们可以新建一个武士来作战了!

1 class Program
2 {
3     public static void Main()
4     {
5         var warrior = new Samurai();
6         warrior.Attack("the evildoers");
7     }
8 }

As you might imagine, this will print Chopped the evildoers clean in half to the console. This works just fine, but what if we wanted to arm our Samurai with another weapon? Since the Sword is created inside the Samurai class’s constructor, we have to modify the implementation of the class in order to make this change.

你能想象,控制台将会输出”Chopped the evildoers clean in half“。目前看来一切工作良好,但一旦出现了我们要为武士更换另一种武器的情况怎么办呢?由于剑是新建在武士类的构造器中的,因此为了让武士能够变更武器,我们需要修改整改武士类。

When a class is dependent on a concrete dependency, it is said to be tightly coupled to that class. In this example, the Samurai class is tightly coupled to the Sword class. When classes are tightly coupled, they cannot be interchanged without altering their implementation. In order to avoid tightly coupling classes, we can use interfaces to provide a level of indirection. Let’s create an interface to represent a weapon in our game.

当一个类依赖于一个具体的类时,我们就说这两个类是紧密关联的。在这个例子中,武士类与剑类是紧密关联的。一旦类需要修改时,所依赖的类也需要进行修改。为了避免这种紧密关联的情况,我们可以使用接口来做中间件。让我们来新建一个接口来代表一个武器类。

1 interface IWeapon
2 {
3     void Hit(string target);
4 }

Then, our Sword class can implement this interface:
然后我们的剑类可以继承这个接口

1 class Sword : IWeapon
2 {
3     public void Hit(string target)
4     {
5         Console.WriteLine("Chopped {0} clean in half", target);
6     }
7 }

And we can alter our Samurai class:
之后我们就能更改我们的武士类

 1 class Samurai
 2 {
 3     readonly IWeapon weapon;
 4     public Samurai()
 5     {
 6         this.weapon = new Sword();
 7     }
 8
 9     public void Attack(string target)
10     {
11         this.weapon.Hit(target);
12     }
13 }

Now our Samurai can be armed with different weapons. But wait! The Sword is still created inside the constructor of Samurai. Since we still need to alter the implementation of Samurai in order to give our warrior another weapon, Samurai is still tightly coupled to Sword.
现在我们的武士类就可以装备不同的武器了。但是等等!剑依然在武士类的构造函数中新建啊~由于我们依然需要修改武士类中的声明才能变更武器,所以武士类和剑类依然是紧密关联的。

Fortunately, there is an easy solution. Rather than creating the Sword from within the constructor of Samurai, we can expose it as a parameter of the constructor instead.
幸运的是,这种情况有一个简单的解决方式。我们可以为构造函数传递一个参数,来替代之前的构造函数。

 1 class Samurai
 2 {
 3     readonly IWeapon weapon;
 4     public Samurai(IWeapon weapon)
 5     {
 6         this.weapon = weapon;
 7     }
 8
 9     public void Attack(string target)
10     {
11         this.weapon.Hit(target);
12     }
13 }

Then, to arm our warrior, we can inject the Sword via the Samurai ‘s constructor. This is an example of dependency injection (specifically, constructor injection). Let’s create another weapon that our Samurai could use:
之后就可以武装我们的武士了,我们可以通过武士类的构造函数注入剑类。这个依赖注入的例子展示的是构造器注入。现在变更武器时可以通过以下方式:

1 class Shuriken : IWeapon
2 {
3     public void Hit(string target)
4     {
5         Console.WriteLine("Pierced {0}‘s armor", target);
6     }
7 }

Now, we can create an army of warriors:
现在,我们可以新建一个装备的武士了:

 1 class Program
 2 {
 3     public static void Main()
 4     {
 5         var warrior1 = new Samurai(new Shuriken());
 6         var warrior2 = new Samurai(new Sword());
 7         warrior1.Attack("the evildoers");
 8         warrior2.Attack("the evildoers");
 9     }
10 }

This results in the following output to be printed to the console:
结果就是输出以下内容:

【Pierced the evildoers armor.

Chopped the evildoers clean in half.】

This is called dependency injection by hand, because each time you want to create a Samurai, you must first create some implementation of IWeapon and then pass it to the constructor of Samurai. Now that we can change the weapon the Samurai uses without having to modify its implementation, the Samurai class could be in a separate assembly from Sword – in fact, we can create new weapons without needing the source code of the Samurai class!

这个例子就是手动依赖注入,因为每次你需要新建一个武士类,你必须首先新建一些IWeapon的继承类,然后把继承类传递给武士类的构造器。现在我们可以为武士类变更武器而不需要修改IWeapon的继承了,武士类可以单独组装剑类了,实际上我们可以新建新的武器而不需要修改武士类的源代码了!

Dependency injection by hand is an effective strategy for small projects, but as your application grows in size and complexity, it becomes more and more cumbersome to wire all of your objects up. What happens when the dependencies have dependencies of their own? What happens when you want to add a (e.g. caching, tracing to a log, auditing etc.) decorator in front of each instance of a given dependency? You can easily end up spending most of your time creating and wiring together objects, when you could be writing code that adds real value to your software. This is where dependency injection libraries / frameworks like Ninject can help.
手动依赖注入对于小型项目是一个有效的方式,但是一旦你的项目越来越大、越来越复杂,手动依赖注入会变成越来越笨重、越来越难以维护。这个时候就需要依赖注入的项目(Ninject)了。

时间: 2024-10-29 16:55:10

Ninject学习(一) - Dependency Injection By Hand的相关文章

AngularJs学习笔记--Dependency Injection(DI,依赖注入)

原版地址:http://code.angularjs.org/1.0.2/docs/guide/di 一.Dependency Injection(依赖注入) 依赖注入(DI)是一个软件设计模式,处理代码如何得到它所依赖的资源. 关于DI更深层次的讨论,可以参观Dependency Injection(http://en.wikipedia.org/wiki/Dependency_injection),Inversion of Control(http://martinfowler.com/ar

spring in action学习笔记一:DI(Dependency Injection)依赖注入之CI(Constructor Injection)构造器注入

一:这里先说一下DI(Dependency Injection)依赖注入有种表现形式:一种是CI(Constructor Injection)构造方法注入,另一种是SI(Set Injection) set 注入.这篇随笔讲的是第一种构造方法注入(Constructor Injection). 其实DI(Dependency Injection)依赖注入你不妨反过来读:注入依赖也就是把"依赖"注入到一个对象中去.那么何为"依赖"呢?依赖就是讲一个对象初始化或者将实例

[LINK]List of .NET Dependency Injection Containers (IOC)

http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx I'm trying to expand my mind around dependency injection in .NET (beyond the two frameworks I've personally used) and an starting to put together a list of .NET Dependency I

Json.NET Updates: Merge, Dependency Injection, F# and JSONPath Support

Json.NET 6.0 received 4 releases this year, the latest last week. Over these releases, several new features have been added, including several F# specific features, support for JSONPath querying, ability to integrate with Dependency Injection framewo

Dependency Injection in ASP.NET Web API 2

What is Dependency Injection? A dependency is any object that another object requires. For example, it's common to define a repository that handles data access. Let's illustrate with an example. First, we'll define a domain model: public class Produc

IoC(Inversion of Control)控制反转和 DI(Dependency Injection)依赖注入

首先想说说IoC(Inversion of Control,控制倒转).这是spring的核心,贯穿始终.所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系.这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好.qq号.电话号.ip号.iq号---,想办法认识她们,投其所好送其所要,然后嘿嘿--这个过程是复杂深奥的,我们必须自己设计和面对每个环节.传统的程序开发也是如此,在

ninject学习笔记一:IOC的实现

这篇文章主要介绍ninject在IOC方面的实现,至于IOC的含义,网络资源很丰富,我这儿就不再赘述了.官方的文档其实挺好的,只是本人英语很烂,看起来比较费劲,下面这些东西是看官方的代码推敲的,我觉得应该能够说明一些问题,希望给和我一样的初学者有一些帮助吧. 这里用一个小案例开始,也就是官方案例的改版. 首先,你要创建项目,并且通过NuGet添加ninject程序集文件 install-package ninject 接着,创建一个武器接口IWeapon,常说攻击性武器,可见咱们这武器也有杀伤力

Dependency Injection 筆記 (4)

續上集未完的相關設計模式... Composite 模式延續先前的電器比喻.現在,如果希望 UPS 不只接電腦,還要接電風扇.除濕機,可是 UPS 卻只有兩個電源輸出孔,怎麼辦? 我們可以買一條電源延長線,接在 UPS 上面.如此一來,電風扇.除濕機.和電腦便都可以同時插上延長線的插座了.這裡的電源延長線,即類似Composite Pattern(組合模式),因為電源延長線本身又可以再連接其他不同廠牌的延長線(這又是因為插座皆採用相同介面),如此不斷連接下去. 呃….延長線的比喻有個小問題:它在

Dependency Injection 筆記 (1)

<.NET 相依性注入>連載 (1) 本文從一個基本的問題開始,點出軟體需求變動的常態,以說明為什麼我們需要學習「相依性注入」(dependency injection:簡稱 DI)來改善設計的品質.接著以一個簡單的入門範例來比較沒有使用 DI 和改寫成 DI 版本之後的差異,並討論使用 DI 的時機.目的是讓讀者先對相關的基礎概念有個概括的理解,包括可維護性(maintainability).寬鬆耦合(loose coupling).控制反轉(inversion of control).動態