Ninject 2.x细说---2.绑定和作用域

转载weixin_33725272 最后发布于2011-11-06 00:03:00 阅读数 9  收藏
 

Ninject中提供多种接口和实现类的绑定的方式供我们选择,同时还可以设置相关的绑定项以及对象的作用域等。具体如下:(其中使用到的类和代码重用上一节的“Ninject 2.x细说---1.基本使用”中的定义)

1.        绑定:

Ninject中提供好几种绑定接口实现的方法,具体如下:

Ø To:绑定到接口的具体实现。

Ø ToConstant:绑定到某个常量值。

Ø ToMethod:绑定到方法。

Ø ToProvider:绑定到某个自定义的对象创建提供程序。

Ø ToSelf:自绑定。

代码如下:

1)        自绑定

Ninject可以使用ToSelf()方法,将自己绑定自己,这里必须是一个具体的类。

Bind<MessageCfg>().ToSelf();

2)        绑定到方法:

Bind<IMessage>().ToMethod(context => new MessageDB());

3)        绑定到具体的类型

Bind<IMessage>().ToConstant(new MessageDB());

4)        绑定到指定的服务提供程序

以及Bind<IMessage>().ToProvider(实现IProvider接口的服务提供程序);

2.        指定相关绑定信息:

Ninject中,可以在绑定的时候指定一些附加信息,以便更加明确构造函数或者是给某些属性赋值或者在绑定时回调方法。如下面的代码中:Bind<IMessage>().To<MessageDB>().WithConstructorArgument("msg", 1);

我们在绑定的同时指定了构造函数的参数以及值。

此外,还可以设置的指定信息分别有:

Ø WithConstructorArgument:指定构造函数中相关的参数,还有回调方法的重载。

Ø WithMetadata:指定相关元数据信息。

Ø WithParameter:指定相关的自定义参数。这个方法也实现构造函数参数值指定,与WithConstructorArgument类似,如:Bind<IMessage>().To<MessageDB>().WithConstructorArgument("msg", 1);同样可以写成:Bind<IMessage>().To<MessageDB>().WithParameter(newConstructorArgument("msg", 1));

Ø WithPropertyValue:指定相关的属性值,还有回调方法的重载。

3.        条件绑定:

Ninject中还可以指定相关的绑定的条件,只有条件满足的情况的下,才将相关的接口实现绑定到相关的接口上。如:

Bind<IMessage>().To<MessageDB>().WhenInjectedInto<MessageCfg>();

上面的代码,由于MessageCfg依赖与IMessage接口,所以其意思是在MessageCfg类中依赖的IMessage接口与MessageDB类绑定。

类似的还有When()如:

Bind<IMessage>().To<MessageDB>().When(cxt => cxt.Service.Name.StartsWith("Msg"));

其他的条件还有WhenClassHas、WhenParentNamed、WhenTargetHas等条件绑定。

4.        设置注入项

在Ninject中可以通过NinjectSettings类来指定注入项。如:

////设置注入项

var settings = new NinjectSettings() { AllowNullInjection = true };

using (var kernal = new StandardKernel(settings, new MessageModule()))

{

var msgcfg = kernal.Get<MessageCfg>();

}

其中,可以设置的项有:

ActivationCacheDisabled、AllowNullInjection、CachePruningInterval、ExtensionSearchPattern、InjectAttribute、InjectNonPublic等等。大概对应的就是设置缓存是否启用、是否允许空注入、缓存周期、扩展查找位置、必须被注入的属性、是否必须注入非公开成员等等。(BTW:Ninject中摘要说明少了Get,还发现好几个地方都是这样呢)。

5.        Inject特性

在Inject中,我们构造函数、属性和字段上加 [Inject]特性指示,以便指定注入的属性、方法和字段等。[Inject]特性定义具体如下:

[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple =false, Inherited = true)]

public class InjectAttribute : Attribute

{

public InjectAttribute();

}

例如使用[Inject]指定构造函数,如果某个类存在多个构造函数,那么我们就可以在某个构造函数上使用[Inject]来指定从此处注入,具体代码如下:

public class MessageDB : IMessage

