Ninject之旅之三:Ninject对象生命周期
2016-08-07 14:20
127 查看
摘要
DI容器的一个责任是管理他创建的对象的生命周期。他应该决定什么时候创建一个给定类型的对象,什么时候使用已经存在的对象。他还需要在对象不需要的时候处理对象。Ninject在不同的情况下管理对象的生命周期提供了强大的支持。在我们定义一个绑定的时候,定义创建对象的范围。在那个范围内,对象将被重用,每次绑定只存在一次。注意,对象不允许依赖于生命周期比自己小的对象。
1、暂时范围
在暂时态范围内,对象生命周期不被Ninject进行管理。任何时候请求一个类型的对象,都将创建一新对象。Ninject不管理保持创建的对象或者在范围内处理他。这是Ninject默认的范围。如果不指定范围,默认是暂时态。在上一篇文章里,ConsoleLogger和MailServer对象都是暂时态,因为没有指定他的范围。
2、单例范围
有时候我们不想每次需要的时候都创建一个新的对象,这时候使用单例。有两种方法创建单例。一种是使用单例模式。一种是使用Ninject方法InSingletonScope。
1)使用单例模式:
然后在Bind方法后调用ToConstant方法指定静态只读对象ConsoleLogger.Instance为常量对象。
2)使用方法InSingletonScope:
如果要给MailServerConfig类对象设置单例,则先调用ToSelf方法将他绑定自身,然后再调用方法InSingletonScope。
3、线程范围
如果定义在线程范围内,每一个线程将只创建一个给定类型的对象。对象的生命周期跟对象所在的线程一样长。
调用方法InThreadScope创建线程范围:
创建两个Test方法测试线程范围。
第一个方法在同一个线程内请求了两个object对象,他们是相同的实例。第二个方法先在主线程内请求一个object实例,然后开启另一个线程请求另一个实例,他们不是相同的实例。
需要添加NUnit和NUnit.Console才能测试上面的方法。我使用的是NUnit 2.6.4和NUnit.Console 2.0.0。
4、请求范围
请求范围在web应用程序里非常有用。可以在相同的请求范围内得到一个单例的对象。一旦一个请求被处理,另一个请求到来,Ninject创建新的对象实例,并保持他直到请求结束。
调用方法InRequestScope设置请求范围:
需要添加Ninject.Web.Common引用才能够调用InRequestScope方法。
DI容器的一个责任是管理他创建的对象的生命周期。他应该决定什么时候创建一个给定类型的对象,什么时候使用已经存在的对象。他还需要在对象不需要的时候处理对象。Ninject在不同的情况下管理对象的生命周期提供了强大的支持。在我们定义一个绑定的时候,定义创建对象的范围。在那个范围内,对象将被重用,每次绑定只存在一次。注意,对象不允许依赖于生命周期比自己小的对象。
1、暂时范围
在暂时态范围内,对象生命周期不被Ninject进行管理。任何时候请求一个类型的对象,都将创建一新对象。Ninject不管理保持创建的对象或者在范围内处理他。这是Ninject默认的范围。如果不指定范围,默认是暂时态。在上一篇文章里,ConsoleLogger和MailServer对象都是暂时态,因为没有指定他的范围。
2、单例范围
有时候我们不想每次需要的时候都创建一个新的对象,这时候使用单例。有两种方法创建单例。一种是使用单例模式。一种是使用Ninject方法InSingletonScope。
1)使用单例模式:
class ConsoleLogger:ILogger { public static readonly ConsoleLogger Instance = new ConsoleLogger(); private static ConsoleLogger() { // Hiding constructor } public void Log(string message) { Console.WriteLine("{0}: {1}", DateTime.Now, message); } }
然后在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方法测试线程范围。
using Ninject; using NUnit.Framework; using System.Threading; namespace Demo.Ninject { [TestFixture] class NinjectTest { [Test] public void ReturnsTheSameInstancesInOneThread() { using (var kernel = new StandardKernel()) { kernel.Bind<object>().ToSelf().InThreadScope(); var instance1 = kernel.Get<object>(); var instance2 = kernel.Get<object>(); Assert.AreEqual(instance1, instance2); } } [Test] public void ReturnsDifferentInstancesInDifferentThreads() { var kernel = new StandardKernel(); kernel.Bind<object>().ToSelf().InThreadScope(); var instance1 = kernel.Get<object>(); new Thread(() => { var instance2 = kernel.Get<object>(); Assert.AreNotEqual(instance1, instance2); kernel.Dispose(); }).Start(); } } }
第一个方法在同一个线程内请求了两个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方法。
相关文章推荐
- 【iOS知识学习】_视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear等的区别及用途
- Mybatis核心对象的生命周期与封装
- iOS视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear的区别及用途
- 深入探索CORBA对象生命周期之慨述-Java基础-Java-编程开发
- 演示对象的生命周期及Session接口
- Hibernate入门(3)- 持久对象的生命周期介绍
- Hibernate对象的生命周期及crud操作
- c++对象的生命周期
- 对象的生命周期
- 004---持久对象的生命周期介绍
- 强化训练2--匿名对象的生命周期
- wxPython_应用程序对象的生命周期
- Hibernate持久化对象的生命周期
- iOS视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear的区别及用
- Hibernate中对象的状态和生命周期
- hibernate中持久化对象的生命周期(三态:自由态,持久态,游离态 之间的转换)
- 自定义Unity对象生命周期管理集成ADO.NET Entity Framework
- Hibernate学习笔记:对象生命周期
- 详细解读JVM中的对象生命周期(1)
- Hibernate 持久化对象的生命周期