Castle IOC容器实践之Startable Facility(二)
2006-05-14 08:51:00
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://terrylee.blog.51cto.com/342737/67685 |
摘要:在Castle IOC容器实践之Startable Facility(一)中我们已经学会了如何去使用Startable Facility,本文将在此基础进一步对它的原理做一些分析。
主要内容
Startable Facility原理分析
……
在Castle IOC容器实践之Startable Facility(一)中我们已经看到了如何去使用Startable Facility,本文将对它的原理做一些分析。先看一下接口IStartable,它的实现代码如下:
public interface IStartable { void Start();![]() void Stop(); }代码是相当的简单,只有两个方法,分别在组件创建的时候和销毁的时候执行,这就涉及到了组件的生命周期管理。在Windsor中,接口ILifecycleConcern提供特定的组件生命周期管理: public interface ILifecycleConcern { void Apply( ComponentModel model, object component );![]() }现在我们要实现组件的自动创建和销毁,就需要实现接口ILifecycleConcern,在Startable Facility中分别用两个类来实现,第一个类StartConcern,它判断如果组件实现了接口IStartable,则直接调用它的Start()方法;如果组件是用特性startMethod,则获取并调用具有startMethod特性的方法: public class StartConcern : ILifecycleConcern { private static readonly StartConcern _instance = new StartConcern();![]() protected StartConcern() {![]() }![]() public static StartConcern Instance { get { return _instance; } }![]() public void Apply(ComponentModel model, object component) { if (component is IStartable) { (component as IStartable).Start(); } else if (model.Configuration != null) { String startMethod = model.Configuration.Attributes["startMethod"]; if (startMethod != null) {![]() MethodInfo method = model.Implementation.GetMethod(startMethod);![]() method.Invoke(component, null); } } } }第二个类是StopConcern,它判断如果组件实现了接口IStartable,则直接调用它的Stop()方法;如果组件是用特性stopMethod,则获取并调用具有stopMethod特性的方法: public class StopConcern : ILifecycleConcern { private static readonly StopConcern _instance = new StopConcern();![]() protected StopConcern() {![]() }![]() public static StopConcern Instance { get { return _instance; } }![]() public void Apply(ComponentModel model, object component) { if(component is IStartable) { (component as IStartable).Stop(); } else if (model.Configuration != null) { String stopMethod = model.Configuration.Attributes["stopMethod"];![]() if (stopMethod != null) { MethodInfo method = model.Implementation.GetMethod(stopMethod);![]() method.Invoke(component, null); } } } }好了,知道了Startable Facility如何管理组件的生命周期,我们就来看看真正的Startable Facility是如何实现的。每一个Facility都是满足这样的一个继承关系: 图1 Facility继承关系图其中的Abstract Facility提供了一些默认的实现,Facility可以直接实现IFacility,也可以继承于Abstract Facility。IFacility的实现如下:
public interface IFacility { void Init(IKernel kernel, IConfiguration facilityConfig);![]() ![]() void Terminate();![]() }那么到底如何让组件满足依赖性后就自动执行呢?注意到再Startable Facility的Init()注册了这样的两个事件: protected override void Init() { converter = (ITypeConverter) Kernel.GetSubSystem(SubSystemConstants.ConversionManagerKey);![]() ![]() Kernel.ComponentModelCreated += ![]() new ComponentModelDelegate(OnComponentModelCreated);![]() Kernel.ComponentRegistered += ![]() new ComponentDataDelegate(OnComponentRegistered);![]() }分别为OnComponentModelCreated和OnComponentRegistered。当我们注册一个组件时首先会出发OnComponentRegistered事件,在它里面判断组件是否满足依赖性,如果不满足,则添加到一个等待列表中,否则就直接启动,然后再对这个等待列表进行检测,看添加改组件后,列表中是否有组件满足了依赖性:
private void OnComponentRegistered(String key, IHandler handler) { bool startable = (bool) handler.ComponentModel.ExtendedProperties["startable"];![]() if (startable) { if (handler.CurrentState == HandlerState.WaitingDependency) { waitList.Add( handler ); } else { Start( key ); } }![]() CheckWaitingList(); }![]() private void CheckWaitingList() { IHandler[] handlers = (IHandler[]) waitList.ToArray( typeof(IHandler) );![]() IList validList = new ArrayList();![]() foreach(IHandler handler in handlers) { if (handler.CurrentState == HandlerState.Valid) { validList.Add(handler);![]() waitList.Remove(handler); } }![]() foreach(IHandler handler in validList) { Start( handler.ComponentModel.Name ); } }刚才说到,如果满足了依赖性,则会请求创建这个组件: private void Start(String key) { object instance = Kernel[key]; }这时就触发了OnComponentModelCreated事件,这时就该用到开始我们所讲的那两生命周期处理的类了: private void OnComponentModelCreated(ComponentModel model) { bool startable = ![]() CheckIfComponentImplementsIStartable(model) || HasStartableAttributeSet(model);![]() model.ExtendedProperties["startable"] = startable;![]() if (startable) { model.LifecycleSteps.Add( ![]() LifecycleStepType.Commission, StartConcern.Instance );![]() model.LifecycleSteps.Add( ![]() LifecycleStepType.Decommission, StopConcern.Instance );![]() } }首先还是先判断组件是否实现了IStartable接口或这时候有特性startable,如果没有那也就不用自动启动了,否则就把StartConcern和StopConcern分别注册为组件的生命周期开始行为和生命周期结束行为,(关于组件的生命周期的详细内容可以参考我前面写的Castle IOC容器组件生命周期管理)。此时组件进入生命周期开始,会调用StartConcern的Apply()方法,这时就触发组件的Start()方法,同样在组件销毁时调用StopConcern的Apply()方法,这时就会调用组件的Stop()方法。这样就完成整个了组件的自动执行与销毁的全过程。 本文出自 “TerryLee技术专栏” 博客,请务必保留此出处http://terrylee.blog.51cto.com/342737/67685 本文出自 51CTO.COM技术博客 |







}
}
图
lihuijun
博客统计信息
热门文章
最新评论
友情链接