{

public MessageDB() { }

public MessageDB(object msg)

{

Console.WriteLine("使用了object 参数构造:{0}", msg);

}

[Inject]

public MessageDB(int msg)

{

Console.WriteLine("使用了int 参数构造:{0}", msg);

}

public string GetMsgNumber()

{

return "从数据中读取消息号!";

}

}

相应的MessageModule进行修改,具体如下:

public class MessageModule : NinjectModule

{

public override void Load()

{

//绑定接口并指定接口的实现。

Bind<IMessage>().To<MessageDB>().WithConstructorArgument("msg", 1);

}

}

具体使用如下:

using (var kernal = new StandardKernel(new MessageModule()))

{

//属性注入

var msgcfg = new MessageCfg() { Msg = kernal.Get<IMessage>() };

Console.WriteLine(msgcfg.GetMsgNumber());

Console.Read();

}

其中MessageCfg类的定义见前一节介绍的内容。通过上面的代码,我们可以看到,MessageDB分别由int和object类型的构造函数,如果没有在构造函数上指定[Inject],经过测试发现它默认就是选择第一个构造函数,如果参数类型不匹配就直接抛出异常。

6.        对象作用域:

Transient

.InTransientScope()

每次调用创建新实例。

Singleton

.InSingletonScope()

单例,仅创建一个实例。

Thread

.InThreadScope()

每一个线程创建一个实例。

Request

.InRequestScope()

每当Web请求发起时创建一个实例,结束请求时释放实例

InScope

InScope(Func)

对象尽量保持到回调委托返回

上表来自“靠近太阳”的博文,后增加了InScope 。如使用InThreadScope()具体例子如下:

public class MessageModule : NinjectModule

{

public override void Load()

{

//绑定接口并指定接口的实现。

Bind<IMessage>().To<MessageDB>().InThreadScope().WithParameter(new ConstructorArgument("msg", 1));

}

}

使用代码如下:

using (var kernal = new StandardKernel(new MessageModule()))

{

//属性注入

var th1 = new Thread(new ThreadStart(() =>

{

var msgcfg = new MessageCfg() { Msg = kernal.Get<IMessage>() };

Console.WriteLine(msgcfg.GetMsgNumber());

}));

var th2 = new Thread(new ThreadStart(() =>

{

var msgcfg = new MessageCfg() { Msg = kernal.Get<IMessage>() };

Console.WriteLine(msgcfg.GetMsgNumber());

}));

var th3 = new Thread(new ThreadStart(() =>

{

var msgcfg = new MessageCfg() { Msg = kernal.Get<IMessage>() };

Console.WriteLine(msgcfg.GetMsgNumber());

}));

th1.Start();

th2.Start();

th3.Start();

Console.Read();

}

}

在上面的代码中,我们指定了对象在InThreadScope,在使用的代码中分别创建了3个线程来进行模拟,最终每个线程都是创建了一个对象。

