摘要

在小的应用系统中一个一个注册一些服务类型不怎么困难。但是,如果是一个实际的有上百个服务的应用程序呢?约定配置允许我们使用约定绑定一组服务,而不用一个一个分别绑定。

要使用约定配置,需要添加Ninject Convention扩展的引用。可以使用NuGet安装Ninject.Extensions.Conventions或者从GitHub上下载二进制文件。

注册一个约定绑定至少需要下面三个步骤:

1. 选择包含具体类的程序集。

2. 选择程序集中的具体组件。

3. 选择具体组件相关的服务类型。

1、选择程序集

注册约定的第一步是得到组件类型的程序集。可以是当前程序集也可以是外部程序集。

下面的方法用来得到程序集:

• FromThisAssembly(): 选择包含当前代码的程序集。
• From(params Assembly[] assemblies): 选择指定程序集。
• FromAssemblyContaining<SomeType>(): 选择包含指定类的程序集。

有时候不是所有的组件都在同一个程序集里,Join语法可以选择多个程序集:

 kernel.Bind(x => x
.FromAssemblyContaining<CustomersService>()
.SelectAllClasses()
.Join
.FromAssemblyContaining<MessageProvider>()
.SelectAllClasses()
.BindAllInterfaces());

大概地说,只有公有类型才可以在程序集里被绑定。为了包含非公有类型,需要在选择程序集后用IncludingNonePublicTypes方法显示声明:

 .FromAssemblyContaining<CustomersService>()
.IncludingNonePublicTypes()
.SelectAllClasses()
.BindAllInterfaces());

2、选择组件

第二步是选择将要注册的组件。可以使用SelectAllClasses方法选择所有的非抽象类,也可以使用Select(Func<Type, bool> filter)方法选择所需要的类。下面的例子选择所有名字以"Customer"开头的所有类。

 kernel.Bind(r => r
.FromThisAssembly()
.Select(t =>t.Name.StartsWith("Customer"))
.BindBase());

不是必须选择程序集中的所有类。可以用条件对结果进行过滤。下面的例子选择那些在基础类型在名称空间"Northwind.Controllers"里的类。

 kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.InNamespaces("Northwind.Controllers")
.BindBase());

也可以使用Exclude方法和Include方法对结果进行过滤得到最终需要的组件列表。

3、选择服务类型
既然选择了具体组件,我们应该选择他们对应的绑定服务类型。可以使用下面的方法指定每一个组件的服务类型:

• BindAllInterfaces(): 绑定所有的选择的组件的接口到选择的组件。
• BindBase(): 绑定选择的组件的基类型到当前的组件。
• BindDefaultInterface(): 绑定指定类型的默认接口到类型。类型的默认接口跟类型同名。例如,ICustomerService是CutomerService的默认接口。
• BindDefaultInterfaces(): 绑定指定类型的默认接口到类型。类型的默认接口是那些以类型的名字结尾的接口。例如,IRepository和ICustomerRepository都是SqlCustomerRepository的默认接口。
• BindSingleInterface(): 要求指定类型只有一个接口。在这个情况下,这个接口绑定到这个类型。如果这个类型没有或者有多个接口,则不添加绑定。
• BindToSelf(): 绑定类型到自身。
• BindSelection(ServiceSelector selector): 绑定选择的接口到类型。
• BindUsingRegex(string pattern): 绑定当前类型的符合正则表达式的接口到类型。
4、绑定配置

绑定创建后,可以像普通绑定的配置一样进行配置:

 kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.BindAllInterfaces()
.Configure(b=>b.InSingletonScope()));

我们也可以使用ConfigureFor<T>方法对某些类型分别进行配置。下面的例子,所有的repository类在构造函数中都注入"connectionString"参数,配置成单例生命周期。SqlCustomerRepository类重载成线程生命周期:

 kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<IRepository>()
.BindAllInterfaces()
.Configure(b =>b.InSingletonScope ()
.WithConstructorArgument("connectionString", ApplicationSettings.
ConnectionString))
.ConfigureFor<SqlCustomerRepository>(b =>b.InThreadScope()));

