2008-09-17 81 views
9

我有一个对象实现了在Windsor容器中注册的IDisposable,我想处理它,因此它的Dispose方法被调用,并且下一次调用Resolve时它会提取一个新的实例。Windsor Container:如何强制处理一个对象?

是否

container.Release(obj); 

自动调用Dispose()马上?或者,我需要做的

obj.Dispose(); 
container.Release(obj); 

上无法找到文档中任何事情究竟是什么版本还

编辑: 见我的回答如下的测试我跑的结果。现在问题变成了,我该如何强制容器释放具有单例生命周期的组件实例?这只需要在一个地方完成,写一个自定义的生命周期似乎太重量级了,是否没有建立它的方式?

回答

10

这是我认为人们没有真正意识到与温莎容器中工作时的 - 尤其是经常奇怪行为一次性短暂的组件由容器扶住为内核的一生,直到它的处置除非你释放他们自己 - 虽然它记录 - 看看here - 但快速报价:

微内核有一个可以连接起来,实现一些 路由处置组件可插拔的发行政策。微内核带有三个IReleasePolicy实现:

  • AllComponentsReleasePolicy:跟踪所有部件在微内核的情况下处置
  • LifecycledComponentsReleasePolicy执行正确的处置:只跟踪具有相关
  • NoTrackingReleasePolicy的停止使用生命周期的组件:不执行任何跟踪

您还可以使用接口IReleasePolicy实现您自己的发布策略。

,你可能会发现更容易是政策改变为NoTrackingReleasePolicy,然后处理处置自己 - 这是潜在的风险为好,但如果你的生活方式在很大程度上是短暂的(或者,如果当您的容器配置无论如何,你的应用程序即将关闭),这可能不是什么大不了的事情。不过请记住,任何已经被单体注入的组件都会有一个引用,所以你最终可能会试图“刷新”你的单例 - 这似乎是一个不好的习惯,我想知道是否可以避免必须首先通过改进应用程序放在一起的方式来做到这一点。其他方法是使用自己的解除执行来构建自定义生命周期(因此释放单例实际上会处理组件,就像暂时的生命周期一样)。

或者,另一种方法是使用单件生活方式在您的服务中注册一个服务的装饰器,但是您的实际底层服务以瞬态生活方式在容器中注册 - 那么当您需要刷新组件时,只需处理暂时的底层组件被装饰者持有,并用一个新解决的实例代替它(使用组件键来解决它,而不是服务,以避免获得装饰器) - 这可以避免与其他单件服务(未被刷新“)从持有过时的服务中解放出来,使它们无法使用,但确实需要一些铸造等来使其工作。

+0

我有一个类似的问题,我非常喜欢装饰者的概念。不错的一个... – 2009-11-09 19:43:40

3

这取决于您将其添加到容器时指定的组件的生活方式。

你会使用Release()如果生活方式是Pooled。这会将组件重新放回池中以供下次检索(对象未被破坏,因此处置会很糟糕)

如果生活方式是暂时的,则在获取组件时会创建一个新对象。在这种情况下,处理由您决定,您不需要拨打发布

如果生活方式为线程,则每个线程使用相同的组件,而不是销毁。

如果生活方式是单身人士,只有一个组件被创建并且没有被销毁。

很可能,您正在使用瞬态组件? (如果您担心及时它们的处置) 在这种情况下,只需用用包裹它,你设置(或致电某处处置自己)

using(ISomeService service = container.Resolve<ISomeService>()) 
{ 
// Do stuff here 
// service.Dispose is automatically called 
} 

编辑 - 是的,为了“刷新”或者处理并重新创建你的单例,你需要销毁容器或者写一个自定义的生命周期。做一个自定义的生命周期并不是那么困难,并且保持逻辑在一个地方这样做。

+0

其实我正在做singletons,但想强制它偶尔重新生成组件。 – 2008-09-17 17:30:19

1

好的,所以我一直在运行测试,看起来像Container.Release()会隐含导致IDisposable的方法只有在生活方式是瞬态时才会执行(这可能不完全正确,但要指出的是它不会“如果生活方式是单身的话)。

现在,如果你调用Container.Dispose()它会调用一次性方法还,但不幸的是它会处理整个内核,你将不得不对所有组件添加回去:

var container = new WindsorContainer(); 
container.AddComponentWithLifestyle<MyDisposable>(Castle.Core.LifestyleType.Singleton); 
var obj = container.Resolve<MyDisposable>(); // Create a new instance of MyDisposable 
obj.DoSomething(); 
var obj2 = container.Resolve<MyDisposable>(); // Returns the same instance as obj 
obj2.DoSomething(); 
container.Dispose(); // Will call the Disposable method of obj 
// Now the components need to be added back in 
container.AddComponentWithLifestyle<MyDisposable>(Castle.Core.LifestyleType.Singleton); 
var obj3 = container.Resolve<MyDisposable>(); // Create a new instance of MyDisposable 

幸运在我的情况,我可以只需放下所有组件,我就可以很容易地恢复它们。然而,这是次优的。