Ninject之旅之三:Ninject对象生命周期

摘要

DI容器的一个责任是管理他创建的对象的生命周期。他应该决定什么时候创建一个给定类型的对象,什么时候使用已经存在的对象。他还需要在对象不需要的时候处理对象。Ninject在不同的情况下管理对象的生命周期提供了强大的支持。在我们定义一个绑定的时候,定义创建对象的范围。在那个范围内,对象将被重用,每次绑定只存在一次。注意,对象不允许依赖于生命周期比自己小的对象。

1、暂时范围

在暂时态范围内,对象生命周期不被Ninject进行管理。任何时候请求一个类型的对象,都将创建一新对象。Ninject不管理保持创建的对象或者在范围内处理他。这是Ninject默认的范围。如果不指定范围,默认是暂时态。在上一篇文章里,ConsoleLogger和MailServer对象都是暂时态,因为没有指定他的范围。

2、单例范围

有时候我们不想每次需要的时候都创建一个新的对象,这时候使用单例。有两种方法创建单例。一种是使用单例模式。一种是使用Ninject方法InSingletonScope。
1)使用单例模式:

 1 class ConsoleLogger:ILogger
 2 {
 3     public static readonly ConsoleLogger Instance = new ConsoleLogger();
 4     private static ConsoleLogger()
 5     {
 6         // Hiding constructor
 7     }
 8     public void Log(string message)
 9     {
10         Console.WriteLine("{0}: {1}", DateTime.Now, message);
11     }
12 }

然后在Bind方法后调用ToConstant方法指定静态只读对象ConsoleLogger.Instance为常量对象。

kernel.Bind<ILogger>().ToConstant(ConsoleLogger.Instance);

2)使用方法InSingletonScope:

kernel.Bind<ILogger>().To<ConsoleLogger>().InSingletonScope();

如果要给MailServerConfig类对象设置单例,则先调用ToSelf方法将他绑定自身,然后再调用方法InSingletonScope。

kernel.Bind<MailServerConfig>().ToSelf().InSingletonScope();

3、线程范围

如果定义在线程范围内,每一个线程将只创建一个给定类型的对象。对象的生命周期跟对象所在的线程一样长。

调用方法InThreadScope创建线程范围:

kernel.Bind<object>().ToSelf().InThreadScope();

创建两个Test方法测试线程范围。

 1 using Ninject;
 2 using NUnit.Framework;
 3 using System.Threading;
 4
 5 namespace Demo.Ninject
 6 {
 7     [TestFixture]
 8     class NinjectTest
 9     {
10         [Test]
11         public void ReturnsTheSameInstancesInOneThread()
12         {
13             using (var kernel = new StandardKernel())
14             {
15                 kernel.Bind<object>().ToSelf().InThreadScope();
16                 var instance1 = kernel.Get<object>();
17                 var instance2 = kernel.Get<object>();
18                 Assert.AreEqual(instance1, instance2);
19             }
20         }
21
22         [Test]
23         public void ReturnsDifferentInstancesInDifferentThreads()
24         {
25             var kernel = new StandardKernel();
26             kernel.Bind<object>().ToSelf().InThreadScope();
27             var instance1 = kernel.Get<object>();
28             new Thread(() =>
29             {
30                 var instance2 = kernel.Get<object>();
31                 Assert.AreNotEqual(instance1, instance2);
32                 kernel.Dispose();
33             }).Start();
34         }
35     }
36 }

第一个方法在同一个线程内请求了两个object对象,他们是相同的实例。第二个方法先在主线程内请求一个object实例,然后开启另一个线程请求另一个实例,他们不是相同的实例。

需要添加NUnit和NUnit.Console才能测试上面的方法。我使用的是NUnit 2.6.4和NUnit.Console 2.0.0。

4、请求范围

请求范围在web应用程序里非常有用。可以在相同的请求范围内得到一个单例的对象。一旦一个请求被处理,另一个请求到来,Ninject创建新的对象实例,并保持他直到请求结束。

调用方法InRequestScope设置请求范围:

kernel.Bind<MailServerConfig>().ToSelf().InRequestScope();

需要添加Ninject.Web.Common引用才能够调用InRequestScope方法。

时间: 2024-10-13 16:43:19

Ninject之旅之三:Ninject对象生命周期的相关文章

[翻译]理解C#对象生命周期