Ninject之旅之六:Ninject约定的更多相关文章

  1. Ninject之旅目录

    第一章:理解依赖注入 Ninject之旅之一:理解DI 第二章:开始使用Ninject Ninject之旅之二:开始使用Ninject(附程序下载) Ninject之旅之三:Ninject对象生命周期 ...

  2. Ninject之旅之一:理解DI

    摘要: DI(IoC)是当前软件架构设计中比较时髦的技术.DI(IoC)可以使代码耦合性更低,更容易维护,更容易测试.现在有很多开源的依赖反转的框架,Ninject是其中一个轻量级开源的.net DI ...

  3. Ninject之旅之十一:Ninject动态工厂(附程序下载)

    摘要 如果我们已经知道了一个类所有的依赖项,在我们只需要依赖项的一个实例的场景中,在类的构造函数中引入一系列的依赖项是容易的.但是有些情况,我们需要在一个类里创建依赖项的多个实例,这时候Ninject ...

  4. Ninject之旅之八:Ninject插件模型(附程序下载)

    摘要 在前面的章节中,我们看了在单一的绑定条件下Ninject能够处理依赖类型,就是说,每个服务类型只绑定到单一的实现类型.然而,有些情况下我们需要绑定一个抽象服务类型到多个实现,这叫多个绑定.多个绑 ...

  5. Ninject之旅之十:Ninject自定义提供者

    摘要 提供者是特殊的工厂类,Ninject使用它来实例化解析类型.任何时候我们绑定一个服务类型到一个组件,我们都隐式地关联那个服务类型到一个可以实例化那个组件的提供者.这个隐藏的提供者被称为Stand ...

  6. Ninject之旅之九:Ninject上下文绑定(附程序下载)

    摘要 既然在插件模型里,每一个服务类型可以被映射到多个实现,绑定方法不用决定要返回哪个实现.因为kernel应该返回所有的实现.然而,上下文绑定是多个绑定场景,在这个场景里,kernel需要根据给定的 ...

  7. Ninject之旅之七:Ninject依赖注入

    摘要 可以使用不同的模式向消费者类注入依赖项,向构造器里注入依赖项是其中一种.有一些遵循的模式用来注册依赖项,同时有一些需要避免的模式,因为他们经常导致不合乎需要的结果.这篇文章讲述那些跟Ninjec ...

  8. Ninject之旅之五:Ninject XML配置

    摘要 使用XML配置,需要添加Ninject XML扩展的引用.下一步是添加一个或多个包含类型注册的XML文件.记得这些文件应该跟应用程序一起发布.因此不要忘记将XML文件的属性设置成“Copy if ...

  9. Ninject之旅之四:Ninject模块

    摘要 随着应用程序的增长,注册的服务列表跟着变长,管理这个列表将变得困难.Ninject模块是一个好的将我们的类型绑定分离到不同的绑定组的方式,它很容易地将分组组织到不同的文件中.将一个类变成一个Ni ...

随机推荐

  1. SQLSERVER系统视图,系统表,sys.sql_modules视图

    SQLServer中提供了相当丰富的系统视图,能够从宏观到微观,从静态到动态反应数据库对象的存储结果.系统性能.系统等待事件等等.同时 也保留了与早期版本兼容性的视图,主要差别在于SQLServer2 ...

  2. 针对web高并发量的处理

    针对web高并发量的处理 针对高并发量的处理 一个老生常谈的话题了 至于需要运维支持的那些cdn.负载均衡神马的就不赘述了 你们都懂的 虫子在此博文只讲一些从程序角度出发的一些不错的解决方案. 至于从 ...

  3. return Acad::ErrorStatus::eOk引发error C2220: warning treated as error - no 'object' file generated

    必须先Acad::ErrorStatus es; 然后return es. 补充: 如果把cpp中#include "*.h"和#include"stdafx.h&quo ...

  4. asp.net中使用基于角色role的Forms验证

    http://www.cnblogs.com/yao/archive/2006/06/24/434783.html asp.net中使用基于角色role的Forms验证,大致经过几下四步:1.配置系统 ...

  5. 【python】调用机器喇叭发出蜂鸣声(Beep)

    ##coding:utf-8 import winsound winsound.Beep(600,6000) #其中600表示声音大小,1000表示发生时长,1000为1秒

  6. 【python】遍历类的所有成员

    # -*- coding: utf-8 -*- #sharejs.com提供代码,转载请注明出处 class Site(object): def __init__(self): self.title ...

  7. 【Jsch】使用SSH协议连接到远程Shell执行脚本

    如果大家熟悉Linux的话,一定对ssh,sftp,scp等命令非常熟悉,ssh是一个安全协议,用来在不同系统或者服务器之间进行安全连接,SSH 在连接和传送的过程中会加密所有的数据. 但是SSH一般 ...

  8. javascript基础部分

    javascript基础部分 1  数据类型: 基础数据类型(通过typeof来检测):Number,string,undefined,null,boolean,function typeof只能检测 ...

  9. fontcreator制作iconfont(包含两个教程)

    第一步 在AI中画好矢量图,或者是在PS中将纯色的图片存成PNG格式,最好是放大很多倍的纯色图片.因为导入到fontcreator中会显得很小,如果不是矢量,图片拉大后就会有锯齿状. 第二步 选中AI ...

  10. 关于print和echo的区别

    我的想法是print是函数,echo是语句.有一个点很难去说明就是为什么可以执行print 666.可以这样不加括号,象print(666);至于为什么一定要认为print是函数,而非网上说的语句和函 ...