Ninject 2.x细说---2.绑定和作用域的更多相关文章

  1. Ninject 2.x细说---1.基本使用

    Ninject 2.x细说---1.基本使用 https://blog.csdn.net/weixin_33809981/article/details/86091159   本来想使用一下Ninje ...

  2. [1] Ninject

    为什么使用这种依赖注入的框架呢?我借鉴两张图做一下说明 传统的接口方式,即 IValueCalculator I=new LinqValueCalculator,虽然用接口做的隔离,但是在调用的时候实 ...

  3. Ninject.MVC 知识点记录

    Ninject 是跟Unity 差不多的DI容器.Ninject 推荐零配置,快速使用.小中型项目,最适合. 通过nuget,安装Ninject.MVC.略.参考博客:Ninject依赖注入      ...

  4. Ninject学习笔记<二>

    本文转载自kuangkro 如果给您带来不便请联系博主 一.控制反转和依赖注入 Ninject是一个轻量级的基于.Net平台的依赖注入(IOC)框架.所谓的IOC,即控制反转(Inversion of ...

  5. IOC框架Ninject实践总结

    原文地址:http://www.cnblogs.com/jeffwongishandsome/archive/2012/04/15/2450462.html IOC框架Ninject实践总结 一.控制 ...

  6. Python的名字绑定

    Python的名字绑定 在Python中,对象是通过名字进行关联和引用的.Python通过名字绑定操作来引入名字. Python中的所谓的代码块就是一段作为执行单元的程序.比如:模块.函数.类定义.在 ...

  7. 理解Ruby中的作用域

    作用域对于Ruby以及其它编程语言都是一个需要理解的至关重要的基础知识.在我刚开始学习ruby的时候遇到很多诸如变量未定义.变量没有正确赋值之类的问题,归根结底是因为自己对于ruby作用域的了解不够, ...

  8. 轻量级IOC框架:Ninject (下)

    一,创建依赖链(Chains of Dependency) 当我们向Ninject请求创建一个类型时,Ninject会去检查该类型和其他类型之间的耦合关系.如果有额外的依赖,Ninject也会解析它们 ...

  9. 【Pro ASP.NET MVC 3 Framework】.学习笔记.2.MVC的主要工具-Ninject

    这三个工具,应该是每个MVC程序员的兵工厂中的一部分.DI容器,单元测试框架,mocking 工具.Ninject是我们偏爱的DI容器,它简单,高雅,并且容易使用.这里有很多复杂的替代品,但是我们喜欢 ...

随机推荐

  1. srpingboot web - 启动(3) 监听器

    接上一篇 一. getRunListeners() 在run() 方法中调用了 getRunListeners(args) 方法, 先看一下这个方法干了什么 private SpringApplica ...

  2. Java第四节课总结

    动手动脑1:如果类提供了一个自定义的构造方法,将导致系统不再提供默认构造方法.Foo obj1=new Foo()在此处调用应增加参数. 动手动脑2:静态初始化块只执行一次.创建子类型的对象时,也会导 ...

  3. webkit 技术内幕 笔记 二

    浏览器历史 80年代末-90年代初:worldwideweb(nexus) -- Berners-Lee 1993: Mosaic浏览器,后来叫网景(Netscape)--Marc Andreesse ...

  4. springboot的yml配置文件里有多个参数的调用方式

    本篇教程适用于配置文件一级下有多个二级或三级时,如何在service层不用通过多个@Value就能获取配置文件的参数 例如yml配置是这样的: 如果service层要引用这些参数,用多个@Value( ...

  5. 摇一摇—微信7.0.8版本audio无法自动播放问题

    近日有一个项目出现audio无法自动播放,查看原因才发现是微信版本更新为7.0.8版本,需要有交互行为,第一次播放需要用户手动点击一下,无法使用DOM中的play()进行直接播放操作,那怎么办呢? 通 ...

  6. BSGS求解离散对数问题

    离散对数问题是求解axΞb mod(n) 同余方程 以下模板使用于gcd(a,n)=1的情况 ; int hs[mod],head[mod],Next[mod],id[mod],top; void i ...

  7. C++-POJ3213-PM3-[矩阵乘法]

    已知矩阵乘法是n^3的,必然超时 故可以在需要验证的等式AB=C两边同时左乘D 一个1xN的任意的不含0矩阵 设E=DA,F=EB,G=DC,则此时只需验证F=G 当匹配到非法列J时,跳出n^2寻找行 ...

  8. AC认证技术

    一.认证方式 Dkey认证(数字密钥认证) 1)免认证key,形同usb,插入即通过认证 2)免审计key,也是上网不被记录审计. 单点登录 登录了某点,其他点都能访问:例如登录了支付宝淘宝就不用登录 ...

  9. 模拟退火SA刷题记录

    洛谷P1337 [JSOI2004]平衡点 / 吊打XXX 基本上是照着别人的代码写的,模拟退火为什么一定能找到答案呢...迷惑,,有时间搜一搜证明啥的 sa步骤:这个是要确定一个(xi,yi)使得函 ...

  10. Codeforces Round #619 (Div. 2) A~D题解

    最近网课也开始了,牛客上一堆比赛题目也没补,所以就D题后面的也懒得补了 A.Three String 水题 #include <cstdio> #include <cstring&g ...