Ninject Injection Patterns

Ninject Injection Patterns

1.依赖注入模式

Ninject 创造性的支持三种类型的注入模式,每种类型都有优缺点。我们需要根据不同情境来决定使用哪种注入模式。

Constructor Injection

主要的依赖注入模式是 Constructor Injection.当激活一个类型的实例时,Ninject将按照如下给出的顺序选择一个这个类型的构造函数:

1.如果一个构造函数拥有一个[Inject]特性,那么它将被使用(如果你对多造函数使用[Inject]特性,那么在运行时进行检测的过程中抛出 NotSupportedException 的异常)。
2.如果没有构造函数包含[Inject]特性,Ninject 将选择一个可以确定最多参数的构造方法。
3.如果没有构造函数被定义,Ninject 将选择默认的无参构造函数。

class Samurai 
{
    readonly IWeapon weapon;

    public Samurai(IWeapon weapon)
    {
        if(weapon == null)
            throw new ArgumentNullException("weapon");
        this.weapon = weapon;
    }

    public void Attack(string target)
    {
        this.weapon.Hit(target);
    }
}

上面的这种实现方式具有如下优点:
1.在一个地方可以看到全部的依赖关系
2.避免了不必要混淆的产生
3.所有的验证可以在同一个地方实现
4.你可以使用编译器提供的 readyonly 关键字来确定字段不会被改变
5.你的代码将不用频繁的去访问DI容器
6.如果你在编写测试代码,或者是在DI容器外部使用一个类型,编译器将清楚的给出这个类的依赖项

我们还应该注意到[Inject]特性可以完全不被使用。也就是说你的大部分代码可以不关注Ninject和引用Ninject的命名空间以及程序集。如果无法访问一个类但却要注入依赖关系到这个类,这将是一件危险的事情(我们也可以告诉Ninject通过添加一些自定义的特性比如一些除了[Inject]外的其他特性,通过设置Ninject属性从而采用这个特性。)。

Initialization methods

如果Constructor Injection 不能满足你的需求,Ninject提供了两种方法,用于在容器构造完成后提供依赖性。虽然表面上看起来很不一样,但是它们的机制和语法基本相同:
1.在构造开始以后,被[Inject]亦或是其他设定的特性标记过的方法和属性,将被赋值依赖项所设定的实例。
2.调用的顺序并不确定,没有方法告诉Ninject以何种顺序来注入这些值,然而你可以通过实现IInitializable 和 IStartable 接口请求在所有的注入动作完成后给予通知。

与Constructor Injection 相比,它的主要缺点是:
1.你不能通过使用 readyonly 关键字来依赖编译器保证初始化时的正确性。
2.分析这些有可能给 weapon 赋值的地方要比追溯到单一的构造函数要复杂的多。
3.你将不再能够一眼看出类型的依赖性
4.它要求[Inject]的特性声明在用的到的地方必须可见,这将把你的代码绑定到一个特殊的容器上。
5.为了保护类中的不变量,我们有必要考虑在外部的任何人任何时候任何顺序调用初始化方法时,执行验证逻辑。

Setter Method Injection

如下对Samurai类以Setter Method Injection 的方式进行了重写,一个方法将在创建实例后被调用,它必须用[Inject]特性进行标记。
class Samurai
{
    IWeapon weapon;

    [Inject]
    public void Arm(IWeapon weapon)
    {
        this.weapon = weapon;
    }

    public void Attack(string target) 
    {
        this.weapon.Hit(target);
    }
}

我们可以在类的继承层级上标记多个方法,每一个被标记的方法将在对象组成图上被调用,但是没有办法确定它们被调用的先后顺序。

Property Setter Injection

如下将 samurai 类以Property Setter Injection 的方式进行重写,被依赖注入的属性需要添加[Inject]特性:

class Samurai 
{    
    [Inject]
    public IWeapon Weapon { private get; set; }

    public void Attack(string target) 
    {
        this.Weapon.Hit(target);
    }
}

Setter Method Injection 是 Property Setter Injection 的一个特例,这是没有明确的指出 set_PropertyName 的方法名,因此具有其相同的缺点。虽然表面上看起来它比上面提到的Constructor Injection 更加整洁,但是它具有更多缺点,在考虑使用这种方式时要更加的慎重。

另外,你的类接口还存在如下缺点:

1.如上所用的一个只写属性,被认为是一种糟糕的实践
2.使 getter 访问器可见将通过公开接口暴露外部依赖关系管理,这将是一个坏主意

Injecting Fields

Fields Injection 是一个差强人意的实践,在新版的Ninject中删除了这种注入方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Summary Dependency Injection Principles, Practices, and Patterns teaches you to use DI to reduce hard-coded dependencies between application components. You'll start by learning what DI is and what types of applications will benefit from it. Then, you'll work through concrete scenarios using C# and the .NET framework to implement DI in your own projects. As you dive into the thoroughly-explained examples, you'll develop a foundation you can apply to any of the many DI libraries for .NET and .NET Core. Purchase of the print book includes a free eBook in PDF, Kindle, and ePub formats from Manning Publications. About the Technology Dependency Injection (DI) is a great way to reduce tight coupling between software components. Instead of hard-coding dependencies, such as specifying a database driver, you make those connections through a third party. Central to application frameworks like ASP.NET Core, DI enables you to better manage changes and other complexity in your software. About the Book Dependency Injection Principles, Practices, and Patterns is a revised and expanded edition of the bestselling classic Dependency Injection in .NET. It teaches you DI from the ground up, featuring relevant examples, patterns, and anti-patterns for creating loosely coupled, well-structured applications. The well-annotated code and diagrams use C# examples to illustrate principles that work flawlessly with modern object-oriented languages and DI libraries. What's Inside Refactoring existing code into loosely coupled code DI techniques that work with statically typed OO languages Integration with common .NET frameworks Updated examples illustrating DI in .NET Core About the Reader For intermediate OO developers. About the Authors Mark Seemann is a programmer, software architect, and speaker who has been working with software since 1995, including six years with Microsoft. Steven van Deursen is a seasoned .NET developer and architect, and the author and maintainer of the Simple Injector DI library. Table of Contents PART 1 Putting Dependency Injection on the map Chapter 1. The Basics Of Dependency Injection: What, Why, And How Chapter 2. Writing Tightly Coupled Code Chapter 3. Writing Loosely Coupled Code PART 2 Catalog Chapter 1. Di Patterns Chapter 2. Di Anti-Patterns Chapter 3. Code Smells PART 3 Pure DI Chapter 1. Application Composition Chapter 2. Object Lifetime Chapter 3. Interception Chapter 4. Aspect-Oriented Programming By Design Chapter 5. Tool-Based Aspect-Oriented Programming PART 4 DI Containers Chapter 1. Di Container Introduction Chapter 2. The Autofac Di Container Chapter 3. The Simple Injector Di Container Chapter 4. The Microsoft.Extensions.Dependencyinjection Di Container
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值