看到网上的一篇讲C#对象生命周期(Object Lifetime)的文章,通俗易懂,而且有图,很适合初学者学习,就翻译过来了.后来发现这是Pro C# 2010 and the .NET 4 Platform的第八章中的一部分.(感谢 大乖乖 提醒).文中的专业名词第一次出现时,括号里会标注对应的英文单词. 请尊重作者劳动,转载请注明出处:http://www.cnblogs.com/Jack47/archive/2012/11/14/2770748.html. ----2012年11月15日修

struts2.0中Action的对象生命周期详解!!(转)

原文出处:http://blog.csdn.net/wxy_g/article/details/2071662 有很多人问Struts2.0中的对象既然都是线程安全的,都不是单例模式,那么它究竟何时创建,何时销毁呢? 这个和struts2.0中的配置有关,我们来看struts.properties ### if specified, the default object factory can be overridden here ### Note: short-hand notation is

.Net组件程序设计之对象生命周期

.Net组件程序设计之对象生命周期 .NET 垃圾回收 IDisposable() Using语句 .NET 垃圾回收 是CLR管理着垃圾回收器,垃圾回收器监控着托管堆,而我们使用的对象以及系统启动是所需要的一些必备的对象信息都存在于托管堆上,CLR会维护着一个列表(对象引用信息列表). 这个列表里存放的信息就是对应着托管堆中所有对象的信息(引用.被引用信息)每当使用一个新的对象或者是改变一个现有对象的引用CLR都会更新 对象引用信息列表.那么回收器一般什么时候调用呢? 垃圾回收器大多数是在托管

【iOS知识学习】_视图控制对象生命周期-init、viewDidLoad、viewWillAppe

iOS视图控制对象生命周期-init.viewDidLoad.viewWillAppear.viewDidAppear.viewWillDisappear.viewDidDisappear的区别及用途 init-初始化程序 viewDidLoad-加载视图 viewWillAppear-UIViewController对象的视图即将加入窗口时调用: viewDidApper-UIViewController对象的视图已经加入到窗口时调用: viewWillDisappear-UIViewCont

_视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear等的区别及用途

iOS视图控制对象生命周期-init.viewDidLoad.viewWillAppear.viewDidAppear.viewWillDisappear.viewDidDisappear的区别及用途 init-初始化程序 viewDidLoad-加载视图 viewWillAppear-UIViewController对象的视图即将加入窗口时调用: viewDidApper-UIViewController对象的视图已经加入到窗口时调用: viewWillDisappear-UIViewCont

IOS 视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear等的区别及用途

iOS视图控制对象生命周期-init.viewDidLoad.viewWillAppear.viewDidAppear.viewWillDisappear.viewDidDisappear的区别及用途 init-初始化程序 viewDidLoad-加载视图 viewWillAppear-UIViewController对象的视图即将加入窗口时调用: viewDidApper-UIViewController对象的视图已经加入到窗口时调用: viewWillDisappear-UIViewCont

hibernate session缓存和java对象生命周期

一.java对象生命周期 1.在java中,使用new关键字,创建一个java对象,jvm就为这个对象分配一块内存空间.只要这个变量被引用,他就一直存在于内存中.如果没有被任何变量引用(包括间接引用),那么这个对象就会被垃圾回收器回收.下面用一段代码来解释: Customer c=new Customer(); Order o1=new Order(); Order 02=new Order(); o1.setCustomer(c); c.getOrders().add(o1); o1=null

6、对象生命周期和垃圾回收基础

掠过架构化异常处理不谈,接下来主要介绍CLR怎样通过垃圾回收来管理已分配的类实例(对象).C#程序员从来不直接在内存中删除一个托管对象,相反,.net对象被分配到了一块叫做托管堆的内存区域上,到了某个时候他们被垃圾回收期自动销毁. 及时释放内部非托管资源:使用System.Object.Fimalize()虚方法和IDisposable接口. .net4垃圾回收器的新功能:后台垃圾回收和使用System.Lazy<>泛型实现的延迟实例化. 第一个问题,类.对象和引用. 类是一个蓝图,描述这个类

ASP.NET Core Web API下事件驱动型架构的实现(二):事件处理器中对象生命周期的管理

在上文中,我介绍了事件驱动型架构的一种简单的实现,并演示了一个完整的事件派发.订阅和处理的流程.这种实现太简单了,百十行代码就展示了一个基本工作原理.然而,要将这样的解决方案运用到实际生产环境,还有很长的路要走.今天,我们就研究一下在事件处理器中,对象生命周期的管理问题. 事实上,不仅仅是在事件处理器中,我们需要关心对象的生命周期,在整个ASP.NET Core Web API的应用程序里,我们需要理解并仔细推敲被注册到IoC容器中的服务,它们的生命周期应该是个怎样的情形,这也是服务端应用程序设