Ninject 2.x细说---2.绑定和作用域
Ninject 2.x细说---2.绑定和作用域
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.绑定和作用域的更多相关文章
- Ninject 2.x细说---1.基本使用
Ninject 2.x细说---1.基本使用 https://blog.csdn.net/weixin_33809981/article/details/86091159 本来想使用一下Ninje ...
- [1] Ninject
为什么使用这种依赖注入的框架呢?我借鉴两张图做一下说明 传统的接口方式,即 IValueCalculator I=new LinqValueCalculator,虽然用接口做的隔离,但是在调用的时候实 ...
- Ninject.MVC 知识点记录
Ninject 是跟Unity 差不多的DI容器.Ninject 推荐零配置,快速使用.小中型项目,最适合. 通过nuget,安装Ninject.MVC.略.参考博客:Ninject依赖注入 ...
- Ninject学习笔记<二>
本文转载自kuangkro 如果给您带来不便请联系博主 一.控制反转和依赖注入 Ninject是一个轻量级的基于.Net平台的依赖注入(IOC)框架.所谓的IOC,即控制反转(Inversion of ...
- IOC框架Ninject实践总结
原文地址:http://www.cnblogs.com/jeffwongishandsome/archive/2012/04/15/2450462.html IOC框架Ninject实践总结 一.控制 ...
- Python的名字绑定
Python的名字绑定 在Python中,对象是通过名字进行关联和引用的.Python通过名字绑定操作来引入名字. Python中的所谓的代码块就是一段作为执行单元的程序.比如:模块.函数.类定义.在 ...
- 理解Ruby中的作用域
作用域对于Ruby以及其它编程语言都是一个需要理解的至关重要的基础知识.在我刚开始学习ruby的时候遇到很多诸如变量未定义.变量没有正确赋值之类的问题,归根结底是因为自己对于ruby作用域的了解不够, ...
- 轻量级IOC框架:Ninject (下)
一,创建依赖链(Chains of Dependency) 当我们向Ninject请求创建一个类型时,Ninject会去检查该类型和其他类型之间的耦合关系.如果有额外的依赖,Ninject也会解析它们 ...
- 【Pro ASP.NET MVC 3 Framework】.学习笔记.2.MVC的主要工具-Ninject
这三个工具,应该是每个MVC程序员的兵工厂中的一部分.DI容器,单元测试框架,mocking 工具.Ninject是我们偏爱的DI容器,它简单,高雅,并且容易使用.这里有很多复杂的替代品,但是我们喜欢 ...
随机推荐
- 理财收益的计算 计算浮点数的n次方 1466
题目描述 老傻非常喜欢购买理财产品,而且这款理财产品被推销人员吹得特别高,对于贪财的老傻来说正中下怀,于是在心里盘算着买了它,自己就是亿万富豪,现需要你编写一个程序,帮老傻计算其收益,老傻的投入是R( ...
- Deepin Linux 升级wine应用
前提是升级已经安装的wine应用 参考: 微信升级 mkdir /tmp/wechat cd /tmp/wechat wget https://dldir1.qq.com/weixin/Windows ...
- Educational Codeforces Round 46 (Rated for Div. 2) D
dp[i]表示一定包含第I个点的好的子序列个数,那么最终答案就是求dp[0] + dp[1] + .... + dp[n-1] 最终的子序列被分成了很多块,因此很明显我们枚举第一块,第一块和剩下的再去 ...
- win10修改jupyter notebook默认路径
安装anaconda3 ,因此自带jupyter notebook 发送到jupyter notebook到桌面快捷方式 右击属性,将目标的%USERPROFILE%,修该为自己需要的路径 起始位置修 ...
- JavaDay9(下)
Java learning_Day9(下) 本人学习视频用的是马士兵的,也在这里献上 <链接:https://pan.baidu.com/s/1qKNGJNh0GgvlJnitTJGqgA> ...
- AI数学基础:符号
1.sigma 表达式 ∑ 是一个求和符号,英语名称:Sigma,汉语名称:西格玛(大写Σ,小写σ) 第十八个希腊字母.在希腊语中,如果一个单字的最末一个字母是小写sigma,要把该字母写成 ς ,此 ...
- 日常问题--解决 ‘Could not fetch URL https://pypi.python.org’的问题
难题描述: 解决方法: 使用命令python -m pip install Scrapy --trusted-host=pypi.python.org --trusted-host=pypi.org ...
- WPF Dispatcher.BeginInvoke子线程更新UI
在开发WPF应用时出现:”调用线程无法访问此对象,因为另一个线程拥有该对象.“ 是因为UI线程是WPF应用的主线程,若尝试子线程更新UI线程应使用Dispatcher.BeginInvoke()或者I ...
- mybatis - 基于拦截器修改执行中的SQL语句
拦截器介绍 mybatis提供了@Intercepts注解允许开发者对mybatis的执行器Executor进行拦截. Executor接口方法主要有update.query.commit.rollb ...
- 如何查看oracle当前连接数,会话数
第一步,在cmd命令行,输入sqlplus 第二步,根据提示输入用户名与密码 1. 查看processes和sessions参数 SQL> show parameter processes NA ...